mirror of
https://gitlab.opencode.de/bwi/bundesmessenger/clients/bundesmessenger-ios.git
synced 2026-04-19 16:13:42 +02:00
Merge MatrixKit develop with commit hash: b85b736313bec0592bd1cabc68035d97f5331137
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <MatrixSDK/MatrixSDK.h>
|
||||
|
||||
#import "MXKRoomMemberCellDataStoring.h"
|
||||
|
||||
/**
|
||||
`MXKRoomMemberCellData` modelised the data for a `MXKRoomMemberTableViewCell` cell.
|
||||
*/
|
||||
@interface MXKRoomMemberCellData : MXKCellData <MXKRoomMemberCellDataStoring>
|
||||
|
||||
/**
|
||||
The matrix session
|
||||
*/
|
||||
@property (nonatomic, readonly) MXSession *mxSession;
|
||||
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "MXKRoomMemberCellData.h"
|
||||
|
||||
#import "MXKRoomMemberListDataSource.h"
|
||||
|
||||
@interface MXKRoomMemberCellData ()
|
||||
{
|
||||
MXKRoomMemberListDataSource *roomMemberListDataSource;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation MXKRoomMemberCellData
|
||||
@synthesize roomMember;
|
||||
@synthesize memberDisplayName, powerLevel, isTyping;
|
||||
|
||||
- (instancetype)initWithRoomMember:(MXRoomMember*)member roomState:(MXRoomState*)roomState andRoomMemberListDataSource:(MXKRoomMemberListDataSource*)memberListDataSource
|
||||
{
|
||||
self = [self init];
|
||||
if (self)
|
||||
{
|
||||
roomMember = member;
|
||||
roomMemberListDataSource = memberListDataSource;
|
||||
|
||||
// Report member info from the current room state
|
||||
memberDisplayName = [roomState.members memberName:roomMember.userId];
|
||||
powerLevel = [roomState memberNormalizedPowerLevel:roomMember.userId];
|
||||
isTyping = NO;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)updateWithRoomState:(MXRoomState*)roomState
|
||||
{
|
||||
memberDisplayName = [roomState.members memberName:roomMember.userId];
|
||||
powerLevel = [roomState memberNormalizedPowerLevel:roomMember.userId];
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
roomMember = nil;
|
||||
roomMemberListDataSource = nil;
|
||||
}
|
||||
|
||||
- (MXSession*)mxSession
|
||||
{
|
||||
return roomMemberListDataSource.mxSession;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <MatrixSDK/MatrixSDK.h>
|
||||
|
||||
#import "MXKCellData.h"
|
||||
|
||||
@class MXKRoomMemberListDataSource;
|
||||
|
||||
/**
|
||||
`MXKRoomMemberCellDataStoring` defines a protocol a class must conform in order to store room member cell data
|
||||
managed by `MXKRoomMemberListDataSource`.
|
||||
*/
|
||||
@protocol MXKRoomMemberCellDataStoring <NSObject>
|
||||
|
||||
|
||||
#pragma mark - Data displayed by a room member cell
|
||||
|
||||
/**
|
||||
The member displayed by the cell.
|
||||
*/
|
||||
@property (nonatomic, readonly) MXRoomMember *roomMember;
|
||||
|
||||
/**
|
||||
The member display name
|
||||
*/
|
||||
@property (nonatomic, readonly) NSString *memberDisplayName;
|
||||
|
||||
/**
|
||||
The member power level
|
||||
*/
|
||||
@property (nonatomic, readonly) CGFloat powerLevel;
|
||||
|
||||
/**
|
||||
YES when member is typing in the room
|
||||
*/
|
||||
@property (nonatomic) BOOL isTyping;
|
||||
|
||||
#pragma mark - Public methods
|
||||
/**
|
||||
Create a new `MXKCellData` object for a new member cell.
|
||||
|
||||
@param memberListDataSource the `MXKRoomMemberListDataSource` object that will use this instance.
|
||||
@return the newly created instance.
|
||||
*/
|
||||
- (instancetype)initWithRoomMember:(MXRoomMember*)member roomState:(MXRoomState*)roomState andRoomMemberListDataSource:(MXKRoomMemberListDataSource*)memberListDataSource;
|
||||
|
||||
/**
|
||||
Update the member data with the provided roon state.
|
||||
*/
|
||||
- (void)updateWithRoomState:(MXRoomState*)roomState;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <MatrixSDK/MatrixSDK.h>
|
||||
|
||||
#import "MXKDataSource.h"
|
||||
#import "MXKRoomMemberCellData.h"
|
||||
|
||||
#import "MXKAppSettings.h"
|
||||
|
||||
/**
|
||||
Identifier to use for cells that display a room member.
|
||||
*/
|
||||
extern NSString *const kMXKRoomMemberCellIdentifier;
|
||||
|
||||
/**
|
||||
The data source for `MXKRoomMemberListViewController`.
|
||||
*/
|
||||
@interface MXKRoomMemberListDataSource : MXKDataSource <UITableViewDataSource> {
|
||||
|
||||
@protected
|
||||
|
||||
/**
|
||||
The data for the cells served by `MXKRoomMembersDataSource`.
|
||||
*/
|
||||
NSMutableArray *cellDataArray;
|
||||
|
||||
/**
|
||||
The filtered members: sub-list of `cellDataArray` defined by `searchWithPatterns:`.
|
||||
*/
|
||||
NSMutableArray *filteredCellDataArray;
|
||||
}
|
||||
|
||||
/**
|
||||
The id of the room managed by the data source.
|
||||
*/
|
||||
@property (nonatomic, readonly) NSString *roomId;
|
||||
|
||||
/**
|
||||
The settings used to sort/display room members.
|
||||
|
||||
By default the shared application settings are considered.
|
||||
*/
|
||||
@property (nonatomic) MXKAppSettings *settings;
|
||||
|
||||
|
||||
#pragma mark - Life cycle
|
||||
|
||||
/**
|
||||
Initialise the data source to serve members corresponding to the passed room.
|
||||
|
||||
@param roomId the id of the room to get members from.
|
||||
@param mxSession the Matrix session to get data from.
|
||||
@return the newly created instance.
|
||||
*/
|
||||
- (instancetype)initWithRoomId:(NSString*)roomId andMatrixSession:(MXSession*)mxSession;
|
||||
|
||||
/**
|
||||
Filter the current members list according to the provided patterns.
|
||||
When patterns are not empty, the search result is stored in `filteredCellDataArray`,
|
||||
this array provides then data for the cells served by `MXKRoomMembersDataSource`.
|
||||
|
||||
@param patternsList the list of patterns (`NSString` instances) to match with. Set nil to cancel search.
|
||||
*/
|
||||
- (void)searchWithPatterns:(NSArray*)patternsList;
|
||||
|
||||
/**
|
||||
Get the data for the cell at the given index.
|
||||
|
||||
@param index the index of the cell in the array
|
||||
@return the cell data
|
||||
*/
|
||||
- (id<MXKRoomMemberCellDataStoring>)cellDataAtIndex:(NSInteger)index;
|
||||
|
||||
/**
|
||||
Get height of the celle at the given index.
|
||||
|
||||
@param index the index of the cell in the array
|
||||
@return the cell height
|
||||
*/
|
||||
- (CGFloat)cellHeightAtIndex:(NSInteger)index;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,464 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "MXKRoomMemberListDataSource.h"
|
||||
|
||||
@import MatrixSDK.MXCallManager;
|
||||
|
||||
#import "MXKRoomMemberCellData.h"
|
||||
|
||||
|
||||
#pragma mark - Constant definitions
|
||||
NSString *const kMXKRoomMemberCellIdentifier = @"kMXKRoomMemberCellIdentifier";
|
||||
|
||||
|
||||
@interface MXKRoomMemberListDataSource ()
|
||||
{
|
||||
/**
|
||||
The room in which members are listed.
|
||||
*/
|
||||
MXRoom *mxRoom;
|
||||
|
||||
/**
|
||||
Cache for loaded room state.
|
||||
*/
|
||||
MXRoomState *mxRoomState;
|
||||
|
||||
/**
|
||||
The members events listener.
|
||||
*/
|
||||
id membersListener;
|
||||
|
||||
/**
|
||||
The typing notification listener in the room.
|
||||
*/
|
||||
id typingNotifListener;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation MXKRoomMemberListDataSource
|
||||
|
||||
- (instancetype)initWithRoomId:(NSString*)roomId andMatrixSession:(MXSession*)mxSession
|
||||
{
|
||||
self = [super initWithMatrixSession:mxSession];
|
||||
if (self)
|
||||
{
|
||||
_roomId = roomId;
|
||||
|
||||
cellDataArray = [NSMutableArray array];
|
||||
filteredCellDataArray = nil;
|
||||
|
||||
// Consider the shared app settings by default
|
||||
_settings = [MXKAppSettings standardAppSettings];
|
||||
|
||||
// Set default data class
|
||||
[self registerCellDataClass:MXKRoomMemberCellData.class forCellIdentifier:kMXKRoomMemberCellIdentifier];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)destroy
|
||||
{
|
||||
cellDataArray = nil;
|
||||
filteredCellDataArray = nil;
|
||||
|
||||
if (membersListener)
|
||||
{
|
||||
[self.mxSession removeListener:membersListener];
|
||||
membersListener = nil;
|
||||
}
|
||||
|
||||
if (typingNotifListener)
|
||||
{
|
||||
MXWeakify(self);
|
||||
[mxRoom liveTimeline:^(MXEventTimeline *liveTimeline) {
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
[liveTimeline removeListener:self->typingNotifListener];
|
||||
self->typingNotifListener = nil;
|
||||
}];
|
||||
}
|
||||
|
||||
[super destroy];
|
||||
}
|
||||
|
||||
- (void)didMXSessionStateChange
|
||||
{
|
||||
if (MXSessionStateStoreDataReady <= self.mxSession.state)
|
||||
{
|
||||
// Check whether the room is not already set
|
||||
if (!mxRoom)
|
||||
{
|
||||
mxRoom = [self.mxSession roomWithRoomId:_roomId];
|
||||
if (mxRoom)
|
||||
{
|
||||
MXWeakify(self);
|
||||
[mxRoom state:^(MXRoomState *roomState) {
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
self->mxRoomState = roomState;
|
||||
|
||||
[self loadData];
|
||||
|
||||
// Register on typing notif
|
||||
[self listenTypingNotifications];
|
||||
|
||||
// Register on members events
|
||||
[self listenMembersEvents];
|
||||
|
||||
// Update here data source state
|
||||
self->state = MXKDataSourceStateReady;
|
||||
|
||||
// Notify delegate
|
||||
if (self.delegate)
|
||||
{
|
||||
if ([self.delegate respondsToSelector:@selector(dataSource:didStateChange:)])
|
||||
{
|
||||
[self.delegate dataSource:self didStateChange:self->state];
|
||||
}
|
||||
[self.delegate dataSource:self didCellChange:nil];
|
||||
}
|
||||
}];
|
||||
}
|
||||
else
|
||||
{
|
||||
MXLogDebug(@"[MXKRoomMemberDataSource] The user does not know the room %@", _roomId);
|
||||
|
||||
// Update here data source state
|
||||
state = MXKDataSourceStateFailed;
|
||||
|
||||
// Notify delegate
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(dataSource:didStateChange:)])
|
||||
{
|
||||
[self.delegate dataSource:self didStateChange:state];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)searchWithPatterns:(NSArray*)patternsList
|
||||
{
|
||||
if (patternsList.count)
|
||||
{
|
||||
if (filteredCellDataArray)
|
||||
{
|
||||
[filteredCellDataArray removeAllObjects];
|
||||
}
|
||||
else
|
||||
{
|
||||
filteredCellDataArray = [NSMutableArray arrayWithCapacity:cellDataArray.count];
|
||||
}
|
||||
|
||||
for (id<MXKRoomMemberCellDataStoring> cellData in cellDataArray)
|
||||
{
|
||||
for (NSString* pattern in patternsList)
|
||||
{
|
||||
if ([[cellData memberDisplayName] rangeOfString:pattern options:NSCaseInsensitiveSearch].location != NSNotFound)
|
||||
{
|
||||
[filteredCellDataArray addObject:cellData];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
filteredCellDataArray = nil;
|
||||
}
|
||||
|
||||
if (self.delegate)
|
||||
{
|
||||
[self.delegate dataSource:self didCellChange:nil];
|
||||
}
|
||||
}
|
||||
|
||||
- (id<MXKRoomMemberCellDataStoring>)cellDataAtIndex:(NSInteger)index
|
||||
{
|
||||
if (filteredCellDataArray)
|
||||
{
|
||||
return filteredCellDataArray[index];
|
||||
}
|
||||
return cellDataArray[index];
|
||||
}
|
||||
|
||||
- (CGFloat)cellHeightAtIndex:(NSInteger)index
|
||||
{
|
||||
if (self.delegate)
|
||||
{
|
||||
id<MXKRoomMemberCellDataStoring> cellData = [self cellDataAtIndex:index];
|
||||
|
||||
Class<MXKCellRendering> class = [self.delegate cellViewClassForCellData:cellData];
|
||||
return [class heightForCellData:cellData withMaximumWidth:0];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#pragma mark - Members processing
|
||||
|
||||
- (void)loadData
|
||||
{
|
||||
NSArray* membersList = [mxRoomState.members membersWithoutConferenceUser];
|
||||
|
||||
if (!_settings.showLeftMembersInRoomMemberList)
|
||||
{
|
||||
NSMutableArray* filteredMembers = [[NSMutableArray alloc] init];
|
||||
|
||||
for (MXRoomMember* member in membersList)
|
||||
{
|
||||
// Filter out left users
|
||||
if (member.membership != MXMembershipLeave)
|
||||
{
|
||||
[filteredMembers addObject:member];
|
||||
}
|
||||
}
|
||||
|
||||
membersList = filteredMembers;
|
||||
}
|
||||
|
||||
[cellDataArray removeAllObjects];
|
||||
|
||||
// Retrieve the MXKCellData class to manage the data
|
||||
Class class = [self cellDataClassForCellIdentifier:kMXKRoomMemberCellIdentifier];
|
||||
NSAssert([class conformsToProtocol:@protocol(MXKRoomMemberCellDataStoring)], @"MXKRoomMemberListDataSource only manages MXKCellData that conforms to MXKRoomMemberCellDataStoring protocol");
|
||||
|
||||
for (MXRoomMember *member in membersList)
|
||||
{
|
||||
|
||||
id<MXKRoomMemberCellDataStoring> cellData = [[class alloc] initWithRoomMember:member roomState:mxRoomState andRoomMemberListDataSource:self];
|
||||
if (cellData)
|
||||
{
|
||||
[cellDataArray addObject:cellData];
|
||||
}
|
||||
}
|
||||
|
||||
[self sortMembers];
|
||||
}
|
||||
|
||||
- (void)sortMembers
|
||||
{
|
||||
NSArray *sortedMembers = [cellDataArray sortedArrayUsingComparator:^NSComparisonResult(id<MXKRoomMemberCellDataStoring> member1, id<MXKRoomMemberCellDataStoring> member2)
|
||||
{
|
||||
|
||||
// Move banned and left members at the end of the list
|
||||
if (member1.roomMember.membership == MXMembershipLeave || member1.roomMember.membership == MXMembershipBan)
|
||||
{
|
||||
if (member2.roomMember.membership != MXMembershipLeave && member2.roomMember.membership != MXMembershipBan)
|
||||
{
|
||||
return NSOrderedDescending;
|
||||
}
|
||||
}
|
||||
else if (member2.roomMember.membership == MXMembershipLeave || member2.roomMember.membership == MXMembershipBan)
|
||||
{
|
||||
return NSOrderedAscending;
|
||||
}
|
||||
|
||||
// Move invited members just before left and banned members
|
||||
if (member1.roomMember.membership == MXMembershipInvite)
|
||||
{
|
||||
if (member2.roomMember.membership != MXMembershipInvite)
|
||||
{
|
||||
return NSOrderedDescending;
|
||||
}
|
||||
}
|
||||
else if (member2.roomMember.membership == MXMembershipInvite)
|
||||
{
|
||||
return NSOrderedAscending;
|
||||
}
|
||||
|
||||
if (self->_settings.sortRoomMembersUsingLastSeenTime)
|
||||
{
|
||||
// Get the users that correspond to these members
|
||||
MXUser *user1 = [self.mxSession userWithUserId:member1.roomMember.userId];
|
||||
MXUser *user2 = [self.mxSession userWithUserId:member2.roomMember.userId];
|
||||
|
||||
// Move users who are not online or unavailable at the end (before invited users)
|
||||
if ((user1.presence == MXPresenceOnline) || (user1.presence == MXPresenceUnavailable))
|
||||
{
|
||||
if ((user2.presence != MXPresenceOnline) && (user2.presence != MXPresenceUnavailable))
|
||||
{
|
||||
return NSOrderedAscending;
|
||||
}
|
||||
}
|
||||
else if ((user2.presence == MXPresenceOnline) || (user2.presence == MXPresenceUnavailable))
|
||||
{
|
||||
return NSOrderedDescending;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Here both users are neither online nor unavailable (the lastActive ago is useless)
|
||||
// We will sort them according to their display, by keeping in front the offline users
|
||||
if (user1.presence == MXPresenceOffline)
|
||||
{
|
||||
if (user2.presence != MXPresenceOffline)
|
||||
{
|
||||
return NSOrderedAscending;
|
||||
}
|
||||
}
|
||||
else if (user2.presence == MXPresenceOffline)
|
||||
{
|
||||
return NSOrderedDescending;
|
||||
}
|
||||
return [[self->mxRoomState.members memberSortedName:member1.roomMember.userId] compare:[self->mxRoomState.members memberSortedName:member2.roomMember.userId] options:NSCaseInsensitiveSearch];
|
||||
}
|
||||
|
||||
// Consider user's lastActive ago value
|
||||
if (user1.lastActiveAgo < user2.lastActiveAgo)
|
||||
{
|
||||
return NSOrderedAscending;
|
||||
}
|
||||
else if (user1.lastActiveAgo == user2.lastActiveAgo)
|
||||
{
|
||||
return [[self->mxRoomState.members memberSortedName:member1.roomMember.userId] compare:[self->mxRoomState.members memberSortedName:member2.roomMember.userId] options:NSCaseInsensitiveSearch];
|
||||
}
|
||||
return NSOrderedDescending;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Move user without display name at the end (before invited users)
|
||||
if (member1.roomMember.displayname.length)
|
||||
{
|
||||
if (!member2.roomMember.displayname.length)
|
||||
{
|
||||
return NSOrderedAscending;
|
||||
}
|
||||
}
|
||||
else if (member2.roomMember.displayname.length)
|
||||
{
|
||||
return NSOrderedDescending;
|
||||
}
|
||||
|
||||
return [[self->mxRoomState.members memberSortedName:member1.roomMember.userId] compare:[self->mxRoomState.members memberSortedName:member2.roomMember.userId] options:NSCaseInsensitiveSearch];
|
||||
}
|
||||
}];
|
||||
|
||||
cellDataArray = [NSMutableArray arrayWithArray:sortedMembers];
|
||||
}
|
||||
|
||||
- (void)listenMembersEvents
|
||||
{
|
||||
// Remove the previous live listener
|
||||
if (membersListener)
|
||||
{
|
||||
[self.mxSession removeListener:membersListener];
|
||||
}
|
||||
|
||||
// Register a listener for events that concern room members
|
||||
NSArray *mxMembersEvents = @[
|
||||
kMXEventTypeStringRoomMember,
|
||||
kMXEventTypeStringRoomPowerLevels,
|
||||
kMXEventTypeStringPresence
|
||||
];
|
||||
membersListener = [self.mxSession listenToEventsOfTypes:mxMembersEvents onEvent:^(MXEvent *event, MXTimelineDirection direction, id customObject)
|
||||
{
|
||||
// consider only live event
|
||||
if (direction == MXTimelineDirectionForwards)
|
||||
{
|
||||
// Check the room Id (if any)
|
||||
if (event.roomId && [event.roomId isEqualToString:self->mxRoom.roomId] == NO)
|
||||
{
|
||||
// This event does not concern the current room members
|
||||
return;
|
||||
}
|
||||
|
||||
// refresh the whole members list. TODO GFO refresh only the updated members.
|
||||
[self loadData];
|
||||
|
||||
if (self.delegate)
|
||||
{
|
||||
[self.delegate dataSource:self didCellChange:nil];
|
||||
}
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)listenTypingNotifications
|
||||
{
|
||||
// Remove the previous live listener
|
||||
if (self->typingNotifListener)
|
||||
{
|
||||
[mxRoom removeListener:self->typingNotifListener];
|
||||
}
|
||||
|
||||
// Add typing notification listener
|
||||
self->typingNotifListener = [mxRoom listenToEventsOfTypes:@[kMXEventTypeStringTypingNotification] onEvent:^(MXEvent *event, MXTimelineDirection direction, MXRoomState *roomState) {
|
||||
// Handle only live events
|
||||
if (direction == MXTimelineDirectionForwards)
|
||||
{
|
||||
// Retrieve typing users list
|
||||
NSMutableArray *typingUsers = [NSMutableArray arrayWithArray:self->mxRoom.typingUsers];
|
||||
// Remove typing info for the current user
|
||||
NSUInteger index = [typingUsers indexOfObject:self.mxSession.myUser.userId];
|
||||
if (index != NSNotFound)
|
||||
{
|
||||
[typingUsers removeObjectAtIndex:index];
|
||||
}
|
||||
|
||||
for (id<MXKRoomMemberCellDataStoring> cellData in self->cellDataArray)
|
||||
{
|
||||
if ([typingUsers indexOfObject:cellData.roomMember.userId] == NSNotFound)
|
||||
{
|
||||
cellData.isTyping = NO;
|
||||
}
|
||||
else
|
||||
{
|
||||
cellData.isTyping = YES;
|
||||
}
|
||||
}
|
||||
|
||||
if (self.delegate)
|
||||
{
|
||||
[self.delegate dataSource:self didCellChange:nil];
|
||||
}
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
#pragma mark - UITableViewDataSource
|
||||
|
||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
|
||||
{
|
||||
if (filteredCellDataArray)
|
||||
{
|
||||
return filteredCellDataArray.count;
|
||||
}
|
||||
return cellDataArray.count;
|
||||
}
|
||||
|
||||
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
id<MXKRoomMemberCellDataStoring> roomData = [self cellDataAtIndex:indexPath.row];
|
||||
|
||||
if (roomData && self.delegate)
|
||||
{
|
||||
NSString *identifier = [self.delegate cellReuseIdentifierForCellData:roomData];
|
||||
if (identifier)
|
||||
{
|
||||
UITableViewCell<MXKCellRendering> *cell = [tableView dequeueReusableCellWithIdentifier:identifier forIndexPath:indexPath];
|
||||
|
||||
// Make the bubble display the data
|
||||
[cell render:roomData];
|
||||
|
||||
return cell;
|
||||
}
|
||||
}
|
||||
|
||||
// Return a fake cell to prevent app from crashing.
|
||||
return [[UITableViewCell alloc] init];
|
||||
}
|
||||
|
||||
@end
|
||||
Reference in New Issue
Block a user