element-ios/Riot/ViewController/HomeViewController.m

536 lines
20 KiB
Mathematica
Raw Normal View History

/*
Copyright 2015 OpenMarket Ltd
Copyright 2017 Vector Creations 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 "HomeViewController.h"
#import "AppDelegate.h"
#import "RecentsDataSource.h"
2017-05-05 13:30:35 +00:00
#import "TableViewCellWithCollectionView.h"
#import "RoomCollectionViewCell.h"
#import "MXRoom+Riot.h"
2017-05-05 13:30:35 +00:00
@interface HomeViewController ()
{
RecentsDataSource *recentsDataSource;
// Room edition
NSInteger editedSection;
NSString *selectedRoomId;
UISwipeGestureRecognizer *horizontalSwipeGestureRecognizer;
UISwipeGestureRecognizer *verticalSwipeGestureRecognizer;
2017-05-05 13:30:35 +00:00
}
@end
@implementation HomeViewController
- (void)finalizeInit
{
[super finalizeInit];
editedSection = -1;
selectedRoomId = nil;
self.screenName = @"Home";
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.accessibilityIdentifier = @"HomeVCView";
self.recentsTableView.accessibilityIdentifier = @"HomeVCTableView";
// Tag the recents table with the its recents data source mode.
// This will be used by the shared RecentsDataSource instance for sanity checks (see UITableViewDataSource methods).
self.recentsTableView.tag = RecentsDataSourceModeHome;
// Add the (+) button programmatically
[self addPlusButton];
2017-05-05 13:30:35 +00:00
// Register table view cell used for rooms collection.
[self.recentsTableView registerClass:TableViewCellWithCollectionView.class forCellReuseIdentifier:TableViewCellWithCollectionView.defaultReuseIdentifier];
// Change the table data source. It must be the home view controller itself.
self.recentsTableView.dataSource = self;
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[AppDelegate theDelegate].masterTabBarController.navigationItem.title = NSLocalizedStringFromTable(@"title_home", @"Vector", nil);
2017-05-05 13:30:35 +00:00
if (recentsDataSource)
{
// Take the lead on the shared data source.
2017-05-05 13:30:35 +00:00
recentsDataSource.areSectionsShrinkable = NO;
[recentsDataSource setDelegate:self andRecentsDataSourceMode:RecentsDataSourceModeHome];
}
[self moveAllCollectionsToLeft];
}
- (void)dealloc
{
}
- (void)destroy
{
[super destroy];
}
- (void)moveAllCollectionsToLeft
{
// Scroll all rooms collections to their beginning
for (NSInteger section = 0; section < [self numberOfSectionsInTableView:self.recentsTableView]; section++)
{
UITableViewCell *firstSectionCell = [self.recentsTableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:section]];
if (firstSectionCell && [firstSectionCell isKindOfClass:TableViewCellWithCollectionView.class])
{
TableViewCellWithCollectionView *tableViewCell = (TableViewCellWithCollectionView*)firstSectionCell;
if ([tableViewCell.collectionView numberOfItemsInSection:0] > 0)
{
[tableViewCell.collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:0] atScrollPosition:UICollectionViewScrollPositionLeft animated:NO];
}
}
}
}
#pragma mark - Override RecentsViewController
2017-05-05 13:30:35 +00:00
- (void)displayList:(MXKRecentsDataSource *)listDataSource
{
[super displayList:listDataSource];
// Change the table data source. It must be the home view controller itself.
self.recentsTableView.dataSource = self;
// Keep a ref on the recents data source
if ([listDataSource isKindOfClass:RecentsDataSource.class])
{
recentsDataSource = (RecentsDataSource*)listDataSource;
}
}
- (void)refreshCurrentSelectedCell:(BOOL)forceVisible
{
// Check whether the recents data source is correctly configured.
2017-05-05 13:30:35 +00:00
if (recentsDataSource.recentsDataSourceMode != RecentsDataSourceModeHome)
{
2017-05-05 13:30:35 +00:00
return;
}
2017-05-05 13:30:35 +00:00
// TODO: refreshCurrentSelectedCell
//[super refreshCurrentSelectedCell:forceVisible];
}
- (void)didTapOnSectionHeader:(UIGestureRecognizer*)gestureRecognizer
{
UIView *view = gestureRecognizer.view;
NSInteger section = view.tag;
if (selectedRoomId)
{
[self cancelEditionMode:YES];
}
// Scroll to the top this section
if ([self.recentsTableView numberOfRowsInSection:section] > 0)
{
[self.recentsTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:section] atScrollPosition:UITableViewScrollPositionTop animated:YES];
}
// Scroll to the beginning the corresponding rooms collection.
UITableViewCell *firstSectionCell = [self.recentsTableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:section]];
if (firstSectionCell && [firstSectionCell isKindOfClass:TableViewCellWithCollectionView.class])
{
TableViewCellWithCollectionView *tableViewCell = (TableViewCellWithCollectionView*)firstSectionCell;
if ([tableViewCell.collectionView numberOfItemsInSection:0] > 0)
{
[tableViewCell.collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:0] atScrollPosition:UICollectionViewScrollPositionLeft animated:YES];
}
}
}
- (void)scrollToTop:(BOOL)animated
{
if (selectedRoomId)
{
[self cancelEditionMode:YES];
}
[super scrollToTop:animated];
}
- (void)onPlusButtonPressed
{
if (selectedRoomId)
{
[self cancelEditionMode:YES];
}
[super onPlusButtonPressed];
}
- (void)cancelEditionMode:(BOOL)forceRefresh
{
if (selectedRoomId)
{
// Ignore forceRefresh, a table refresh is forced at the end.
[super cancelEditionMode:NO];
editedRoomId = selectedRoomId = nil;
editedSection = -1;
// Remove existing gesture recognizers
[self.recentsTableView removeGestureRecognizer:horizontalSwipeGestureRecognizer];
horizontalSwipeGestureRecognizer = nil;
[self.recentsTableView removeGestureRecognizer:verticalSwipeGestureRecognizer];
verticalSwipeGestureRecognizer = nil;
self.recentsTableView.scrollEnabled = YES;
[self refreshRecentsTable];
}
}
2017-05-05 13:30:35 +00:00
#pragma mark - UITableViewDataSource
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the actual number of sections prepared in recents dataSource.
return [recentsDataSource numberOfSectionsInTableView:tableView];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Edit the potential selected room (see `onCollectionViewCellLongPress`).
editedRoomId = selectedRoomId;
2017-05-05 13:30:35 +00:00
// Each rooms section is represented by only one collection view.
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if ((indexPath.section == recentsDataSource.conversationSection && !recentsDataSource.conversationCellDataArray.count)
|| (indexPath.section == recentsDataSource.peopleSection && !recentsDataSource.peopleCellDataArray.count))
2017-05-05 13:30:35 +00:00
{
return [recentsDataSource tableView:tableView cellForRowAtIndexPath:indexPath];
2017-05-05 13:30:35 +00:00
}
TableViewCellWithCollectionView *tableViewCell = [tableView dequeueReusableCellWithIdentifier:TableViewCellWithCollectionView.defaultReuseIdentifier forIndexPath:indexPath];
tableViewCell.collectionView.tag = indexPath.section;
[tableViewCell.collectionView registerClass:RoomCollectionViewCell.class forCellWithReuseIdentifier:RoomCollectionViewCell.defaultReuseIdentifier];
tableViewCell.collectionView.delegate = self;
tableViewCell.collectionView.dataSource = self;
tableViewCell.selectionStyle = UITableViewCellSelectionStyleNone;
2017-05-05 13:30:35 +00:00
if (editedSection != -1 && editedRoomId)
{
// Disable collection scrolling during edition
tableViewCell.collectionView.scrollEnabled = NO;
if (indexPath.section == editedSection)
{
// Show edition menu
tableViewCell.editionViewHeightConstraint.constant = 65;
tableViewCell.editionView.hidden = NO;
MXRoom *room = [self.mainSession roomWithRoomId:editedRoomId];
// Update the edition menu content (Use the button tag to store the current value).
tableViewCell.directChatButton.tag = room.isDirect;
[tableViewCell.directChatButton addTarget:self action:@selector(onDirectChatButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
tableViewCell.directChatImageView.image = tableViewCell.directChatButton.tag ? [UIImage imageNamed:@"directChatOff"] : [UIImage imageNamed:@"directChatOn"];
tableViewCell.notificationsButton.tag = room.isMute || room.isMentionsOnly;
[tableViewCell.notificationsButton addTarget:self action:@selector(onNotificationsButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
tableViewCell.notificationsImageView.image = tableViewCell.notificationsButton.tag ? [UIImage imageNamed:@"notifications"] : [UIImage imageNamed:@"notificationsOff"];
// Get the room tag (use only the first one).
MXRoomTag* currentTag = nil;
if (room.accountData.tags)
{
NSArray<MXRoomTag*>* tags = room.accountData.tags.allValues;
if (tags.count)
{
currentTag = [tags objectAtIndex:0];
}
}
tableViewCell.favouriteButton.tag = (currentTag && [kMXRoomTagFavourite isEqualToString:currentTag.name]);
[tableViewCell.favouriteButton addTarget:self action:@selector(onFavouriteButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
tableViewCell.favouriteImageView.image = tableViewCell.favouriteButton.tag ? [UIImage imageNamed:@"favouriteOff"] : [UIImage imageNamed:@"favourite"];
tableViewCell.priorityButton.tag = (currentTag && [kMXRoomTagLowPriority isEqualToString:currentTag.name]);
[tableViewCell.priorityButton addTarget:self action:@selector(onPriorityButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
tableViewCell.priorityImageView.image = tableViewCell.priorityButton.tag ? [UIImage imageNamed:@"priorityHigh"] : [UIImage imageNamed:@"priorityLow"];
[tableViewCell.leaveButton addTarget:self action:@selector(onLeaveButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
tableViewCell.leaveImageView.image = [UIImage imageNamed:@"leave"];
}
}
return tableViewCell;
2017-05-05 13:30:35 +00:00
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
return NO;
}
#pragma mark - UITableView delegate
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if ((indexPath.section == recentsDataSource.conversationSection && !recentsDataSource.conversationCellDataArray.count)
|| (indexPath.section == recentsDataSource.peopleSection && !recentsDataSource.peopleCellDataArray.count))
2017-05-05 13:30:35 +00:00
{
return [recentsDataSource cellHeightAtIndexPath:indexPath];
2017-05-05 13:30:35 +00:00
}
if (indexPath.section != editedSection)
{
// Return the fixed height of the collection view cell used to display a room.
return [RoomCollectionViewCell defaultCellSize].height;
}
else
{
// Add the edition view height
return [RoomCollectionViewCell defaultCellSize].height + 65.0;
}
2017-05-05 13:30:35 +00:00
}
#pragma mark - UICollectionViewDataSource
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return [recentsDataSource tableView:self.recentsTableView numberOfRowsInSection:collectionView.tag];
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
RoomCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:RoomCollectionViewCell.defaultReuseIdentifier
forIndexPath:indexPath];
id<MXKRecentCellDataStoring> cellData = [recentsDataSource cellDataAtIndexPath:[NSIndexPath indexPathForRow:indexPath.item inSection:collectionView.tag]];
if (cellData)
{
[cell render:cellData];
cell.tag = indexPath.item;
cell.collectionViewTag = collectionView.tag;
2017-05-05 13:30:35 +00:00
// Edition mode?
if (editedRoomId)
{
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onCollectionViewCellTap:)];
[cell addGestureRecognizer:tapGesture];
if ([cellData.roomSummary.roomId isEqualToString:editedRoomId])
{
cell.editionArrowView.hidden = NO;
}
}
else
{
// Add long tap gesture recognizer.
UILongPressGestureRecognizer *cellLongPressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(onCollectionViewCellLongPress:)];
[cell addGestureRecognizer:cellLongPressGesture];
}
2017-05-05 13:30:35 +00:00
}
return cell;
}
#pragma mark - UICollectionViewDelegate
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
if (self.delegate)
{
RoomCollectionViewCell *roomCollectionViewCell = (RoomCollectionViewCell*)[collectionView cellForItemAtIndexPath:indexPath];
2017-05-05 13:30:35 +00:00
id<MXKRecentCellDataStoring> renderedCellData = (id<MXKRecentCellDataStoring>)roomCollectionViewCell.renderedCellData;
[self.delegate recentListViewController:self didSelectRoom:renderedCellData.roomSummary.roomId inMatrixSession:renderedCellData.roomSummary.room.mxSession];
2017-05-05 13:30:35 +00:00
}
// Hide the keyboard when user select a room
// do not hide the searchBar until the view controller disappear
// on tablets / iphone 6+, the user could expect to search again while looking at a room
[self.recentsSearchBar resignFirstResponder];
}
#pragma mark - UICollectionViewDelegateFlowLayout
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
return [RoomCollectionViewCell defaultCellSize];
}
#pragma mark - Gesture Recognizer
- (void)onCollectionViewCellLongPress:(UIGestureRecognizer*)gestureRecognizer
{
RoomCollectionViewCell *selectedCell;
if (gestureRecognizer.state == UIGestureRecognizerStateBegan)
{
UIView *view = gestureRecognizer.view;
if ([view isKindOfClass:[RoomCollectionViewCell class]])
{
selectedCell = (RoomCollectionViewCell*)view;
MXRoom* room = [self.dataSource getRoomAtIndexPath:[NSIndexPath indexPathForRow:selectedCell.tag inSection:selectedCell.collectionViewTag]];
if (room)
{
// Display no action for the invited room
if (room.state.membership == MXMembershipInvite)
{
return;
}
// Store the identifier of the room related to the edited cell.
selectedRoomId = room.state.roomId;
// Store the concerned section
editedSection = selectedCell.collectionViewTag;
[self refreshRecentsTable];
// Make visible the edited cell
TableViewCellWithCollectionView *tableViewCellWithCollectionView = [self.recentsTableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:editedSection]];
NSIndexPath *indexPath = [self.dataSource cellIndexPathWithRoomId:selectedRoomId andMatrixSession:room.mxSession];
indexPath = [NSIndexPath indexPathForItem:indexPath.item inSection:0];
UICollectionViewCell *roomCollectionViewCell = [tableViewCellWithCollectionView.collectionView cellForItemAtIndexPath:indexPath];
if (roomCollectionViewCell)
{
[tableViewCellWithCollectionView.collectionView scrollRectToVisible:roomCollectionViewCell.frame animated:YES];
}
else
{
[tableViewCellWithCollectionView.collectionView scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionNone animated:YES];
}
[self.recentsTableView scrollRectToVisible:tableViewCellWithCollectionView.frame animated:YES];
// Disable table view scrolling, and defined the swipe gesture recognizers used to cancel the edition mode
self.recentsTableView.scrollEnabled = NO;
horizontalSwipeGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(onTableViewSwipe:)];
[horizontalSwipeGestureRecognizer setDirection:(UISwipeGestureRecognizerDirectionLeft | UISwipeGestureRecognizerDirectionRight)];
[self.recentsTableView addGestureRecognizer:horizontalSwipeGestureRecognizer];
verticalSwipeGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(onTableViewSwipe:)];
[verticalSwipeGestureRecognizer setDirection:(UISwipeGestureRecognizerDirectionUp | UISwipeGestureRecognizerDirectionDown)];
[self.recentsTableView addGestureRecognizer:verticalSwipeGestureRecognizer];
}
}
}
}
- (void)onCollectionViewCellTap:(UIGestureRecognizer*)gestureRecognizer
{
[self cancelEditionMode:YES];
}
- (void)onTableViewSwipe:(UIGestureRecognizer*)gestureRecognizer
{
[self cancelEditionMode:YES];
}
#pragma mark - Action
- (IBAction)onDirectChatButtonPressed:(id)sender
{
if (editedRoomId)
{
MXRoom *room = [self.mainSession roomWithRoomId:editedRoomId];
if (room)
{
UIButton *button = (UIButton*)sender;
[self makeDirectEditedRoom:!button.tag];
}
}
}
- (IBAction)onNotificationsButtonPressed:(id)sender
{
if (editedRoomId)
{
MXRoom *room = [self.mainSession roomWithRoomId:editedRoomId];
if (room)
{
UIButton *button = (UIButton*)sender;
[self muteEditedRoomNotifications:!button.tag];
}
}
}
- (IBAction)onFavouriteButtonPressed:(id)sender
{
if (editedRoomId)
{
MXRoom *room = [self.mainSession roomWithRoomId:editedRoomId];
if (room)
{
UIButton *button = (UIButton*)sender;
if (button.tag)
{
[self updateEditedRoomTag:nil];
}
else
{
[self updateEditedRoomTag:kMXRoomTagFavourite];
}
}
}
}
- (IBAction)onPriorityButtonPressed:(id)sender
{
if (editedRoomId)
{
MXRoom *room = [self.mainSession roomWithRoomId:editedRoomId];
if (room)
{
UIButton *button = (UIButton*)sender;
if (button.tag)
{
[self updateEditedRoomTag:nil];
}
else
{
[self updateEditedRoomTag:kMXRoomTagLowPriority];
}
}
}
}
- (IBAction)onLeaveButtonPressed:(id)sender
{
[self leaveEditedRoom];
}
@end