diff --git a/CHANGES.rst b/CHANGES.rst index a642f983d3..33e7767bbb 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -2,6 +2,7 @@ Changes in Matrix iOS SDK in 0.16.6 (2020-05-xx) ================================================ Improvements: + * MXStore: Add a method to remove all the messages sent before a specific timestamp in a room. * MXCrypto: Only create one olm session at a time per device (vector-im/riot-ios/issues/2331). * MXCrossSigning: Add the bootstrapWithAuthParams method. * MXRecoveryService: Create this service to manage keys we want to store in SSSS. diff --git a/MatrixSDK/Data/Store/MXFileStore/MXFileStore.m b/MatrixSDK/Data/Store/MXFileStore/MXFileStore.m index 73ec69c859..8e6552f660 100644 --- a/MatrixSDK/Data/Store/MXFileStore/MXFileStore.m +++ b/MatrixSDK/Data/Store/MXFileStore/MXFileStore.m @@ -319,6 +319,18 @@ - (void)replaceEvent:(MXEvent*)event inRoom:(NSString*)roomId } } +- (BOOL)removeAllMessagesSentBefore:(uint64_t)limitTs inRoom:(nonnull NSString *)roomId +{ + BOOL ret = [super removeAllMessagesSentBefore:limitTs inRoom:roomId]; + + if (ret && NSNotFound == [roomsToCommitForMessages indexOfObject:roomId]) + { + [roomsToCommitForMessages addObject:roomId]; + } + + return ret; +} + - (void)deleteAllMessagesInRoom:(NSString *)roomId { [super deleteAllMessagesInRoom:roomId]; diff --git a/MatrixSDK/Data/Store/MXMemoryStore/MXMemoryRoomStore.h b/MatrixSDK/Data/Store/MXMemoryStore/MXMemoryRoomStore.h index 7d78eec4a9..37df52c675 100644 --- a/MatrixSDK/Data/Store/MXMemoryStore/MXMemoryRoomStore.h +++ b/MatrixSDK/Data/Store/MXMemoryStore/MXMemoryRoomStore.h @@ -51,6 +51,16 @@ */ - (void)replaceEvent:(MXEvent*)event; +/** + Remove all the messages sent before a specific timestamp in a room. + The state events are not removed during this operation. We keep them in the timeline. + + @param limitTs the timestamp from which the messages are kept. + + @return YES if at least one event has been removed. + */ +- (BOOL)removeAllMessagesSentBefore:(uint64_t)limitTs; + /** Get an event from this room. diff --git a/MatrixSDK/Data/Store/MXMemoryStore/MXMemoryRoomStore.m b/MatrixSDK/Data/Store/MXMemoryStore/MXMemoryRoomStore.m index e4653b4e9e..0522a0e582 100644 --- a/MatrixSDK/Data/Store/MXMemoryStore/MXMemoryRoomStore.m +++ b/MatrixSDK/Data/Store/MXMemoryStore/MXMemoryRoomStore.m @@ -76,6 +76,33 @@ - (void)replaceEvent:(MXEvent*)event } } +- (BOOL)removeAllMessagesSentBefore:(uint64_t)limitTs +{ + NSUInteger index = 0; + BOOL didChange = NO; + while (index < messages.count) + { + MXEvent *anEvent = messages[index]; + if (anEvent.isState) + { + // Keep state event + index++; + } + else if (anEvent.originServerTs < limitTs) + { + [messages removeObjectAtIndex:index]; + [messagesByEventIds removeObjectForKey:anEvent.eventId]; + didChange = YES; + } + else + { + // Break the loop, we've reached the first non-state event in the timeline which is not expired + break; + } + } + return didChange; +} + - (MXEvent *)eventWithEventId:(NSString *)eventId { return messagesByEventIds[eventId]; diff --git a/MatrixSDK/Data/Store/MXMemoryStore/MXMemoryStore.m b/MatrixSDK/Data/Store/MXMemoryStore/MXMemoryStore.m index 24aca78290..b6c396de5c 100644 --- a/MatrixSDK/Data/Store/MXMemoryStore/MXMemoryStore.m +++ b/MatrixSDK/Data/Store/MXMemoryStore/MXMemoryStore.m @@ -68,6 +68,12 @@ - (void)replaceEvent:(MXEvent *)event inRoom:(NSString *)roomId [roomStore replaceEvent:event]; } +- (BOOL)removeAllMessagesSentBefore:(uint64_t)limitTs inRoom:(nonnull NSString *)roomId +{ + MXMemoryRoomStore *roomStore = [self getOrCreateRoomStore:roomId]; + return [roomStore removeAllMessagesSentBefore:limitTs]; +} + - (BOOL)eventExistsWithEventId:(NSString *)eventId inRoom:(NSString *)roomId { return (nil != [self eventWithEventId:eventId inRoom:roomId]); diff --git a/MatrixSDK/Data/Store/MXNoStore/MXNoStore.m b/MatrixSDK/Data/Store/MXNoStore/MXNoStore.m index 5f73842a8d..6b279ed3ef 100644 --- a/MatrixSDK/Data/Store/MXNoStore/MXNoStore.m +++ b/MatrixSDK/Data/Store/MXNoStore/MXNoStore.m @@ -105,6 +105,17 @@ - (void)replaceEvent:(MXEvent *)event inRoom:(NSString *)roomId } } +- (BOOL)removeAllMessagesSentBefore:(uint64_t)limitTs inRoom:(nonnull NSString *)roomId +{ + // Only the last message is stored + MXEvent *lastMessage = lastMessages[roomId]; + if (!lastMessage.isState && lastMessage.originServerTs < limitTs) { + lastMessages[roomId] = nil; + return YES; + } + return NO; +} + - (BOOL)eventExistsWithEventId:(NSString *)eventId inRoom:(NSString *)roomId { // Events are not stored. So, we cannot find it. diff --git a/MatrixSDK/Data/Store/MXStore.h b/MatrixSDK/Data/Store/MXStore.h index 009304de4a..acf8cb1463 100644 --- a/MatrixSDK/Data/Store/MXStore.h +++ b/MatrixSDK/Data/Store/MXStore.h @@ -70,6 +70,18 @@ */ - (void)replaceEvent:(nonnull MXEvent*)event inRoom:(nonnull NSString*)roomId; +/** + Remove all the messages sent before a specific timestamp in a room. + The state events are not removed during this operation. We keep them in the timeline. + This operation doesn't change the pagination token, and the flag indicating that the SDK has reached the end of pagination. + + @param limitTs the timestamp from which the messages are kept. + @param roomId the id of the room. + + @return YES if at least one event has been removed. + */ +- (BOOL)removeAllMessagesSentBefore:(uint64_t)limitTs inRoom:(nonnull NSString *)roomId; + /** Returns a Boolean value that indicates whether an event is already stored.