From 7af387251608d8a7de86bdee5e5ca987f52f1bdc Mon Sep 17 00:00:00 2001 From: giomfo <giom@matrix.org> Date: Sat, 16 Jul 2016 00:40:21 +0200 Subject: [PATCH 1/4] Redacting membership events should immediately reset the displayname & avatar of room members. https://github.com/vector-im/vector-ios/issues/443 - MXEventTimeline: prepare state event redaction. - MXRoom Notification break: rename "kMXRoomSyncWithLimitedTimelineNotification" with "kMXRoomDidFlushMessagesNotification" --- MatrixSDK/Data/MXEventTimeline.m | 152 +++++++++++++++++++++++++++++-- MatrixSDK/Data/MXRoom.h | 6 +- MatrixSDK/Data/MXRoom.m | 2 +- 3 files changed, 147 insertions(+), 13 deletions(-) diff --git a/MatrixSDK/Data/MXEventTimeline.m b/MatrixSDK/Data/MXEventTimeline.m index 9232e3b6ce..52896abc4f 100644 --- a/MatrixSDK/Data/MXEventTimeline.m +++ b/MatrixSDK/Data/MXEventTimeline.m @@ -19,6 +19,8 @@ #import "MXSession.h" #import "MXMemoryStore.h" +#import "MXEvent+MatrixKit.h" + #import "MXError.h" NSString *const kMXRoomInviteStateEventIdPrefix = @"invite-"; @@ -47,6 +49,11 @@ @interface MXEventTimeline () // past timelines is managed locally. NSString *forwardsPaginationToken; BOOL hasReachedHomeServerForwardsPaginationEnd; + + /** + The current pending request. + */ + MXHTTPOperation *httpOperation; } @end @@ -102,6 +109,13 @@ - (void)initialiseState:(NSArray<MXEvent *> *)stateEvents - (void)destroy { + if (httpOperation) + { + // Cancel the current server request + [httpOperation cancel]; + httpOperation = nil; + } + if (!_isLiveTimeline) { // Release past timeline events stored in memory @@ -409,7 +423,7 @@ - (void)handleJoinedRoomSync:(MXRoomSync *)roomSync else if (roomSync.timeline.limited) { // The room has been resync with a limited timeline - Post notification - [[NSNotificationCenter defaultCenter] postNotificationName:kMXRoomSyncWithLimitedTimelineNotification + [[NSNotificationCenter defaultCenter] postNotificationName:kMXRoomDidFlushMessagesNotification object:room userInfo:nil]; } @@ -537,7 +551,9 @@ - (void)addEvent:(MXEvent*)event direction:(MXTimelineDirection)direction fromSt #pragma mark - Specific events Handling - (void)handleRedaction:(MXEvent*)redactionEvent { - // Check whether the redacted event has been already processed + NSLog(@"[MXEventTimeline] handle an event redaction"); + + // Check whether the redacted event is stored in room messages MXEvent *redactedEvent = [store eventWithEventId:redactionEvent.redacts inRoom:_state.roomId]; if (redactedEvent) { @@ -545,15 +561,133 @@ - (void)handleRedaction:(MXEvent*)redactionEvent redactedEvent = [redactedEvent prune]; redactedEvent.redactedBecause = redactionEvent.JSONDictionary; - if (redactedEvent.isState) { - // FIXME: The room state must be refreshed here since this redacted event. - } - - // Store the event + // Store the updated event [store replaceEvent:redactedEvent inRoom:_state.roomId]; } + + // Check whether the current room state depends on this redacted event. + if (!redactedEvent || redactedEvent.isState) + { + // FIXME: Is @autoreleasepool block required or not here? + NSArray *stateEvents = _state.stateEvents; + + for (MXEvent *stateEvent in stateEvents) + { + if ([stateEvent.eventId isEqualToString:redactionEvent.redacts]) + { + NSLog(@"[MXEventTimeline] the current room state has been modified by the event redaction."); + + // Redact the stored event + redactedEvent = [stateEvent prune]; + redactedEvent.redactedBecause = redactionEvent.JSONDictionary; + + // Reset the room state. //FIXME: is it possible to handle only the redacted event? + _state = [[MXRoomState alloc] initWithRoomId:room.roomId andMatrixSession:room.mxSession andDirection:YES]; + [self initialiseState:stateEvents]; + + // Update store with new room state when all state event have been processed + if ([store respondsToSelector:@selector(storeStateForRoom:stateEvents:)]) + { + [store storeStateForRoom:_state.roomId stateEvents:_state.stateEvents]; + } + + // Reset the current pagination + // FIXME: Shall we let the kMXRoomStateHasBeenRedactedNotification listener trigger this reset? (like [MXKRoomDataSource reload] do) + [self resetPagination]; + + // Notify that room history has been flushed + [[NSNotificationCenter defaultCenter] postNotificationName:kMXRoomDidFlushMessagesNotification + object:room + userInfo:nil]; + return; + } + } + } + + // Re-sync the room in case of redacted state event from the past. + // Indeed, redacted information shouldn't spontaneously appear when you backpaginate... + if (!redactedEvent) + { + // Use a /context request to check whether the redacted event is a state event or not. + httpOperation = [room.mxSession.matrixRestClient contextOfEvent:redactionEvent.redacts inRoom:room.roomId limit:1 success:^(MXEventContext *eventContext) { + + if (!httpOperation) + { + return; + } + httpOperation = nil; + + if (eventContext.event.isState) + { + NSLog(@"[MXEventTimeline] the redacted event is a state event from the past"); + [self forceRoomServerSync]; + } + + } failure:^(NSError *error) { + + if (!httpOperation) + { + return; + } + httpOperation = nil; + + NSLog(@"[MXEventTimeline] handleRedaction: failed to retrieved the redacted event"); + [self forceRoomServerSync]; + }]; + } + else if (redactedEvent.isState) + { + NSLog(@"[MXEventTimeline] the redacted event is a former state event"); + [self forceRoomServerSync]; + } } +- (void)forceRoomServerSync +{ + // Reset the storage of this room. Re-sync it from the server + NSLog(@"[MXEventTimeline] re-sync room (%@) from the server.", room.roomId); + [store deleteRoom:room.roomId]; + + // Make an /initialSync request to get data + // Use a 0 messages limit for now because: + // - /initialSync is marked as obsolete in the spec + // - MXEventTimeline does not have methods to handle /initialSync responses + // So, avoid to write temparary code and let the user uses [MXEventTimeline paginate] + // to get room messages. + httpOperation = [room.mxSession.matrixRestClient initialSyncOfRoom:room.roomId withLimit:0 success:^(MXRoomInitialSync *roomInitialSync) { + + if (!httpOperation) + { + return; + } + httpOperation = nil; + + _state = [[MXRoomState alloc] initWithRoomId:room.roomId andMatrixSession:room.mxSession andDirection:YES]; + [self initialiseState:roomInitialSync.state]; + + // Update store with new room state when all state event have been processed + if ([store respondsToSelector:@selector(storeStateForRoom:stateEvents:)]) + { + [store storeStateForRoom:_state.roomId stateEvents:_state.stateEvents]; + } + + [self resetPagination]; + + // Notify that room history has been flushed + [[NSNotificationCenter defaultCenter] postNotificationName:kMXRoomDidFlushMessagesNotification + object:room + userInfo:nil]; + + } failure:^(NSError *error) { + + NSLog(@"[MXEventTimeline] forceRoomServerSync failed."); + + // FIXME: Reload entirely the app? +// [[NSNotificationCenter defaultCenter] postNotificationName:kMXSessionIgnoredUsersDidChangeNotification +// object:room.mxSession +// userInfo:nil]; + }]; +} #pragma mark - State events handling - (void)cloneState:(MXTimelineDirection)direction @@ -584,8 +718,8 @@ - (void)handleStateEvent:(MXEvent*)event direction:(MXTimelineDirection)directio // Forwards events update the current state of the room [_state handleStateEvent:event]; - // Special handling for presence - if (_isLiveTimeline && MXEventTypeRoomMember == event.eventType) + // Special handling for presence (CAUTION: ignore redacted state event here) + if (_isLiveTimeline && MXEventTypeRoomMember == event.eventType && !event.isRedactedEvent) { // Update MXUser data MXUser *user = [room.mxSession getOrCreateUser:event.sender]; diff --git a/MatrixSDK/Data/MXRoom.h b/MatrixSDK/Data/MXRoom.h index d9525a88e4..fb5fb0810b 100644 --- a/MatrixSDK/Data/MXRoom.h +++ b/MatrixSDK/Data/MXRoom.h @@ -39,13 +39,13 @@ FOUNDATION_EXPORT NSString *const kMXRoomInitialSyncNotification; /** - Posted when a limited timeline is observed for an existing room during server sync. - All the existing messages have been removed from the room storage. Only the messages received during this sync are available. + Posted when the messages of an existing room has been flushed during server sync. + This flush may be due to a limited timeline in the room sync, or the redaction of a state event. The token where to start back pagination has been updated. The notification object is the concerned room (MXRoom instance). */ -FOUNDATION_EXPORT NSString *const kMXRoomSyncWithLimitedTimelineNotification; +FOUNDATION_EXPORT NSString *const kMXRoomDidFlushMessagesNotification; /** Posted when the number of unread notifications ('notificationCount' and 'highlightCount' properties) are updated. diff --git a/MatrixSDK/Data/MXRoom.m b/MatrixSDK/Data/MXRoom.m index 6d71954f78..53600b66aa 100644 --- a/MatrixSDK/Data/MXRoom.m +++ b/MatrixSDK/Data/MXRoom.m @@ -21,7 +21,7 @@ #import "MXError.h" -NSString *const kMXRoomSyncWithLimitedTimelineNotification = @"kMXRoomSyncWithLimitedTimelineNotification"; +NSString *const kMXRoomDidFlushMessagesNotification = @"kMXRoomDidFlushMessagesNotification"; NSString *const kMXRoomInitialSyncNotification = @"kMXRoomInitialSyncNotification"; NSString *const kMXRoomDidUpdateUnreadNotification = @"kMXRoomDidUpdateUnreadNotification"; From ae312a3dca705f1e8a4eda42203fb8da5b80b067 Mon Sep 17 00:00:00 2001 From: giomfo <giom@matrix.org> Date: Mon, 18 Jul 2016 01:03:29 +0200 Subject: [PATCH 2/4] Redacting membership events should immediately reset the displayname & avatar of room members. vector-im/vector-ios#443 - Fix: The redacted state event was ignored in room state handling - Add FIXME related to the blocker issue on server side SYN-724 ("prev_content is totally pruned by the server on redacted membership event"). --- MatrixSDK/Data/MXEventTimeline.m | 8 ++++++-- MatrixSDK/Data/MXRoomState.m | 21 +++++++++++++-------- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/MatrixSDK/Data/MXEventTimeline.m b/MatrixSDK/Data/MXEventTimeline.m index 52896abc4f..f155626ba6 100644 --- a/MatrixSDK/Data/MXEventTimeline.m +++ b/MatrixSDK/Data/MXEventTimeline.m @@ -569,10 +569,12 @@ - (void)handleRedaction:(MXEvent*)redactionEvent if (!redactedEvent || redactedEvent.isState) { // FIXME: Is @autoreleasepool block required or not here? - NSArray *stateEvents = _state.stateEvents; + NSMutableArray *stateEvents = [NSMutableArray arrayWithArray:_state.stateEvents]; - for (MXEvent *stateEvent in stateEvents) + for (NSInteger index = 0; index < stateEvents.count; index++) { + MXEvent *stateEvent = stateEvents[index]; + if ([stateEvent.eventId isEqualToString:redactionEvent.redacts]) { NSLog(@"[MXEventTimeline] the current room state has been modified by the event redaction."); @@ -581,6 +583,8 @@ - (void)handleRedaction:(MXEvent*)redactionEvent redactedEvent = [stateEvent prune]; redactedEvent.redactedBecause = redactionEvent.JSONDictionary; + [stateEvents replaceObjectAtIndex:index withObject:redactedEvent]; + // Reset the room state. //FIXME: is it possible to handle only the redacted event? _state = [[MXRoomState alloc] initWithRoomId:room.roomId andMatrixSession:room.mxSession andDirection:YES]; [self initialiseState:stateEvents]; diff --git a/MatrixSDK/Data/MXRoomState.m b/MatrixSDK/Data/MXRoomState.m index 183484f906..0118c8f4ff 100644 --- a/MatrixSDK/Data/MXRoomState.m +++ b/MatrixSDK/Data/MXRoomState.m @@ -450,7 +450,8 @@ - (void)handleStateEvent:(MXEvent*)event membersWithThirdPartyInviteTokenCache[roomMember.thirdPartyInviteToken] = roomMember; } } - else + else// FIXME: In case of redacted membership event (prev_content is missing see SYN-724), + // the room member is then nil: the client considers by mistake the user is no more part of the room... { // The user is no more part of the room. Remove him. // This case happens during back pagination: we remove here users when they are not in the room yet. @@ -550,13 +551,17 @@ - (NSString*)memberName:(NSString*)userId if (!member) { - // The user may not have joined the room yet. So try to resolve display name from presence data - // Note: This data may not be available - MXUser* user = [mxSession userWithUserId:userId]; - if (user && user.displayname.length) - { - displayName = user.displayname; - } + // FIXME: In case of redacted membership event (prev_content is missing see SYN-724), + // the client considers by mistake that some users are no more part of the room. + // PATCH: we comment the following, else some redacted information re-appear spontaneously. + +// // The user may not have joined the room yet. So try to resolve display name from presence data +// // Note: This data may not be available +// MXUser* user = [mxSession userWithUserId:userId]; +// if (user && user.displayname.length) +// { +// displayName = user.displayname; +// } } else if (member.displayname.length) { From a8b97fb529af202c2a5b2c6117fa7b7d4ff2fac5 Mon Sep 17 00:00:00 2001 From: giomfo <giom@matrix.org> Date: Thu, 11 Aug 2016 17:52:43 +0200 Subject: [PATCH 3/4] Redacting membership events should immediately reset the displayname & avatar of room members. vector-im/vector-ios#443 - remove FIXME (the blocker issue SYN-724 has been fixed on server side). --- MatrixSDK/Data/MXEventTimeline.m | 13 ++++++------- MatrixSDK/Data/MXRoomState.m | 21 ++++++++------------- MatrixSDK/MXSession.h | 8 ++++++++ MatrixSDK/MXSession.m | 1 + 4 files changed, 23 insertions(+), 20 deletions(-) diff --git a/MatrixSDK/Data/MXEventTimeline.m b/MatrixSDK/Data/MXEventTimeline.m index f155626ba6..d51e7f4953 100644 --- a/MatrixSDK/Data/MXEventTimeline.m +++ b/MatrixSDK/Data/MXEventTimeline.m @@ -568,7 +568,6 @@ - (void)handleRedaction:(MXEvent*)redactionEvent // Check whether the current room state depends on this redacted event. if (!redactedEvent || redactedEvent.isState) { - // FIXME: Is @autoreleasepool block required or not here? NSMutableArray *stateEvents = [NSMutableArray arrayWithArray:_state.stateEvents]; for (NSInteger index = 0; index < stateEvents.count; index++) @@ -585,7 +584,7 @@ - (void)handleRedaction:(MXEvent*)redactionEvent [stateEvents replaceObjectAtIndex:index withObject:redactedEvent]; - // Reset the room state. //FIXME: is it possible to handle only the redacted event? + // Reset the room state. _state = [[MXRoomState alloc] initWithRoomId:room.roomId andMatrixSession:room.mxSession andDirection:YES]; [self initialiseState:stateEvents]; @@ -596,7 +595,7 @@ - (void)handleRedaction:(MXEvent*)redactionEvent } // Reset the current pagination - // FIXME: Shall we let the kMXRoomStateHasBeenRedactedNotification listener trigger this reset? (like [MXKRoomDataSource reload] do) + // FIXME: Shall we let the kMXRoomDidFlushMessagesNotification listener trigger this reset? (like [MXKRoomDataSource reload] do) [self resetPagination]; // Notify that room history has been flushed @@ -686,10 +685,10 @@ - (void)forceRoomServerSync NSLog(@"[MXEventTimeline] forceRoomServerSync failed."); - // FIXME: Reload entirely the app? -// [[NSNotificationCenter defaultCenter] postNotificationName:kMXSessionIgnoredUsersDidChangeNotification -// object:room.mxSession -// userInfo:nil]; + // Reload entirely the app + [[NSNotificationCenter defaultCenter] postNotificationName:kMXSessionDidCorruptDataNotification + object:room.mxSession + userInfo:nil]; }]; } diff --git a/MatrixSDK/Data/MXRoomState.m b/MatrixSDK/Data/MXRoomState.m index 8174f9c1a4..41722b21a0 100644 --- a/MatrixSDK/Data/MXRoomState.m +++ b/MatrixSDK/Data/MXRoomState.m @@ -462,8 +462,7 @@ - (void)handleStateEvent:(MXEvent*)event membersWithThirdPartyInviteTokenCache[roomMember.thirdPartyInviteToken] = roomMember; } } - else// FIXME: In case of redacted membership event (prev_content is missing see SYN-724), - // the room member is then nil: the client considers by mistake the user is no more part of the room... + else { // The user is no more part of the room. Remove him. // This case happens during back pagination: we remove here users when they are not in the room yet. @@ -568,17 +567,13 @@ - (NSString*)memberName:(NSString*)userId if (!member) { - // FIXME: In case of redacted membership event (prev_content is missing see SYN-724), - // the client considers by mistake that some users are no more part of the room. - // PATCH: we comment the following, else some redacted information re-appear spontaneously. - -// // The user may not have joined the room yet. So try to resolve display name from presence data -// // Note: This data may not be available -// MXUser* user = [mxSession userWithUserId:userId]; -// if (user && user.displayname.length) -// { -// displayName = user.displayname; -// } + // The user may not have joined the room yet. So try to resolve display name from presence data + // Note: This data may not be available + MXUser* user = [mxSession userWithUserId:userId]; + if (user && user.displayname.length) + { + displayName = user.displayname; + } } else if (member.displayname.length) { diff --git a/MatrixSDK/MXSession.h b/MatrixSDK/MXSession.h index 01c9af6353..0c2641c2e9 100644 --- a/MatrixSDK/MXSession.h +++ b/MatrixSDK/MXSession.h @@ -161,9 +161,17 @@ FOUNDATION_EXPORT NSString *const kMXSessionNotificationEventKey; /** Posted when MXSession has detected a change in the `ignoredUsers` property. + + The notification object is the concerned session (MXSession instance). */ FOUNDATION_EXPORT NSString *const kMXSessionIgnoredUsersDidChangeNotification; +/** + Posted when MXSession data have been corrupted. The listener must reload the session data with a full server sync. + + The notification object is the concerned session (MXSession instance). + */ +FOUNDATION_EXPORT NSString *const kMXSessionDidCorruptDataNotification; #pragma mark - Other constants /** diff --git a/MatrixSDK/MXSession.m b/MatrixSDK/MXSession.m index 1f8fa8816c..6f83879992 100644 --- a/MatrixSDK/MXSession.m +++ b/MatrixSDK/MXSession.m @@ -40,6 +40,7 @@ NSString *const kMXSessionNotificationRoomIdKey = @"roomId"; NSString *const kMXSessionNotificationEventKey = @"event"; NSString *const kMXSessionIgnoredUsersDidChangeNotification = @"kMXSessionIgnoredUsersDidChangeNotification"; +NSString *const kMXSessionDidCorruptDataNotification = @"kMXSessionDidCorruptDataNotification"; NSString *const kMXSessionNoRoomTag = @"m.recent"; // Use the same value as matrix-react-sdk /** From e1158a4ea56c2672f7a116231fb3475a43034de0 Mon Sep 17 00:00:00 2001 From: giomfo <giom@matrix.org> Date: Fri, 12 Aug 2016 16:47:57 +0200 Subject: [PATCH 4/4] Redacting membership events should immediately reset the displayname & avatar of room members. vector-im/vector-ios#443 Fix Manu's comments (https://github.com/matrix-org/matrix-ios-sdk/pull/118). --- MatrixSDK/Data/MXEventTimeline.m | 13 +++++-------- MatrixSDK/Data/MXRoom.h | 2 +- MatrixSDK/Data/MXRoom.m | 2 +- MatrixSDK/JSONModels/MXEvent.h | 12 +++++++++++- MatrixSDK/JSONModels/MXEvent.m | 19 +++++++++++++++++++ 5 files changed, 37 insertions(+), 11 deletions(-) diff --git a/MatrixSDK/Data/MXEventTimeline.m b/MatrixSDK/Data/MXEventTimeline.m index d51e7f4953..c711763391 100644 --- a/MatrixSDK/Data/MXEventTimeline.m +++ b/MatrixSDK/Data/MXEventTimeline.m @@ -19,8 +19,6 @@ #import "MXSession.h" #import "MXMemoryStore.h" -#import "MXEvent+MatrixKit.h" - #import "MXError.h" NSString *const kMXRoomInviteStateEventIdPrefix = @"invite-"; @@ -423,7 +421,7 @@ - (void)handleJoinedRoomSync:(MXRoomSync *)roomSync else if (roomSync.timeline.limited) { // The room has been resync with a limited timeline - Post notification - [[NSNotificationCenter defaultCenter] postNotificationName:kMXRoomDidFlushMessagesNotification + [[NSNotificationCenter defaultCenter] postNotificationName:kMXRoomDidFlushDataNotification object:room userInfo:nil]; } @@ -595,11 +593,10 @@ - (void)handleRedaction:(MXEvent*)redactionEvent } // Reset the current pagination - // FIXME: Shall we let the kMXRoomDidFlushMessagesNotification listener trigger this reset? (like [MXKRoomDataSource reload] do) [self resetPagination]; // Notify that room history has been flushed - [[NSNotificationCenter defaultCenter] postNotificationName:kMXRoomDidFlushMessagesNotification + [[NSNotificationCenter defaultCenter] postNotificationName:kMXRoomDidFlushDataNotification object:room userInfo:nil]; return; @@ -677,7 +674,7 @@ - (void)forceRoomServerSync [self resetPagination]; // Notify that room history has been flushed - [[NSNotificationCenter defaultCenter] postNotificationName:kMXRoomDidFlushMessagesNotification + [[NSNotificationCenter defaultCenter] postNotificationName:kMXRoomDidFlushDataNotification object:room userInfo:nil]; @@ -721,10 +718,10 @@ - (void)handleStateEvent:(MXEvent*)event direction:(MXTimelineDirection)directio // Forwards events update the current state of the room [_state handleStateEvent:event]; - // Special handling for presence (CAUTION: ignore redacted state event here) + // Special handling for presence: update MXUser data in case of membership event. + // CAUTION: ignore here redacted state event, the redaction concerns only the context of the event room. if (_isLiveTimeline && MXEventTypeRoomMember == event.eventType && !event.isRedactedEvent) { - // Update MXUser data MXUser *user = [room.mxSession getOrCreateUser:event.sender]; MXRoomMember *roomMember = [_state memberWithUserId:event.sender]; diff --git a/MatrixSDK/Data/MXRoom.h b/MatrixSDK/Data/MXRoom.h index e43766f69e..46e0034c14 100644 --- a/MatrixSDK/Data/MXRoom.h +++ b/MatrixSDK/Data/MXRoom.h @@ -45,7 +45,7 @@ FOUNDATION_EXPORT NSString *const kMXRoomInitialSyncNotification; The notification object is the concerned room (MXRoom instance). */ -FOUNDATION_EXPORT NSString *const kMXRoomDidFlushMessagesNotification; +FOUNDATION_EXPORT NSString *const kMXRoomDidFlushDataNotification; /** Posted when the number of unread notifications ('notificationCount' and 'highlightCount' properties) are updated. diff --git a/MatrixSDK/Data/MXRoom.m b/MatrixSDK/Data/MXRoom.m index 26c968b542..c955b47f9c 100644 --- a/MatrixSDK/Data/MXRoom.m +++ b/MatrixSDK/Data/MXRoom.m @@ -21,7 +21,7 @@ #import "MXError.h" -NSString *const kMXRoomDidFlushMessagesNotification = @"kMXRoomDidFlushMessagesNotification"; +NSString *const kMXRoomDidFlushDataNotification = @"kMXRoomDidFlushDataNotification"; NSString *const kMXRoomInitialSyncNotification = @"kMXRoomInitialSyncNotification"; NSString *const kMXRoomDidUpdateUnreadNotification = @"kMXRoomDidUpdateUnreadNotification"; diff --git a/MatrixSDK/JSONModels/MXEvent.h b/MatrixSDK/JSONModels/MXEvent.h index fa286da2fa..0ce6a61d4c 100644 --- a/MatrixSDK/JSONModels/MXEvent.h +++ b/MatrixSDK/JSONModels/MXEvent.h @@ -216,10 +216,20 @@ FOUNDATION_EXPORT uint64_t const kMXUndefinedTimestamp; - (MXEventType)eventType; /** - Indicates if the event hosts state data + Indicates if the event hosts state data. */ - (BOOL)isState; +/** + Indicates if the event has been redacted. + */ +- (BOOL)isRedactedEvent; + +/** + Return YES if the event is an emote event + */ +- (BOOL)isEmote; + /** Returns the event IDs for which a read receipt is defined in this event. diff --git a/MatrixSDK/JSONModels/MXEvent.m b/MatrixSDK/JSONModels/MXEvent.m index 37e03559d9..e08a9c29c1 100644 --- a/MatrixSDK/JSONModels/MXEvent.m +++ b/MatrixSDK/JSONModels/MXEvent.m @@ -225,6 +225,25 @@ - (BOOL)isState return (nil != self.stateKey); } +- (BOOL)isRedactedEvent +{ + // The event is redacted if its redactedBecause is filed (with a redaction event id) + return (self.redactedBecause != nil); +} + +- (BOOL)isEmote +{ + if (self.eventType == MXEventTypeRoomMessage) + { + NSString *msgtype = self.content[@"msgtype"]; + if ([msgtype isEqualToString:kMXMessageTypeEmote]) + { + return YES; + } + } + return NO; +} + - (NSArray *)readReceiptEventIds { NSMutableArray* list = nil;