2015-11-20 17:14:15 +00:00
/ *
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 "RecentsDataSource.h"
# import "EventFormatter.h"
2015-12-04 16:45:56 +00:00
# import "VectorDesignValues.h"
2015-12-09 16:01:29 +00:00
# import "InviteRecentTableViewCell.h"
2015-12-18 09:59:45 +00:00
# import "DirectoryRecentTableViewCell.h"
# import "PublicRoomsDirectoryDataSource.h"
2015-12-09 16:01:29 +00:00
2015-12-21 09:35:48 +00:00
# import "MXRoom+Vector.h"
# import "RecentCellData.h"
2015-12-02 16:18:55 +00:00
@ interface RecentsDataSource ( )
{
2015-12-09 15:09:46 +00:00
NSMutableArray * invitesCellDataArray ;
2015-12-04 08:02:02 +00:00
NSMutableArray * favoriteCellDataArray ;
NSMutableArray * conversationCellDataArray ;
NSMutableArray * lowPriorityCellDataArray ;
2015-12-18 09:59:45 +00:00
2015-12-16 15:29:34 +00:00
NSInteger directorySection ;
2015-12-09 15:09:46 +00:00
NSInteger invitesSection ;
2015-12-04 08:02:02 +00:00
NSInteger favoritesSection ;
NSInteger conversationSection ;
NSInteger lowPrioritySection ;
2015-12-02 16:18:55 +00:00
NSInteger sectionsCount ;
NSMutableDictionary < NSString * , id > * roomTagsListenerByUserId ;
}
@ end
2015-11-20 17:14:15 +00:00
@ implementation RecentsDataSource
2015-12-10 08:00:57 +00:00
@ synthesize onRoomInvitationReject , onRoomInvitationAccept ;
2015-12-16 07:59:40 +00:00
@ synthesize hiddenCellIndexPath , droppingCellIndexPath , droppingCellBackGroundView ;
2015-11-20 17:14:15 +00:00
- ( instancetype ) init
{
self = [ super init ] ;
if ( self )
{
// Replace event formatter
self . eventFormatter = [ [ EventFormatter alloc ] initWithMatrixSession : self . mxSession ] ;
2016-01-20 12:06:13 +00:00
self . eventFormatter . isForSubtitle = YES ;
2015-12-02 16:18:55 +00:00
2015-12-04 08:02:02 +00:00
favoriteCellDataArray = [ [ NSMutableArray alloc ] init ] ;
conversationCellDataArray = [ [ NSMutableArray alloc ] init ] ;
lowPriorityCellDataArray = [ [ NSMutableArray alloc ] init ] ;
2015-12-16 15:29:34 +00:00
directorySection = -1 ;
2015-12-09 15:09:46 +00:00
invitesSection = -1 ;
2015-12-04 08:02:02 +00:00
favoritesSection = -1 ;
conversationSection = -1 ;
lowPrioritySection = -1 ;
sectionsCount = 0 ;
2015-12-02 16:18:55 +00:00
roomTagsListenerByUserId = [ [ NSMutableDictionary alloc ] init ] ;
2015-12-21 09:35:48 +00:00
// Set default data and view classes
[ self registerCellDataClass : RecentCellData . class forCellIdentifier : kMXKRecentCellIdentifier ] ;
2015-11-20 17:14:15 +00:00
}
return self ;
}
2015-12-18 09:59:45 +00:00
- ( void ) addMatrixSession : ( MXSession * ) mxSession
{
[ super addMatrixSession : mxSession ] ;
// Initialise the public room directory data source
// Note that it is single matrix session only for now
2015-12-18 16:17:03 +00:00
if ( ! _publicRoomsDirectoryDataSource )
2015-12-18 09:59:45 +00:00
{
2015-12-18 16:17:03 +00:00
_publicRoomsDirectoryDataSource = [ [ PublicRoomsDirectoryDataSource alloc ] initWithMatrixSession : mxSession ] ;
_publicRoomsDirectoryDataSource . delegate = self ;
2015-12-18 09:59:45 +00:00
}
}
2015-12-02 16:18:55 +00:00
- ( void ) removeMatrixSession : ( MXSession * ) matrixSession
{
[ super removeMatrixSession : matrixSession ] ;
// sanity check
if ( matrixSession && matrixSession . myUser && matrixSession . myUser . userId )
{
id roomTagListener = [ roomTagsListenerByUserId objectForKey : matrixSession . myUser . userId ] ;
if ( roomTagListener )
{
[ self . mxSession removeListener : roomTagListener ] ;
[ roomTagsListenerByUserId removeObjectForKey : matrixSession . myUser . userId ] ;
}
2015-12-18 09:59:45 +00:00
2015-12-18 16:17:03 +00:00
if ( _publicRoomsDirectoryDataSource . mxSession = = matrixSession )
2015-12-18 09:59:45 +00:00
{
2015-12-18 16:17:03 +00:00
[ _publicRoomsDirectoryDataSource destroy ] ;
_publicRoomsDirectoryDataSource = nil ;
2015-12-18 09:59:45 +00:00
}
2015-12-02 16:18:55 +00:00
}
}
- ( void ) dataSource : ( MXKDataSource * ) dataSource didStateChange : ( MXKDataSourceState ) aState
{
2015-12-18 16:17:03 +00:00
if ( dataSource = = _publicRoomsDirectoryDataSource )
2015-12-18 09:59:45 +00:00
{
2015-12-18 11:03:43 +00:00
[ self refreshRoomsSectionsAndReload ] ;
2015-12-18 09:59:45 +00:00
}
else
{
[ super dataSource : dataSource didStateChange : aState ] ;
if ( ( aState = = MXKDataSourceStateReady ) && self . mxSession && self . mxSession . myUser && self . mxSession . myUser . userId )
{
// Register the room tags updates to refresh the favorites order
id roomTagsListener = [ self . mxSession listenToEventsOfTypes : @ [ kMXEventTypeStringRoomTag ]
onEvent : ^ ( MXEvent * event , MXEventDirection direction , id customObject ) {
// Consider only live event
if ( direction = = MXEventDirectionForwards )
{
dispatch_async ( dispatch_get _main _queue ( ) , ^ {
[ self refreshRoomsSectionsAndReload ] ;
} ) ;
}
} ] ;
[ roomTagsListenerByUserId setObject : roomTagsListener forKey : self . mxSession . myUser . userId ] ;
}
2015-12-02 16:18:55 +00:00
}
2015-12-10 09:16:22 +00:00
}
2015-12-21 09:35:48 +00:00
- ( BOOL ) isRoomNotifiedAtIndexPath : ( NSIndexPath * ) indexPath
{
MXRoom * room = [ self getRoomAtIndexPath : indexPath ] ;
if ( room )
{
return ! room . areRoomNotificationsMuted ;
}
return YES ;
}
- ( void ) muteRoomNotifications : ( BOOL ) mute atIndexPath : ( NSIndexPath * ) indexPath
{
MXRoom * room = [ self getRoomAtIndexPath : indexPath ] ;
// sanity check
if ( room )
{
[ room toggleRoomNotifications : mute ] ;
}
}
2015-12-14 07:29:01 +00:00
2015-12-14 10:08:57 +00:00
- ( void ) refreshRoomsSectionsAndReload
2015-12-10 09:16:22 +00:00
{
2015-12-16 07:59:40 +00:00
// Refresh is disabled during drag & drop animation "
if ( ! self . droppingCellIndexPath )
2015-12-10 09:16:22 +00:00
{
2015-12-14 07:29:01 +00:00
[ self refreshRoomsSections ] ;
// And inform the delegate about the update
2015-12-10 09:16:22 +00:00
[ self . delegate dataSource : self didCellChange : nil ] ;
}
2015-12-02 16:18:55 +00:00
}
2015-12-10 09:16:22 +00:00
- ( void ) didMXSessionInviteRoomUpdate : ( NSNotification * ) notif
{
MXSession * mxSession = notif . object ;
if ( mxSession = = self . mxSession )
{
2015-12-14 10:08:57 +00:00
[ self refreshRoomsSectionsAndReload ] ;
2015-12-10 09:16:22 +00:00
}
2015-12-02 16:18:55 +00:00
}
# pragma mark - UITableViewDataSource
/ * *
Return the header height from the section .
* /
- ( CGFloat ) heightForHeaderInSection : ( NSInteger ) section
{
2015-12-16 15:29:34 +00:00
if ( ( section = = directorySection ) || ( section = = invitesSection ) || ( section = = favoritesSection ) || ( section = = conversationSection ) || ( section = = lowPrioritySection ) )
2015-12-02 16:18:55 +00:00
{
2015-12-04 16:45:56 +00:00
return 30.0 f ;
2015-12-02 16:18:55 +00:00
}
return 0.0 f ;
}
- ( NSInteger ) numberOfSectionsInTableView : ( UITableView * ) tableView
{
// Check whether all data sources are ready before rendering recents
if ( self . state = = MXKDataSourceStateReady )
{
// Only one section is handled by this data source .
return sectionsCount ;
}
return 0 ;
}
2015-12-14 09:47:10 +00:00
- ( BOOL ) isMovingCellSection : ( NSInteger ) section
{
2015-12-16 07:59:40 +00:00
return self . droppingCellIndexPath && ( self . droppingCellIndexPath . section = = section ) ;
2015-12-14 09:47:10 +00:00
}
- ( BOOL ) isHiddenCellSection : ( NSInteger ) section
{
return self . hiddenCellIndexPath && ( self . hiddenCellIndexPath . section = = section ) ;
}
2015-12-02 16:18:55 +00:00
- ( NSInteger ) tableView : ( UITableView * ) tableView numberOfRowsInSection : ( NSInteger ) section
{
NSUInteger count = 0 ;
2015-12-16 15:29:34 +00:00
if ( section = = directorySection )
{
2015-12-18 09:59:45 +00:00
count = 1 ;
2015-12-16 15:29:34 +00:00
}
else if ( section = = favoritesSection )
2015-12-02 16:18:55 +00:00
{
2015-12-04 08:02:02 +00:00
count = favoriteCellDataArray . count ;
2015-12-02 16:18:55 +00:00
}
2015-12-04 08:02:02 +00:00
else if ( section = = conversationSection )
2015-12-02 16:18:55 +00:00
{
2015-12-04 08:02:02 +00:00
count = conversationCellDataArray . count ;
2015-12-02 16:18:55 +00:00
}
2015-12-04 08:02:02 +00:00
else if ( section = = lowPrioritySection )
2015-12-02 16:18:55 +00:00
{
2015-12-04 08:02:02 +00:00
count = lowPriorityCellDataArray . count ;
2015-12-02 16:18:55 +00:00
}
2015-12-09 15:09:46 +00:00
else if ( section = = invitesSection )
{
count = invitesCellDataArray . count ;
}
2015-12-14 09:47:10 +00:00
if ( [ self isMovingCellSection : section ] )
2015-12-11 13:59:55 +00:00
{
count + + ;
}
2015-12-14 09:47:10 +00:00
if ( [ self isHiddenCellSection : section ] )
{
count - - ;
}
2015-12-02 16:18:55 +00:00
return count ;
}
- ( UIView * ) viewForHeaderInSection : ( NSInteger ) section withFrame : ( CGRect ) frame
{
// add multi accounts section management
2015-12-16 15:29:34 +00:00
if ( ( section = = directorySection ) || ( section = = favoritesSection ) || ( section = = conversationSection ) || ( section = = lowPrioritySection ) || ( section = = invitesSection ) )
2015-12-02 16:18:55 +00:00
{
UILabel * label = [ [ UILabel alloc ] initWithFrame : frame ] ;
NSString * text = @ "" ;
2015-12-16 15:29:34 +00:00
if ( section = = directorySection )
{
text = NSLocalizedStringFromTable ( @ "room_recents_directory" , @ "Vector" , nil ) ;
}
else if ( section = = favoritesSection )
2015-12-02 16:18:55 +00:00
{
text = NSLocalizedStringFromTable ( @ "room_recents_favourites" , @ "Vector" , nil ) ;
}
2015-12-04 08:02:02 +00:00
else if ( section = = conversationSection )
2015-12-02 16:18:55 +00:00
{
text = NSLocalizedStringFromTable ( @ "room_recents_conversations" , @ "Vector" , nil ) ;
}
2015-12-04 08:02:02 +00:00
else if ( section = = lowPrioritySection )
2015-12-02 16:18:55 +00:00
{
text = NSLocalizedStringFromTable ( @ "room_recents_low_priority" , @ "Vector" , nil ) ;
}
2015-12-09 15:09:46 +00:00
else if ( section = = invitesSection )
{
text = NSLocalizedStringFromTable ( @ "room_recents_invites" , @ "Vector" , nil ) ;
}
2015-12-02 16:18:55 +00:00
label . text = [ NSString stringWithFormat : @ " %@" , text ] ;
2015-12-04 16:45:56 +00:00
label . font = [ UIFont boldSystemFontOfSize : 15.0 ] ;
label . backgroundColor = VECTOR_LIGHT _GRAY _COLOR ;
2015-12-02 16:18:55 +00:00
return label ;
}
return [ super viewForHeaderInSection : section withFrame : frame ] ;
}
2015-12-11 13:59:55 +00:00
- ( UITableViewCell * ) tableView : ( UITableView * ) tableView cellForRowAtIndexPath : ( NSIndexPath * ) anIndexPath
2015-12-09 16:01:29 +00:00
{
2015-12-11 13:59:55 +00:00
NSIndexPath * indexPath = anIndexPath ;
2015-12-18 09:59:45 +00:00
// For the cell showing the public rooms directory search result ,
// skip the MatrixKit mechanism and return directly the UITableViewCell
if ( indexPath . section = = directorySection )
{
DirectoryRecentTableViewCell * directoryCell = [ tableView dequeueReusableCellWithIdentifier : DirectoryRecentTableViewCell . defaultReuseIdentifier ] ;
if ( ! directoryCell )
{
directoryCell = [ [ DirectoryRecentTableViewCell alloc ] initWithStyle : UITableViewCellStyleDefault reuseIdentifier : [ DirectoryRecentTableViewCell defaultReuseIdentifier ] ] ;
}
2015-12-18 16:17:03 +00:00
[ directoryCell render : _publicRoomsDirectoryDataSource ] ;
2015-12-18 09:59:45 +00:00
return directoryCell ;
}
2015-12-16 07:59:40 +00:00
if ( self . droppingCellIndexPath && ( self . droppingCellIndexPath . section = = indexPath . section ) )
2015-12-11 13:59:55 +00:00
{
2015-12-16 07:59:40 +00:00
if ( [ anIndexPath isEqual : self . droppingCellIndexPath ] )
2015-12-11 13:59:55 +00:00
{
static NSString * cellIdentifier = @ "VectorRecentsMovingCell" ;
UITableViewCell * cell = [ [ UITableViewCell alloc ] initWithStyle : UITableViewCellStyleDefault reuseIdentifier : @ "VectorRecentsMovingCell" ] ;
2015-12-16 07:59:40 +00:00
// add an imageview of the cell .
// The image is a shot of the genuine cell .
// Thus , this cell has the same look as the genuine cell withourt computing it .
2015-12-11 13:59:55 +00:00
UIImageView * imageView = [ cell viewWithTag : [ cellIdentifier hash ] ] ;
2015-12-16 07:59:40 +00:00
if ( ! imageView || ( imageView ! = self . droppingCellBackGroundView ) )
2015-12-11 13:59:55 +00:00
{
if ( imageView )
{
[ imageView removeFromSuperview ] ;
}
2015-12-16 07:59:40 +00:00
self . droppingCellBackGroundView . tag = [ cellIdentifier hash ] ;
[ cell . contentView addSubview : self . droppingCellBackGroundView ] ;
2015-12-11 13:59:55 +00:00
}
2015-12-16 07:59:40 +00:00
self . droppingCellBackGroundView . frame = self . droppingCellBackGroundView . frame ;
2015-12-14 10:14:58 +00:00
cell . contentView . backgroundColor = [ UIColor clearColor ] ;
cell . backgroundColor = [ UIColor clearColor ] ;
2015-12-11 13:59:55 +00:00
return cell ;
}
2015-12-16 07:59:40 +00:00
if ( anIndexPath . row > self . droppingCellIndexPath . row )
2015-12-11 13:59:55 +00:00
{
indexPath = [ NSIndexPath indexPathForRow : anIndexPath . row -1 inSection : anIndexPath . section ] ;
}
}
2015-12-14 09:47:10 +00:00
if ( self . hiddenCellIndexPath && [ anIndexPath isEqual : self . hiddenCellIndexPath ] )
{
indexPath = [ NSIndexPath indexPathForRow : anIndexPath . row -1 inSection : anIndexPath . section ] ;
}
2015-12-11 13:59:55 +00:00
UITableViewCell * cell = [ super tableView : tableView cellForRowAtIndexPath : indexPath ] ;
2015-12-10 16:08:09 +00:00
// on invite cell , add listeners on accept / reject buttons
if ( cell && [ cell isKindOfClass : [ InviteRecentTableViewCell class ] ] )
2015-12-09 16:01:29 +00:00
{
2015-12-10 16:08:09 +00:00
id < MXKRecentCellDataStoring > roomData = [ self cellDataAtIndexPath : indexPath ] ;
InviteRecentTableViewCell * inviteRecentTableViewCell = ( InviteRecentTableViewCell * ) cell ;
inviteRecentTableViewCell . onRejectClick = ^ ( ) {
if ( self . onRoomInvitationReject )
2015-12-09 16:01:29 +00:00
{
2015-12-10 16:08:09 +00:00
self . onRoomInvitationReject ( roomData . roomDataSource . room ) ;
2015-12-09 16:01:29 +00:00
}
2015-12-10 16:08:09 +00:00
} ;
inviteRecentTableViewCell . onJoinClick = ^ ( ) {
if ( self . onRoomInvitationAccept )
2015-12-10 08:00:57 +00:00
{
2015-12-10 16:08:09 +00:00
self . onRoomInvitationAccept ( roomData . roomDataSource . room ) ;
2015-12-10 08:00:57 +00:00
}
2015-12-10 16:08:09 +00:00
} ;
2015-12-09 16:01:29 +00:00
}
2015-12-10 16:08:09 +00:00
return cell ;
2015-12-09 16:01:29 +00:00
}
2015-12-11 13:59:55 +00:00
- ( id < MXKRecentCellDataStoring > ) cellDataAtIndexPath : ( NSIndexPath * ) anIndexPath
2015-12-02 16:18:55 +00:00
{
id < MXKRecentCellDataStoring > cellData = nil ;
2015-12-11 13:59:55 +00:00
NSInteger row = anIndexPath . row ;
NSInteger section = anIndexPath . section ;
2015-12-16 07:59:40 +00:00
if ( self . droppingCellIndexPath && ( self . droppingCellIndexPath . section = = section ) )
2015-12-11 13:59:55 +00:00
{
2015-12-16 07:59:40 +00:00
if ( anIndexPath . row > self . droppingCellIndexPath . row )
2015-12-11 13:59:55 +00:00
{
row = anIndexPath . row - 1 ;
}
}
2015-12-02 16:18:55 +00:00
2015-12-18 09:59:45 +00:00
if ( section = = favoritesSection )
2015-12-02 16:18:55 +00:00
{
2015-12-11 13:59:55 +00:00
cellData = [ favoriteCellDataArray objectAtIndex : row ] ;
2015-12-02 16:18:55 +00:00
}
2015-12-11 13:59:55 +00:00
else if ( section = = conversationSection )
2015-12-02 16:18:55 +00:00
{
2015-12-11 13:59:55 +00:00
cellData = [ conversationCellDataArray objectAtIndex : row ] ;
2015-12-02 16:18:55 +00:00
}
2015-12-11 13:59:55 +00:00
else if ( section = = lowPrioritySection )
2015-12-02 16:18:55 +00:00
{
2015-12-11 13:59:55 +00:00
cellData = [ lowPriorityCellDataArray objectAtIndex : row ] ;
2015-12-02 16:18:55 +00:00
}
2015-12-11 13:59:55 +00:00
else if ( section = = invitesSection )
2015-12-09 15:09:46 +00:00
{
2015-12-11 13:59:55 +00:00
cellData = [ invitesCellDataArray objectAtIndex : row ] ;
2015-12-09 15:09:46 +00:00
}
2015-12-02 16:18:55 +00:00
return cellData ;
}
- ( CGFloat ) cellHeightAtIndexPath : ( NSIndexPath * ) indexPath
{
2015-12-18 09:59:45 +00:00
// For the cell showing the public rooms directory search result ,
// skip the MatrixKit mechanism and return directly the cell height
if ( indexPath . section = = directorySection )
{
return DirectoryRecentTableViewCell . cellHeight ;
}
2015-12-16 07:59:40 +00:00
if ( self . droppingCellIndexPath && [ indexPath isEqual : self . droppingCellIndexPath ] )
2015-12-11 13:59:55 +00:00
{
2015-12-16 07:59:40 +00:00
return self . droppingCellBackGroundView . frame . size . height ;
2015-12-11 13:59:55 +00:00
}
2015-12-07 10:50:13 +00:00
// Override this method here to use our own cellDataAtIndexPath
2015-12-02 16:18:55 +00:00
id < MXKRecentCellDataStoring > cellData = [ self cellDataAtIndexPath : indexPath ] ;
2015-12-07 10:50:13 +00:00
if ( cellData && self . delegate )
2015-12-02 16:18:55 +00:00
{
2015-12-07 10:50:13 +00:00
Class < MXKCellRendering > class = [ self . delegate cellViewClassForCellData : cellData ] ;
2015-12-09 15:09:46 +00:00
2015-12-02 16:18:55 +00:00
return [ class heightForCellData : cellData withMaximumWidth : 0 ] ;
}
return 0 ;
}
2015-12-10 12:41:03 +00:00
- ( NSInteger ) cellIndexPosWithRoomId : ( NSString * ) roomId andMatrixSession : ( MXSession * ) matrixSession within : ( NSMutableArray * ) cellDataArray
{
if ( roomId && matrixSession && cellDataArray . count )
{
for ( int index = 0 ; index < cellDataArray . count ; index + + )
{
id < MXKRecentCellDataStoring > cellDataStoring = [ cellDataArray objectAtIndex : index ] ;
if ( [ roomId isEqualToString : cellDataStoring . roomDataSource . roomId ] && ( matrixSession = = cellDataStoring . roomDataSource . mxSession ) )
{
return index ;
}
}
}
return NSNotFound ;
}
- ( NSIndexPath * ) cellIndexPathWithRoomId : ( NSString * ) roomId andMatrixSession : ( MXSession * ) matrixSession
{
NSIndexPath * indexPath = nil ;
NSInteger index = NSNotFound ;
if ( ! indexPath && ( invitesSection >= 0 ) )
{
index = [ self cellIndexPosWithRoomId : roomId andMatrixSession : matrixSession within : invitesCellDataArray ] ;
if ( index ! = NSNotFound )
{
indexPath = [ NSIndexPath indexPathForRow : index inSection : invitesSection ] ;
}
}
if ( ! indexPath && ( favoritesSection >= 0 ) )
{
index = [ self cellIndexPosWithRoomId : roomId andMatrixSession : matrixSession within : favoriteCellDataArray ] ;
if ( index ! = NSNotFound )
{
indexPath = [ NSIndexPath indexPathForRow : index inSection : favoritesSection ] ;
}
}
if ( ! indexPath && ( conversationSection >= 0 ) )
{
index = [ self cellIndexPosWithRoomId : roomId andMatrixSession : matrixSession within : conversationCellDataArray ] ;
if ( index ! = NSNotFound )
{
indexPath = [ NSIndexPath indexPathForRow : index inSection : conversationSection ] ;
}
}
if ( ! indexPath && ( lowPrioritySection >= 0 ) )
{
index = [ self cellIndexPosWithRoomId : roomId andMatrixSession : matrixSession within : lowPriorityCellDataArray ] ;
if ( index ! = NSNotFound )
{
indexPath = [ NSIndexPath indexPathForRow : index inSection : lowPrioritySection ] ;
}
}
if ( ! indexPath )
{
indexPath = [ super cellIndexPathWithRoomId : roomId andMatrixSession : matrixSession ] ;
}
return indexPath ;
}
2015-12-02 16:18:55 +00:00
# pragma mark - MXKDataSourceDelegate
2015-12-02 17:10:22 +00:00
// create an array filled with NSNull and with the same size as sourceArray
2015-12-04 08:02:02 +00:00
- ( NSMutableArray * ) createEmptyArray : ( NSUInteger ) count
2015-12-02 17:10:22 +00:00
{
NSMutableArray * array = [ [ NSMutableArray alloc ] init ] ;
2015-12-04 08:02:02 +00:00
for ( NSUInteger i = 0 ; i < count ; i + + )
2015-12-02 17:10:22 +00:00
{
2015-12-04 08:02:02 +00:00
[ array addObject : [ NSNull null ] ] ;
2015-12-02 17:10:22 +00:00
}
return array ;
}
2015-12-02 16:38:10 +00:00
- ( void ) refreshRoomsSections
2015-12-02 16:18:55 +00:00
{
2015-12-04 08:02:02 +00:00
// FIXME manage multi accounts
2015-12-18 11:03:43 +00:00
NSUInteger sectionIndex = 0 ;
2015-12-04 08:02:02 +00:00
favoriteCellDataArray = [ [ NSMutableArray alloc ] init ] ;
conversationCellDataArray = [ [ NSMutableArray alloc ] init ] ;
lowPriorityCellDataArray = [ [ NSMutableArray alloc ] init ] ;
2015-12-03 08:37:45 +00:00
2015-12-16 15:29:34 +00:00
directorySection = favoritesSection = conversationSection = lowPrioritySection = invitesSection = -1 ;
2015-12-02 16:18:55 +00:00
sectionsCount = 0 ;
2015-12-02 17:10:22 +00:00
2015-12-18 13:07:26 +00:00
// Manage the public room search results cell outside the recents .
2015-12-18 11:03:43 +00:00
// Show the cell showing the public rooms directory search result
2015-12-18 13:07:26 +00:00
// once a search is active
2015-12-21 14:29:57 +00:00
if ( _publicRoomsDirectoryDataSource . searchPatternsList )
2015-12-18 11:03:43 +00:00
{
directorySection = sectionIndex ;
sectionIndex + + ;
}
2015-12-02 16:18:55 +00:00
if ( displayedRecentsDataSourceArray . count > 0 )
{
MXKSessionRecentsDataSource * recentsDataSource = [ displayedRecentsDataSourceArray objectAtIndex : 0 ] ;
2015-12-02 17:10:22 +00:00
MXSession * session = recentsDataSource . mxSession ;
2015-12-09 15:09:46 +00:00
NSArray * sortedInvitesRooms = [ session invitedRooms ] ;
2015-12-02 17:10:22 +00:00
NSArray * sortedFavRooms = [ session roomsWithTag : kMXRoomTagFavourite ] ;
NSArray * sortedLowPriorRooms = [ session roomsWithTag : kMXRoomTagLowPriority ] ;
2015-12-09 15:09:46 +00:00
invitesCellDataArray = [ self createEmptyArray : sortedInvitesRooms . count ] ;
2015-12-04 08:02:02 +00:00
favoriteCellDataArray = [ self createEmptyArray : sortedFavRooms . count ] ;
lowPriorityCellDataArray = [ self createEmptyArray : sortedLowPriorRooms . count ] ;
2015-12-02 17:10:22 +00:00
2015-12-02 16:18:55 +00:00
NSInteger count = recentsDataSource . numberOfCells ;
for ( int index = 0 ; index < count ; index + + )
{
2015-12-02 17:10:22 +00:00
NSUInteger pos ;
2015-12-02 16:18:55 +00:00
id < MXKRecentCellDataStoring > recentCellDataStoring = [ recentsDataSource cellDataAtIndex : index ] ;
MXRoom * room = recentCellDataStoring . roomDataSource . room ;
2015-12-02 17:10:22 +00:00
if ( ( pos = [ sortedFavRooms indexOfObject : room ] ) ! = NSNotFound )
2015-12-02 16:18:55 +00:00
{
2015-12-04 08:02:02 +00:00
if ( pos < favoriteCellDataArray . count )
2015-12-02 17:10:22 +00:00
{
2015-12-04 08:02:02 +00:00
[ favoriteCellDataArray replaceObjectAtIndex : pos withObject : recentCellDataStoring ] ;
2015-12-02 17:10:22 +00:00
}
2015-12-02 16:18:55 +00:00
}
2015-12-02 17:10:22 +00:00
else if ( ( pos = [ sortedLowPriorRooms indexOfObject : room ] ) ! = NSNotFound )
2015-12-02 16:18:55 +00:00
{
2015-12-04 08:02:02 +00:00
if ( pos < lowPriorityCellDataArray . count )
2015-12-02 17:10:22 +00:00
{
2015-12-04 08:02:02 +00:00
[ lowPriorityCellDataArray replaceObjectAtIndex : pos withObject : recentCellDataStoring ] ;
2015-12-02 17:10:22 +00:00
}
2015-12-02 16:18:55 +00:00
}
2015-12-09 15:09:46 +00:00
else if ( ( pos = [ sortedInvitesRooms indexOfObject : room ] ) ! = NSNotFound )
{
if ( pos < invitesCellDataArray . count )
{
[ invitesCellDataArray replaceObjectAtIndex : pos withObject : recentCellDataStoring ] ;
}
}
2015-12-02 16:18:55 +00:00
else
{
2015-12-04 08:02:02 +00:00
[ conversationCellDataArray addObject : recentCellDataStoring ] ;
2015-12-02 16:18:55 +00:00
}
}
2015-12-16 15:29:34 +00:00
2015-12-09 15:09:46 +00:00
[ invitesCellDataArray removeObject : [ NSNull null ] ] ;
if ( invitesCellDataArray . count > 0 )
{
invitesSection = sectionIndex ;
sectionIndex + + ;
}
2015-12-04 08:02:02 +00:00
[ favoriteCellDataArray removeObject : [ NSNull null ] ] ;
if ( favoriteCellDataArray . count > 0 )
2015-12-02 16:18:55 +00:00
{
2015-12-04 08:02:02 +00:00
favoritesSection = sectionIndex ;
sectionIndex + + ;
2015-12-02 16:18:55 +00:00
}
2015-12-04 08:02:02 +00:00
[ conversationCellDataArray removeObject : [ NSNull null ] ] ;
if ( conversationCellDataArray . count > 0 )
2015-12-02 16:18:55 +00:00
{
2015-12-04 08:02:02 +00:00
conversationSection = sectionIndex ;
sectionIndex + + ;
2015-12-02 16:18:55 +00:00
}
2015-12-04 08:02:02 +00:00
[ lowPriorityCellDataArray removeObject : [ NSNull null ] ] ;
if ( lowPriorityCellDataArray . count > 0 )
2015-12-02 16:18:55 +00:00
{
2015-12-04 08:02:02 +00:00
lowPrioritySection = sectionIndex ;
sectionIndex + + ;
2015-12-02 16:18:55 +00:00
}
}
2015-12-18 11:03:43 +00:00
sectionsCount = sectionIndex ;
2015-12-02 16:38:10 +00:00
}
- ( void ) dataSource : ( MXKDataSource * ) dataSource didCellChange : ( id ) changes
{
2015-12-16 08:17:28 +00:00
// Refresh is disabled during drag & drop animation
2015-12-16 07:59:40 +00:00
if ( self . droppingCellIndexPath )
2015-12-11 14:30:26 +00:00
{
return ;
}
2015-12-04 08:02:02 +00:00
// FIXME : manage multi accounts
// to manage multi accounts
// this method in MXKInterleavedRecentsDataSource must be split in two parts
// 1 - the intervealing cells method
// 2 - [ super dataSource : dataSource didCellChange : changes ] call .
// the [ self refreshRoomsSections ] call should be done at the end of the 1 - method
// so a dedicated method must be implemented in MXKInterleavedRecentsDataSource
// this class will inherit of this new method
// 1 - call [ super thisNewMethod ]
// 2 - call [ self refreshRoomsSections ]
2015-12-14 07:29:01 +00:00
// refresh the sections
2015-12-03 08:06:40 +00:00
[ self refreshRoomsSections ] ;
2015-12-02 16:18:55 +00:00
// Call super to keep update readyRecentsDataSourceArray .
[ super dataSource : dataSource didCellChange : changes ] ;
}
2015-11-20 17:14:15 +00:00
# pragma mark - Override MXKDataSource
- ( void ) destroy
{
[ super destroy ] ;
}
2015-12-16 15:29:34 +00:00
# pragma mark - Override MXKRecentsDataSource
- ( void ) searchWithPatterns : ( NSArray * ) patternsList
{
[ super searchWithPatterns : patternsList ] ;
2015-12-21 10:13:46 +00:00
if ( _publicRoomsDirectoryDataSource )
2015-12-16 15:29:34 +00:00
{
2015-12-21 14:29:57 +00:00
_publicRoomsDirectoryDataSource . searchPatternsList = patternsList ;
2015-12-16 15:29:34 +00:00
}
}
2015-12-11 10:50:13 +00:00
# pragma mark - drag and drop managemenent
- ( BOOL ) isDraggableCellAt : ( NSIndexPath * ) path
{
return ( path && ( ( path . section = = favoritesSection ) || ( path . section = = lowPrioritySection ) || ( path . section = = conversationSection ) ) ) ;
}
- ( BOOL ) canCellMoveFrom : ( NSIndexPath * ) oldPath to : ( NSIndexPath * ) newPath
{
BOOL res = [ self isDraggableCellAt : oldPath ] && [ self isDraggableCellAt : newPath ] ;
// the both index pathes are movable
if ( res )
{
2015-12-11 15:20:26 +00:00
// only the favorites cell can be moved within the same section
res & = ( oldPath . section = = favoritesSection ) || ( newPath . section ! = oldPath . section ) ;
2015-12-11 10:50:13 +00:00
// other cases ?
}
return res ;
}
- ( NSString * ) roomTagAt : ( NSIndexPath * ) path
{
if ( path . section = = favoritesSection )
{
return kMXRoomTagFavourite ;
}
else if ( path . section = = lowPrioritySection )
{
return kMXRoomTagLowPriority ;
}
return nil ;
}
2015-12-15 07:34:46 +00:00
- ( void ) moveRoomCell : ( MXRoom * ) room from : ( NSIndexPath * ) oldPath to : ( NSIndexPath * ) newPath success : ( void ( ^ ) ( ) ) moveSuccess failure : ( void ( ^ ) ( NSError * error ) ) moveFailure ;
2015-12-11 10:50:13 +00:00
{
2015-12-21 09:35:48 +00:00
NSLog ( @ "[RecentsDataSource] moveCellFrom (%tu, %tu) to (%tu, %tu)" , oldPath . section , oldPath . row , newPath . section , newPath . row ) ;
2015-12-11 11:03:05 +00:00
2015-12-11 10:50:13 +00:00
if ( [ self canCellMoveFrom : oldPath to : newPath ] && ! [ newPath isEqual : oldPath ] )
{
NSString * oldRoomTag = [ self roomTagAt : oldPath ] ;
NSString * dstRoomTag = [ self roomTagAt : newPath ] ;
2015-12-15 07:34:46 +00:00
NSUInteger oldPos = ( oldPath . section = = newPath . section ) ? oldPath . row : NSNotFound ;
2015-12-11 10:50:13 +00:00
2015-12-15 07:34:46 +00:00
NSString * tagOrder = [ room . mxSession tagOrderToBeAtIndex : newPath . row from : oldPos withTag : dstRoomTag ] ;
2015-12-11 10:50:13 +00:00
2015-12-15 07:34:46 +00:00
NSLog ( @ "[RecentsDataSource] Update the room %@ [%@] tag from %@ to %@ with tag order %@" , room . state . roomId , room . state . displayname , oldRoomTag , dstRoomTag , tagOrder ) ;
2015-12-11 10:50:13 +00:00
[ room replaceTag : oldRoomTag
byTag : dstRoomTag
withOrder : tagOrder
success : ^ {
2015-12-11 14:30:26 +00:00
NSLog ( @ "[RecentsDataSource] move is done" ) ;
if ( moveSuccess )
2015-12-11 10:50:13 +00:00
{
2015-12-11 14:30:26 +00:00
moveSuccess ( ) ;
2015-12-11 10:50:13 +00:00
}
2015-12-15 07:34:46 +00:00
// wait the server echo to reload the tableview .
2015-12-14 10:08:57 +00:00
2015-12-11 10:50:13 +00:00
} failure : ^ ( NSError * error ) {
2015-12-11 11:03:05 +00:00
NSLog ( @ "[RecentsDataSource] Failed to update the tag %@ of room (%@) failed: %@" , dstRoomTag , room . state . roomId , error ) ;
2015-12-11 14:30:26 +00:00
if ( moveFailure )
{
moveFailure ( error ) ;
}
2015-12-11 10:50:13 +00:00
2015-12-14 10:08:57 +00:00
[ self refreshRoomsSectionsAndReload ] ;
2015-12-11 10:50:13 +00:00
// Notify MatrixKit user
[ [ NSNotificationCenter defaultCenter ] postNotificationName : kMXKErrorNotification object : error ] ;
} ] ;
}
2015-12-11 11:03:05 +00:00
else
{
NSLog ( @ "[RecentsDataSource] cannot move this cell" ) ;
2015-12-11 14:30:26 +00:00
if ( moveFailure )
{
moveFailure ( nil ) ;
}
2015-12-14 12:06:25 +00:00
[ self refreshRoomsSectionsAndReload ] ;
2015-12-11 11:03:05 +00:00
}
2015-12-11 10:50:13 +00:00
}
2015-11-20 17:14:15 +00:00
@ end