Skip to content
This repository has been archived by the owner on Dec 12, 2022. It is now read-only.

Commit

Permalink
Ensure both session state and event existence when loading room data …
Browse files Browse the repository at this point in the history
  • Loading branch information
ismailgulek committed Jun 2, 2020
1 parent 65a0975 commit feafeb5
Showing 1 changed file with 54 additions and 17 deletions.
71 changes: 54 additions & 17 deletions MatrixKit/Models/Room/MXKRoomDataSource.m
Original file line number Diff line number Diff line change
Expand Up @@ -167,41 +167,78 @@ @implementation MXKRoomDataSource
+ (void)loadRoomDataSourceWithRoomId:(NSString*)roomId andMatrixSession:(MXSession*)mxSession onComplete:(void (^)(id roomDataSource))onComplete
{
MXKRoomDataSource *roomDataSource = [[self alloc] initWithRoomId:roomId andMatrixSession:mxSession];
[self ensureSessionStateForDataSource:roomDataSource initialEventId:nil andMatrixSession:mxSession onComplete:onComplete];
}

+ (void)loadRoomDataSourceWithRoomId:(NSString*)roomId initialEventId:(NSString*)initialEventId andMatrixSession:(MXSession*)mxSession onComplete:(void (^)(id roomDataSource))onComplete
{
MXKRoomDataSource *roomDataSource = [[self alloc] initWithRoomId:roomId initialEventId:initialEventId andMatrixSession:mxSession];
[self ensureSessionStateForDataSource:roomDataSource initialEventId:initialEventId andMatrixSession:mxSession onComplete:onComplete];
}

+ (void)loadRoomDataSourceWithPeekingRoom:(MXPeekingRoom*)peekingRoom andInitialEventId:(NSString*)initialEventId onComplete:(void (^)(id roomDataSource))onComplete
{
MXKRoomDataSource *roomDataSource = [[self alloc] initWithPeekingRoom:peekingRoom andInitialEventId:initialEventId];
[self finalizeRoomDataSource:roomDataSource onComplete:onComplete];
}

/// Ensure session state to be store data ready for the roomDataSource.
+ (void)ensureSessionStateForDataSource:(MXKRoomDataSource*)roomDataSource initialEventId:(NSString*)initialEventId andMatrixSession:(MXSession*)mxSession onComplete:(void (^)(id roomDataSource))onComplete
{
// if store is not ready, roomDataSource.room will be nil. So onComplete block will never be called.
// In order to successfully fetch the room, we should wait for store to be ready.
if (mxSession.state >= MXSessionStateStoreDataReady)
{
if (!roomDataSource.room)
{
[self finalizeRoomDataSource:roomDataSource onComplete:onComplete];
}
[self ensureInitialEventExistenceForDataSource:roomDataSource initialEventId:initialEventId andMatrixSession:mxSession onComplete:onComplete];
}
else
{
// wait for session state to be store data ready
id sessionStateObserver = nil;
sessionStateObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMXSessionStateDidChangeNotification object:mxSession queue:nil usingBlock:^(NSNotification * _Nonnull note) {
if (mxSession.state >= MXSessionStateStoreDataReady)
{
[[NSNotificationCenter defaultCenter] removeObserver:sessionStateObserver];
if (!roomDataSource.room)
{
[self finalizeRoomDataSource:roomDataSource onComplete:onComplete];
}
[self ensureInitialEventExistenceForDataSource:roomDataSource initialEventId:initialEventId andMatrixSession:mxSession onComplete:onComplete];
}
}];
}
}

+ (void)loadRoomDataSourceWithRoomId:(NSString*)roomId initialEventId:(NSString*)initialEventId andMatrixSession:(MXSession*)mxSession onComplete:(void (^)(id roomDataSource))onComplete
/// Ensure initial event existence for the roomDataSource.
+ (void)ensureInitialEventExistenceForDataSource:(MXKRoomDataSource*)roomDataSource initialEventId:(NSString*)initialEventId andMatrixSession:(MXSession*)mxSession onComplete:(void (^)(id roomDataSource))onComplete
{
MXKRoomDataSource *roomDataSource = [[self alloc] initWithRoomId:roomId initialEventId:initialEventId andMatrixSession:mxSession];
[self finalizeRoomDataSource:roomDataSource onComplete:onComplete];
}

+ (void)loadRoomDataSourceWithPeekingRoom:(MXPeekingRoom*)peekingRoom andInitialEventId:(NSString*)initialEventId onComplete:(void (^)(id roomDataSource))onComplete
{
MXKRoomDataSource *roomDataSource = [[self alloc] initWithPeekingRoom:peekingRoom andInitialEventId:initialEventId];
[self finalizeRoomDataSource:roomDataSource onComplete:onComplete];
if (roomDataSource.room)
{
// already finalized
return;
}

if (initialEventId == nil)
{
// if an initialEventId not provided, finalize
[self finalizeRoomDataSource:roomDataSource onComplete:onComplete];
return;
}

// ensure event with id 'initialEventId' exists in the session store
if ([mxSession.store eventExistsWithEventId:initialEventId inRoom:roomDataSource.roomId])
{
[self finalizeRoomDataSource:roomDataSource onComplete:onComplete];
}
else
{
// wait for the specific event to be existent
// use kMXSessionDidSyncNotification here instead of MXSessionStateRunning, because session does not send this state update if it's already in this state
id syncObserver = nil;
syncObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMXSessionDidSyncNotification object:mxSession queue:nil usingBlock:^(NSNotification * _Nonnull note) {
if ([mxSession.store eventExistsWithEventId:initialEventId inRoom:roomDataSource.roomId])
{
[[NSNotificationCenter defaultCenter] removeObserver:syncObserver];
[self finalizeRoomDataSource:roomDataSource onComplete:onComplete];
}
}];
}
}

+ (void)finalizeRoomDataSource:(MXKRoomDataSource*)roomDataSource onComplete:(void (^)(id roomDataSource))onComplete
Expand Down

0 comments on commit feafeb5

Please sign in to comment.