Merge branch 'ismail/5068_start_thread' into ismail/5096_thread_notifications

This commit is contained in:
ismailgulek
2022-01-17 11:39:25 +03:00
300 changed files with 6263 additions and 923 deletions
@@ -1826,27 +1826,31 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
dispatch_group_t dispatchGroup = dispatch_group_create();
for (MXRoomSummary *summary in mxSession.roomsSummaries)
for (MXRoom *room in mxSession.rooms)
{
dispatch_group_enter(dispatchGroup);
[summary.mxSession eventWithEventId:summary.lastMessage.eventId
inRoom:summary.roomId
success:^(MXEvent *event) {
if (event)
{
if (summary.lastMessage.others == nil)
MXRoomSummary *summary = room.summary;
if (summary)
{
dispatch_group_enter(dispatchGroup);
[summary.mxSession eventWithEventId:summary.lastMessage.eventId
inRoom:summary.roomId
success:^(MXEvent *event) {
if (event)
{
summary.lastMessage.others = [NSMutableDictionary dictionary];
if (summary.lastMessage.others == nil)
{
summary.lastMessage.others = [NSMutableDictionary dictionary];
}
summary.lastMessage.others[@"lastEventDate"] = [eventFormatter dateStringFromEvent:event withTime:YES];
[self->mxSession.store.roomSummaryStore storeSummary:summary];
}
summary.lastMessage.others[@"lastEventDate"] = [eventFormatter dateStringFromEvent:event withTime:YES];
[self->mxSession.store storeSummaryForRoom:summary.roomId summary:summary];
}
dispatch_group_leave(dispatchGroup);
} failure:^(NSError *error) {
dispatch_group_leave(dispatchGroup);
}];
dispatch_group_leave(dispatchGroup);
} failure:^(NSError *error) {
dispatch_group_leave(dispatchGroup);
}];
}
}
dispatch_group_notify(dispatchGroup, dispatch_get_main_queue(), ^{
@@ -33,7 +33,6 @@ typedef enum : NSUInteger {
MXKAttachmentTypeAudio,
MXKAttachmentTypeVoiceMessage,
MXKAttachmentTypeVideo,
MXKAttachmentTypeLocation,
MXKAttachmentTypeFile,
MXKAttachmentTypeSticker
@@ -91,7 +91,7 @@ NSString *const kMXKAttachmentFileNameBase = @"attatchment";
else
{
// Note: mxEvent.eventType is supposed to be MXEventTypeRoomMessage here.
NSString *msgtype = eventContent[@"msgtype"];
NSString *msgtype = eventContent[kMXMessageTypeKey];
if ([msgtype isEqualToString:kMXMessageTypeImage])
{
_type = MXKAttachmentTypeImage;
@@ -109,12 +109,6 @@ NSString *const kMXKAttachmentFileNameBase = @"attatchment";
_type = MXKAttachmentTypeVideo;
MXJSONModelSetDictionary(_thumbnailInfo, eventContent[@"info"][@"thumbnail_info"]);
}
else if ([msgtype isEqualToString:kMXMessageTypeLocation])
{
// Not supported yet
// _type = MXKAttachmentTypeLocation;
return nil;
}
else if ([msgtype isEqualToString:kMXMessageTypeFile])
{
_type = MXKAttachmentTypeFile;
@@ -125,7 +119,7 @@ NSString *const kMXKAttachmentFileNameBase = @"attatchment";
}
}
MXJSONModelSetString(_originalFileName, eventContent[@"body"]);
MXJSONModelSetString(_originalFileName, eventContent[kMXMessageBodyKey]);
MXJSONModelSetDictionary(_contentInfo, eventContent[@"info"]);
MXJSONModelSetMXJSONModel(contentFile, MXEncryptedContentFile, eventContent[@"file"]);
@@ -102,7 +102,7 @@ static NSAttributedString *messageSeparator = nil;
return NO;
}
}
// Add all components of the provided message
for (MXKRoomBubbleComponent* component in cellData.bubbleComponents)
{
@@ -124,7 +124,7 @@
return;
}
NSString *messageType = self.event.content[@"msgtype"];
NSString *messageType = self.event.content[kMXMessageTypeKey];
if (!messageType || !([messageType isEqualToString:kMXMessageTypeText] || [messageType isEqualToString:kMXMessageTypeNotice] || [messageType isEqualToString:kMXMessageTypeEmote]))
{
@@ -605,6 +605,25 @@ extern NSString *const kMXKRoomDataSourceTimelineErrorErrorKey;
success:(void (^)(NSString *eventId))success
failure:(void (^)(NSError *error))failure;
/**
Send a location message to a room.
While sending, a fake event will be echoed in the messages list.
Once complete, this local echo will be replaced by the event saved by the homeserver.
@param latitude the location's latitude
@param longitude the location's longitude
@param description an optional description
@param success A block object called when the operation succeeds. It returns
the event id of the event generated on the homeserver
@param failure A block object called when the operation fails.
*/
- (void)sendLocationWithLatitude:(double)latitude
longitude:(double)longitude
description:(NSString *)description
success:(void (^)(NSString *))success
failure:(void (^)(NSError *))failure;
/**
Send a generic non state event to a room.
@@ -2062,6 +2062,29 @@ typedef NS_ENUM (NSUInteger, MXKRoomDataSourceError) {
}
}
- (void)sendLocationWithLatitude:(double)latitude
longitude:(double)longitude
description:(NSString *)description
success:(void (^)(NSString *))success
failure:(void (^)(NSError *))failure
{
__block MXEvent *localEchoEvent = nil;
// Make the request to the homeserver
[_room sendLocationWithLatitude:latitude
longitude:longitude
description:description
localEcho:&localEchoEvent
success:success failure:failure];
if (localEchoEvent)
{
// Make the data source digest this fake local echo message
[self queueEventForProcessing:localEchoEvent withRoomState:self.roomState direction:MXTimelineDirectionForwards];
[self processQueuedEvents:nil];
}
}
- (void)sendEventOfType:(MXEventTypeString)eventTypeString content:(NSDictionary<NSString*, id>*)msgContent success:(void (^)(NSString *eventId))success failure:(void (^)(NSError *error))failure
{
__block MXEvent *localEchoEvent = nil;
@@ -2099,7 +2122,7 @@ typedef NS_ENUM (NSUInteger, MXKRoomDataSourceError) {
else if ([event.type isEqualToString:kMXEventTypeStringRoomMessage])
{
// And retry the send the message according to its type
NSString *msgType = event.content[@"msgtype"];
NSString *msgType = event.content[kMXMessageTypeKey];
if ([msgType isEqualToString:kMXMessageTypeText] || [msgType isEqualToString:kMXMessageTypeEmote])
{
// Resend the Matrix event by reusing the existing echo
@@ -2860,7 +2883,7 @@ typedef NS_ENUM (NSUInteger, MXKRoomDataSourceError) {
return NO;
}
NSString *messageType = event.content[@"msgtype"];
NSString *messageType = event.content[kMXMessageTypeKey];
if (messageType == nil || [messageType isEqualToString:@"m.bad.encrypted"]) {
return NO;
}
@@ -4058,7 +4081,7 @@ typedef NS_ENUM (NSUInteger, MXKRoomDataSourceError) {
if ([self canPerformActionOnEvent:event])
{
NSString *messageType = event.content[@"msgtype"];
NSString *messageType = event.content[kMXMessageTypeKey];
if ([messageType isEqualToString:kMXMessageTypeKeyVerificationRequest])
{
@@ -4101,7 +4124,7 @@ typedef NS_ENUM (NSUInteger, MXKRoomDataSourceError) {
{
MXEvent *event = [self eventWithEventId:eventId];
BOOL isRoomMessage = event.eventType == MXEventTypeRoomMessage;
NSString *messageType = event.content[@"msgtype"];
NSString *messageType = event.content[kMXMessageTypeKey];
return isRoomMessage
&& ([messageType isEqualToString:kMXMessageTypeText] || [messageType isEqualToString:kMXMessageTypeEmote])
@@ -4122,7 +4145,7 @@ typedef NS_ENUM (NSUInteger, MXKRoomDataSourceError) {
}
else
{
editableTextMessage = event.content[@"body"];
editableTextMessage = event.content[kMXMessageBodyKey];
}
return editableTextMessage;
@@ -4239,7 +4262,7 @@ typedef NS_ENUM (NSUInteger, MXKRoomDataSourceError) {
NSString *sanitizedText = [self sanitizedMessageText:text];
NSString *formattedText = [self htmlMessageFromSanitizedText:sanitizedText];
NSString *eventBody = event.content[@"body"];
NSString *eventBody = event.content[kMXMessageBodyKey];
NSString *eventFormattedBody = event.content[@"formatted_body"];
if (![sanitizedText isEqualToString:eventBody] && (!eventFormattedBody || ![formattedText isEqualToString:eventFormattedBody]))
@@ -45,6 +45,11 @@
return [MatrixKitL10n messageReplyToSenderSentAFile];
}
- (NSString *)senderSentTheirLocation
{
return [MatrixKitL10n messageReplyToSenderSentTheirLocation];
}
- (NSString *)messageToReplyToPrefix
{
return [MatrixKitL10n messageReplyToMessageToReplyToPrefix];
@@ -46,7 +46,14 @@
- (MXSession *)mxSession
{
return dataSource.mxSession;
MXSession *session = dataSource.mxSession;
if (session == nil)
{
session = roomSummary.mxSession;
}
return session;
}
- (NSString*)lastEventDate
@@ -25,52 +25,6 @@
#pragma mark - Constant definitions
NSString *const kMXKRecentCellIdentifier = @"kMXKRecentCellIdentifier";
static NSTimeInterval const roomSummaryChangeThrottlerDelay = .5;
@interface MXKSessionRecentsDataSource ()
{
MXKRoomDataSourceManager *roomDataSourceManager;
/**
Internal array used to regulate change notifications.
Cell data changes are stored instantly in this array.
These changes are reported to the delegate only if no server sync is in progress.
*/
NSMutableArray *internalCellDataArray;
/**
Store the current search patterns list.
*/
NSArray* searchPatternsList;
/**
Do not react on every summary change
*/
MXThrottler *roomSummaryChangeThrottler;
/**
Last received suggested rooms per space ID
*/
NSMutableDictionary<NSString*, NSArray<MXSpaceChildInfo *> *> *lastSuggestedRooms;
/**
Event listener of the current space used to update the UI if an event occurs.
*/
id spaceEventsListener;
/**
Observer used to reload data when the space service is initialised
*/
id spaceServiceDidInitialiseObserver;
}
/**
Additional suggestedRooms related to the current selected Space
*/
@property (nonatomic, strong) NSArray<MXSpaceChildInfo *> *suggestedRooms;
@end
@implementation MXKSessionRecentsDataSource
@@ -79,474 +33,52 @@ static NSTimeInterval const roomSummaryChangeThrottlerDelay = .5;
self = [super initWithMatrixSession:matrixSession];
if (self)
{
roomDataSourceManager = [MXKRoomDataSourceManager sharedManagerForMatrixSession:self.mxSession];
// Update here data source state
if (state != MXKDataSourceStateReady)
{
state = MXKDataSourceStateReady;
if (self.delegate && [self.delegate respondsToSelector:@selector(dataSource:didStateChange:)])
{
[self.delegate dataSource:self didStateChange:state];
}
}
internalCellDataArray = [NSMutableArray array];
filteredCellDataArray = nil;
lastSuggestedRooms = [NSMutableDictionary new];
// Set default data and view classes
[self registerCellDataClass:MXKRecentCellData.class forCellIdentifier:kMXKRecentCellIdentifier];
roomSummaryChangeThrottler = [[MXThrottler alloc] initWithMinimumDelay:roomSummaryChangeThrottlerDelay];
[[MXKAppSettings standardAppSettings] addObserver:self forKeyPath:@"showAllRoomsInHomeSpace" options:0 context:nil];
// And inform the delegate about the update
[self.delegate dataSource:self didCellChange:nil];
}
return self;
}
- (void)destroy
{
[[NSNotificationCenter defaultCenter] removeObserver:self name:kMXRoomSummaryDidChangeNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:kMXKRoomDataSourceSyncStatusChanged object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:kMXSessionNewRoomNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:kMXSessionDidLeaveRoomNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:kMXSessionDirectRoomsDidChangeNotification object:nil];
if (spaceServiceDidInitialiseObserver) {
[[NSNotificationCenter defaultCenter] removeObserver:spaceServiceDidInitialiseObserver];
}
[roomSummaryChangeThrottler cancelAll];
roomSummaryChangeThrottler = nil;
cellDataArray = nil;
internalCellDataArray = nil;
filteredCellDataArray = nil;
lastSuggestedRooms = nil;
searchPatternsList = nil;
[[MXKAppSettings standardAppSettings] removeObserver:self forKeyPath:@"showAllRoomsInHomeSpace" context:nil];
[super destroy];
}
- (void)didMXSessionStateChange
{
if (MXSessionStateStoreDataReady <= self.mxSession.state)
{
// Check whether some data have been already load
if (0 == internalCellDataArray.count)
{
[self loadData];
}
else if (!roomDataSourceManager.isServerSyncInProgress)
{
// Sort cell data and notify the delegate
[self sortCellDataAndNotifyChanges];
}
}
}
- (void)setCurrentSpace:(MXSpace *)currentSpace
{
if (_currentSpace == currentSpace)
{
return;
}
if (_currentSpace && spaceEventsListener)
{
[_currentSpace.room removeListener:spaceEventsListener];
}
_currentSpace = currentSpace;
self.suggestedRooms = _currentSpace ? lastSuggestedRooms[_currentSpace.spaceId] : nil;
[self updateSuggestedRooms];
MXWeakify(self);
spaceEventsListener = [self.currentSpace.room listenToEvents:^(MXEvent *event, MXTimelineDirection direction, MXRoomState *roomState) {
MXStrongifyAndReturnIfNil(self);
[self updateSuggestedRooms];
}];
}
-(void)setSuggestedRooms:(NSArray<MXSpaceChildInfo *> *)suggestedRooms
{
_suggestedRooms = suggestedRooms;
[self loadData];
}
-(void)updateSuggestedRooms
{
if (self.currentSpace)
{
NSString *currentSpaceId = self.currentSpace.spaceId;
MXWeakify(self);
[self.mxSession.spaceService getSpaceChildrenForSpaceWithId:currentSpaceId suggestedOnly:YES limit:5 maxDepth:1 paginationToken:nil success:^(MXSpaceChildrenSummary * _Nonnull childrenSummary) {
MXLogDebug(@"[MXKSessionRecentsDataSource] getSpaceChildrenForSpaceWithId %@: %ld found", self.currentSpace.spaceId, childrenSummary.childInfos.count);
MXStrongifyAndReturnIfNil(self);
self->lastSuggestedRooms[currentSpaceId] = childrenSummary.childInfos;
if ([self.currentSpace.spaceId isEqual:currentSpaceId]) {
self.suggestedRooms = childrenSummary.childInfos;
}
} failure:^(NSError * _Nonnull error) {
MXLogError(@"[MXKSessionRecentsDataSource] getSpaceChildrenForSpaceWithId failed with error: %@", error);
}];
}
}
#pragma mark -
- (NSInteger)numberOfCells
{
if (filteredCellDataArray)
{
return filteredCellDataArray.count;
}
return cellDataArray.count;
return 0;
}
- (BOOL)hasUnread
{
// Check all current cells
// Use numberOfRowsInSection methods so that we take benefit of the filtering
for (NSUInteger i = 0; i < self.numberOfCells; i++)
{
id<MXKRecentCellDataStoring> cellData = [self cellDataAtIndex:i];
if (cellData.hasUnread)
{
return YES;
}
}
return NO;
}
- (void)searchWithPatterns:(NSArray*)patternsList
{
if (patternsList.count)
{
searchPatternsList = patternsList;
if (filteredCellDataArray)
{
[filteredCellDataArray removeAllObjects];
}
else
{
filteredCellDataArray = [NSMutableArray arrayWithCapacity:cellDataArray.count];
}
for (id<MXKRecentCellDataStoring> cellData in cellDataArray)
{
for (NSString* pattern in patternsList)
{
if (cellData.roomDisplayname && [cellData.roomDisplayname rangeOfString:pattern options:NSCaseInsensitiveSearch].location != NSNotFound)
{
[filteredCellDataArray addObject:cellData];
break;
}
}
}
}
else
{
filteredCellDataArray = nil;
searchPatternsList = nil;
}
[self.delegate dataSource:self didCellChange:nil];
}
- (id<MXKRecentCellDataStoring>)cellDataAtIndex:(NSInteger)index
{
if (filteredCellDataArray)
{
if (index < filteredCellDataArray.count)
{
return filteredCellDataArray[index];
}
}
else if (index < cellDataArray.count)
{
return cellDataArray[index];
}
return nil;
}
- (CGFloat)cellHeightAtIndex:(NSInteger)index
{
if (self.delegate)
{
id<MXKRecentCellDataStoring> cellData = [self cellDataAtIndex:index];
Class<MXKCellRendering> class = [self.delegate cellViewClassForCellData:cellData];
return [class heightForCellData:cellData withMaximumWidth:0];
}
return 0;
}
#pragma mark - Events processing
/**
Filtering in this method won't have any effect anymore. This class is not maintained.
*/
- (void)loadData
{
[[NSNotificationCenter defaultCenter] removeObserver:self name:kMXRoomSummaryDidChangeNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:kMXKRoomDataSourceSyncStatusChanged object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:kMXSessionNewRoomNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:kMXSessionDidLeaveRoomNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:kMXSessionDirectRoomsDidChangeNotification object:nil];
if (!self.mxSession.spaceService.isInitialised && !spaceServiceDidInitialiseObserver) {
MXWeakify(self);
spaceServiceDidInitialiseObserver = [[NSNotificationCenter defaultCenter] addObserverForName:MXSpaceService.didInitialise object:self.mxSession.spaceService queue:nil usingBlock:^(NSNotification * _Nonnull note) {
MXStrongifyAndReturnIfNil(self);
[self loadData];
}];
}
// Reset the table
[internalCellDataArray removeAllObjects];
// Retrieve the MXKCellData class to manage the data
Class class = [self cellDataClassForCellIdentifier:kMXKRecentCellIdentifier];
NSAssert([class conformsToProtocol:@protocol(MXKRecentCellDataStoring)], @"MXKSessionRecentsDataSource only manages MXKCellData that conforms to MXKRecentCellDataStoring protocol");
NSDate *startDate = [NSDate date];
for (MXRoomSummary *roomSummary in self.mxSession.roomsSummaries)
{
// Filter out private rooms with conference users
if (!roomSummary.isConferenceUserRoom // @TODO Abstract this condition with roomSummary.hiddenFromUser
&& !roomSummary.hiddenFromUser)
{
id<MXKRecentCellDataStoring> cellData = [[class alloc] initWithRoomSummary:roomSummary dataSource:self];
if (cellData)
{
[internalCellDataArray addObject:cellData];
}
}
}
for (MXSpaceChildInfo *childInfo in _suggestedRooms)
{
id<MXRoomSummaryProtocol> summary = [[MXRoomSummary alloc] initWithSpaceChildInfo:childInfo];
id<MXKRecentCellDataStoring> cellData = [[class alloc] initWithRoomSummary:summary
dataSource:self];
if (cellData)
{
[internalCellDataArray addObject:cellData];
}
}
MXLogDebug(@"[MXKSessionRecentsDataSource] Loaded %tu recents in %.3fms", self.mxSession.rooms.count, [[NSDate date] timeIntervalSinceDate:startDate] * 1000);
// Make sure all rooms have a last message
[self.mxSession fixRoomsSummariesLastMessage];
// Report loaded array except if sync is in progress
if (!roomDataSourceManager.isServerSyncInProgress)
{
[self sortCellDataAndNotifyChanges];
}
// Listen to MXSession rooms count changes
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didMXSessionHaveNewRoom:) name:kMXSessionNewRoomNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didMXSessionDidLeaveRoom:) name:kMXSessionDidLeaveRoomNotification object:nil];
// Listen to the direct rooms list
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didDirectRoomsChange:) name:kMXSessionDirectRoomsDidChangeNotification object:nil];
// Listen to MXRoomSummary
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didRoomSummaryChanged:) name:kMXRoomSummaryDidChangeNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didMXSessionStateChange) name:kMXKRoomDataSourceSyncStatusChanged object:nil];
}
- (void)didDirectRoomsChange:(NSNotification *)notif
{
// Inform the delegate about the update
[self.delegate dataSource:self didCellChange:nil];
}
- (void)didRoomSummaryChanged:(NSNotification *)notif
{
[roomSummaryChangeThrottler throttle:^{
[self didRoomSummaryChanged2:notif];
}];
}
- (void)didRoomSummaryChanged2:(NSNotification *)notif
{
MXRoomSummary *roomSummary = notif.object;
if (roomSummary.mxSession == self.mxSession && internalCellDataArray.count)
{
// Find the index of the related cell data
NSInteger index = NSNotFound;
for (index = 0; index < internalCellDataArray.count; index++)
{
id<MXKRecentCellDataStoring> theRoomData = [internalCellDataArray objectAtIndex:index];
if (theRoomData.roomSummary == roomSummary)
{
break;
}
}
if (index < internalCellDataArray.count)
{
if (roomSummary.hiddenFromUser)
{
[internalCellDataArray removeObjectAtIndex:index];
}
else
{
// Create a new instance to not modify the content of 'cellDataArray' (the copy is not a deep copy).
Class class = [self cellDataClassForCellIdentifier:kMXKRecentCellIdentifier];
id<MXKRecentCellDataStoring> cellData = [[class alloc] initWithRoomSummary:roomSummary dataSource:self];
if (cellData)
{
[internalCellDataArray replaceObjectAtIndex:index withObject:cellData];
}
}
// Report change except if sync is in progress
if (!roomDataSourceManager.isServerSyncInProgress)
{
[self sortCellDataAndNotifyChanges];
}
}
else
{
MXLogDebug(@"[MXKSessionRecentsDataSource] didRoomLastMessageChanged: Cannot find the changed room summary for %@ (%@). It is probably not managed by this recents data source", roomSummary.roomId, roomSummary);
}
}
else
{
// Inform the delegate that all the room summaries have been updated.
[self.delegate dataSource:self didCellChange:nil];
}
}
- (void)didMXSessionHaveNewRoom:(NSNotification *)notif
{
MXSession *mxSession = notif.object;
if (mxSession == self.mxSession)
{
NSString *roomId = notif.userInfo[kMXSessionNotificationRoomIdKey];
// Add the room if there is not yet a cell for it
id<MXKRecentCellDataStoring> roomData = [self cellDataWithRoomId:roomId];
if (nil == roomData)
{
MXLogDebug(@"MXKSessionRecentsDataSource] Add newly joined room: %@", roomId);
// Retrieve the MXKCellData class to manage the data
Class class = [self cellDataClassForCellIdentifier:kMXKRecentCellIdentifier];
MXRoomSummary *roomSummary = [mxSession roomSummaryWithRoomId:roomId];
id<MXKRecentCellDataStoring> cellData = [[class alloc] initWithRoomSummary:roomSummary dataSource:self];
if (cellData)
{
[internalCellDataArray addObject:cellData];
// Report change except if sync is in progress
if (!roomDataSourceManager.isServerSyncInProgress)
{
[self sortCellDataAndNotifyChanges];
}
}
}
}
}
- (void)didMXSessionDidLeaveRoom:(NSNotification *)notif
{
MXSession *mxSession = notif.object;
if (mxSession == self.mxSession)
{
NSString *roomId = notif.userInfo[kMXSessionNotificationRoomIdKey];
id<MXKRecentCellDataStoring> roomData = [self cellDataWithRoomId:roomId];
if (roomData)
{
MXLogDebug(@"MXKSessionRecentsDataSource] Remove left room: %@", roomId);
[internalCellDataArray removeObject:roomData];
// Report change except if sync is in progress
if (!roomDataSourceManager.isServerSyncInProgress)
{
[self sortCellDataAndNotifyChanges];
}
}
}
}
// Order cells
- (void)sortCellDataAndNotifyChanges
{
// Order them by origin_server_ts
[internalCellDataArray sortUsingComparator:^NSComparisonResult(id<MXKRecentCellDataStoring> cellData1, id<MXKRecentCellDataStoring> cellData2)
{
return [cellData1.roomSummary.lastMessage compareOriginServerTs:cellData2.roomSummary.lastMessage];
}];
// Snapshot the cell data array
cellDataArray = [internalCellDataArray copy];
// Update search result if any
if (searchPatternsList)
{
[self searchWithPatterns:searchPatternsList];
}
// Update here data source state
if (state != MXKDataSourceStateReady)
{
state = MXKDataSourceStateReady;
if (self.delegate && [self.delegate respondsToSelector:@selector(dataSource:didStateChange:)])
{
[self.delegate dataSource:self didStateChange:state];
}
}
// And inform the delegate about the update
[self.delegate dataSource:self didCellChange:nil];
}
// Find the cell data that stores information about the given room id
- (id<MXKRecentCellDataStoring>)cellDataWithRoomId:(NSString*)roomId
{
id<MXKRecentCellDataStoring> theRoomData;
NSMutableArray *dataArray = internalCellDataArray;
if (!roomDataSourceManager.isServerSyncInProgress)
{
dataArray = cellDataArray;
}
for (id<MXKRecentCellDataStoring> roomData in dataArray)
{
if ([roomData.roomSummary.roomId isEqualToString:roomId])
{
theRoomData = roomData;
break;
}
}
return theRoomData;
}
#pragma mark - KVO
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context
{
if (object == [MXKAppSettings standardAppSettings] && [keyPath isEqualToString:@"showAllRoomsInHomeSpace"])
{
if (self.currentSpace == nil)
{
[self loadData];
}
}
return nil;
}
@end
@@ -56,7 +56,7 @@
date = [searchDataSource.eventFormatter dateStringFromEvent:searchResult.result withTime:YES];
// Code from [MXEventFormatter stringFromEvent] for the particular case of a text message
message = [searchResult.result.content[@"body"] isKindOfClass:[NSString class]] ? searchResult.result.content[@"body"] : nil;
message = [searchResult.result.content[kMXMessageBodyKey] isKindOfClass:[NSString class]] ? searchResult.result.content[kMXMessageBodyKey] : nil;
}
return self;
}