element-ios/matrixConsole/ViewController/RoomViewController.m

655 lines
25 KiB
Mathematica
Raw Normal View History

/*
Copyright 2014 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.
*/
2014-11-17 16:32:46 +00:00
#import "RoomViewController.h"
2014-12-23 17:51:49 +00:00
#import "MemberViewController.h"
#import "MXKRoomBubbleTableViewCell.h"
#import "RoomMemberTableCell.h"
#import "RoomTitleView.h"
#import "MatrixSDKHandler.h"
2014-10-14 15:56:03 +00:00
#import "AppDelegate.h"
#import "AppSettings.h"
2014-10-14 15:56:03 +00:00
#import "RageShakeManager.h"
// TODO GFO
#define ROOMVIEWCONTROLLER_UPLOAD_FILE_SIZE 5000000
2014-10-09 17:06:30 +00:00
@interface RoomViewController () {
2014-10-17 13:54:59 +00:00
// Members list
NSArray *members;
id membersListener;
// the user taps on a member thumbnail
MXRoomMember *selectedRoomMember;
2014-10-14 15:56:03 +00:00
}
@property (weak, nonatomic) IBOutlet UINavigationItem *roomNavItem;
@property (strong, nonatomic) IBOutlet UIBarButtonItem *showRoomMembersButtonItem;
@property (weak, nonatomic) IBOutlet RoomTitleView *roomTitleView;
@property (weak, nonatomic) IBOutlet UIView *membersView;
@property (weak, nonatomic) IBOutlet UITableView *membersTableView;
2014-10-13 16:53:33 +00:00
@property (strong, nonatomic) MXKAlert *actionMenu;
@end
@implementation RoomViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Replace the default input toolbar view with the one based on `HPGrowingTextView`.
[self setRoomInputToolbarViewClass:MXKRoomInputToolbarViewWithHPGrowingText.class];
// Set rageShake handler
self.rageShakeManager = [RageShakeManager sharedManager];
// ensure that the titleView will be scaled when it will be required
// during a screen rotation for example.
self.roomTitleView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
2014-10-13 16:53:33 +00:00
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
// Register a listener for events that concern room members
MatrixSDKHandler *mxHandler = [MatrixSDKHandler sharedHandler];
NSArray *mxMembersEvents = @[
kMXEventTypeStringRoomMember,
kMXEventTypeStringRoomPowerLevels,
kMXEventTypeStringPresence
];
membersListener = [mxHandler.mxSession listenToEventsOfTypes:mxMembersEvents onEvent:^(MXEvent *event, MXEventDirection direction, id customObject) {
// consider only live event
if (direction == MXEventDirectionForwards) {
// Check the room Id (if any)
2015-04-07 14:22:40 +00:00
if (event.roomId && [event.roomId isEqualToString:self.roomDataSource.roomId] == NO) {
// This event does not concern the current room members
return;
}
// Check whether no text field is editing before refreshing title view
if (!self.roomTitleView.isEditing) {
[self.roomTitleView refreshDisplay];
}
// refresh the
if (members.count > 0) {
// Hide potential action sheet
if (self.actionMenu) {
[self.actionMenu dismiss:NO];
self.actionMenu = nil;
}
// Refresh members list
[self updateRoomMembers];
[self.membersTableView reloadData];
}
}
}];
2014-10-13 16:53:33 +00:00
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
MatrixSDKHandler *mxHandler = [MatrixSDKHandler sharedHandler];
// hide action
if (self.actionMenu) {
[self.actionMenu dismiss:NO];
self.actionMenu = nil;
}
2014-10-17 13:54:59 +00:00
// Hide members by default
[self hideRoomMembers:nil];
2014-10-17 13:54:59 +00:00
// Store the potential message partially typed in text input
2015-04-07 14:22:40 +00:00
[mxHandler storePartialTextMessage:self.inputToolbarView.textMessage forRoomId:self.roomDataSource.roomId];
if (membersListener) {
[mxHandler.mxSession removeListener:membersListener];
membersListener = nil;
}
2014-10-13 16:53:33 +00:00
}
2014-10-14 15:56:03 +00:00
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
// Set visible room id
2015-04-07 14:22:40 +00:00
[AppDelegate theDelegate].masterTabBarController.visibleRoomId = self.roomDataSource.roomId;
[self updateUI];
// Retrieve the potential message partially typed during last room display.
// Note: We have to wait for viewDidAppear before updating growingTextView (viewWillAppear is too early)
2015-04-07 14:22:40 +00:00
self.inputToolbarView.textMessage = [[MatrixSDKHandler sharedHandler] partialTextMessageForRoomId:self.roomDataSource.roomId];
2014-10-14 15:56:03 +00:00
}
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
// Reset visible room id
[AppDelegate theDelegate].masterTabBarController.visibleRoomId = nil;
}
#pragma mark -
- (void)dismissKeyboard {
[_roomTitleView dismissKeyboard];
[super dismissKeyboard];
}
- (void)didMatrixSessionStateChange {
[super didMatrixSessionStateChange];
// Check dataSource state
2015-04-07 14:22:40 +00:00
if (self.roomDataSource && self.roomDataSource.state == MXKDataSourceStatePreparing) {
// dataSource is not ready, keep running the loading wheel
[self.activityIndicator startAnimating];
}
}
- (void)updateUI {
// Update UI by considering dataSource state
2015-04-07 14:22:40 +00:00
if (self.roomDataSource && self.roomDataSource.state == MXKDataSourceStateReady) {
// Here the activityIndicator should be stopped, we call `didMatrixSessionStateChange` to take
// into account mxSession state before stopping activity indicator.
[super didMatrixSessionStateChange];
// Show input tool bar
self.inputToolbarView.hidden = NO;
// Check room members to enable/disable members button in nav bar
2015-04-07 14:22:40 +00:00
self.showRoomMembersButtonItem.enabled = ([self.roomDataSource.room.state members].count != 0);
2015-04-07 14:22:40 +00:00
self.roomTitleView.mxRoom = self.roomDataSource.room;
self.roomTitleView.editable = YES;
self.roomTitleView.hidden = NO;
}
else {
self.inputToolbarView.hidden = YES;
self.showRoomMembersButtonItem.enabled = NO;
2015-04-07 14:22:40 +00:00
if (self.roomDataSource && self.roomDataSource.state == MXKDataSourceStatePreparing) {
self.roomTitleView.mxRoom = self.roomDataSource.room;
self.roomTitleView.hidden = (!self.roomTitleView.mxRoom);
} else {
self.roomTitleView.mxRoom = nil;
self.roomTitleView.hidden = NO;
}
self.roomTitleView.editable = NO;
}
[self.roomTitleView refreshDisplay];
}
#pragma mark -
- (void)displayRoom:(MXKRoomDataSource*)roomDataSource {
[super displayRoom:roomDataSource];
[self updateUI];
}
- (void)destroy {
members = nil;
if (membersListener) {
membersListener = nil;
}
if (self.actionMenu) {
[self.actionMenu dismiss:NO];
self.actionMenu = nil;
}
[super destroy];
}
#pragma mark - MXKDataSource delegate
2014-10-15 23:34:46 +00:00
- (void)dataSource:(MXKDataSource *)dataSource didStateChange:(MXKDataSourceState)state {
// Take into account dataSource state to update UI
[self updateUI];
if ([super.class respondsToSelector:@selector(dataSource:didStateChange:)]) {
[super dataSource:dataSource didStateChange:state];
}
2014-10-15 23:34:46 +00:00
}
- (void)dataSource:(MXKDataSource *)dataSource didRecognizeAction:(NSString *)actionIdentifier inCell:(id<MXKCellRendering>)cell userInfo:(NSDictionary *)userInfo {
// Override default implementation in case of tap on avatar
if ([actionIdentifier isEqualToString:kMXKRoomBubbleCellTapOnAvatarView]) {
2015-04-07 14:22:40 +00:00
selectedRoomMember = [self.roomDataSource.room.state memberWithUserId:userInfo[kMXKRoomBubbleCellUserIdKey]];
if (selectedRoomMember) {
[self performSegueWithIdentifier:@"showMemberSheet" sender:self];
}
} else {
// Keep default implementation for other actions
[super dataSource:dataSource didRecognizeAction:actionIdentifier inCell:cell userInfo:userInfo];
}
}
//#pragma mark - Internal methods
//- (void)configureView {
//
//
//// TODO GFO review following observer use
//// [[AppSettings sharedSettings] addObserver:self forKeyPath:@"hideRedactions" options:0 context:nil];
//// [[AppSettings sharedSettings] addObserver:self forKeyPath:@"hideUnsupportedEvents" options:0 context:nil];
//// [mxHandler addObserver:self forKeyPath:@"isActivityInProgress" options:0 context:nil];
//}
//#pragma mark - KVO
//- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
// if ([@"isActivityInProgress" isEqualToString:keyPath]) {
// if ([MatrixSDKHandler sharedHandler].isActivityInProgress) {
// [self startActivityIndicator];
// } else {
// [self stopActivityIndicator];
// }
// } else if ([@"hideUnsupportedEvents" isEqualToString:keyPath] || [@"hideRedactions" isEqualToString:keyPath]) {
// dispatch_async(dispatch_get_main_queue(), ^{
// if (nil == _mxRoom) {
// // The view controller has been released. Not need to go further
// return;
// }
// [self configureView];
// });
// }
//}
# pragma mark - Room members
- (void)updateRoomMembers {
2015-04-07 14:22:40 +00:00
NSArray* membersList = [self.roomDataSource.room.state members];
if (![[AppSettings sharedSettings] displayLeftUsers]) {
NSMutableArray* filteredMembers = [[NSMutableArray alloc] init];
for (MXRoomMember* member in membersList) {
if (member.membership != MXMembershipLeave) {
[filteredMembers addObject:member];
}
}
membersList = filteredMembers;
}
members = [membersList sortedArrayUsingComparator:^NSComparisonResult(MXRoomMember *member1, MXRoomMember *member2) {
// Move banned and left members at the end of the list
if (member1.membership == MXMembershipLeave || member1.membership == MXMembershipBan) {
if (member2.membership != MXMembershipLeave && member2.membership != MXMembershipBan) {
return NSOrderedDescending;
}
} else if (member2.membership == MXMembershipLeave || member2.membership == MXMembershipBan) {
return NSOrderedAscending;
}
// Move invited members just before left and banned members
if (member1.membership == MXMembershipInvite) {
if (member2.membership != MXMembershipInvite) {
return NSOrderedDescending;
}
} else if (member2.membership == MXMembershipInvite) {
return NSOrderedAscending;
}
if ([[AppSettings sharedSettings] sortMembersUsingLastSeenTime]) {
// Get the users that correspond to these members
MatrixSDKHandler *mxHandler = [MatrixSDKHandler sharedHandler];
MXUser *user1 = [mxHandler.mxSession userWithUserId:member1.userId];
MXUser *user2 = [mxHandler.mxSession userWithUserId:member2.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;
}
2015-04-07 14:22:40 +00:00
return [[self.roomDataSource.room.state memberSortedName:member1.userId] compare:[self.roomDataSource.room.state memberSortedName:member2.userId] options:NSCaseInsensitiveSearch];
}
// Consider user's lastActive ago value
if (user1.lastActiveAgo < user2.lastActiveAgo) {
return NSOrderedAscending;
} else if (user1.lastActiveAgo == user2.lastActiveAgo) {
2015-04-07 14:22:40 +00:00
return [[self.roomDataSource.room.state memberSortedName:member1.userId] compare:[self.roomDataSource.room.state memberSortedName:member2.userId] options:NSCaseInsensitiveSearch];
}
return NSOrderedDescending;
} else {
// Move user without display name at the end (before invited users)
if (member1.displayname.length) {
if (!member2.displayname.length) {
return NSOrderedAscending;
}
} else if (member2.displayname.length) {
return NSOrderedDescending;
}
2015-04-07 14:22:40 +00:00
return [[self.roomDataSource.room.state memberSortedName:member1.userId] compare:[self.roomDataSource.room.state memberSortedName:member2.userId] options:NSCaseInsensitiveSearch];
}
}];
self.showRoomMembersButtonItem.enabled = (members.count != 0);
}
- (IBAction)showRoomMembers:(id)sender {
// Dismiss keyboard
[self dismissKeyboard];
[self updateRoomMembers];
2014-10-15 23:34:46 +00:00
// check if there is some members to display
// else it makes no sense to display the list
if (0 == members.count) {
return;
2014-10-15 23:34:46 +00:00
}
self.membersView.hidden = NO;
[self.membersTableView reloadData];
// Update navigation bar items
self.navigationItem.hidesBackButton = YES;
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(hideRoomMembers:)];
2014-10-15 23:34:46 +00:00
}
- (IBAction)hideRoomMembers:(id)sender {
self.membersView.hidden = YES;
members = nil;
// Update navigation bar items
self.navigationItem.hidesBackButton = NO;
self.navigationItem.rightBarButtonItem = _showRoomMembersButtonItem;
// Force a reload to release all table cells (and then stop running timer)
[self.membersTableView reloadData];
}
#pragma mark - UITableView data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Check table view members vs messages
if (tableView == self.membersTableView) {
return members.count;
}
return 0;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
// Check table view members vs messages
if (tableView == self.membersTableView) {
// Use the same default height than message cell
return 50;
}
return [super tableView:tableView heightForRowAtIndexPath:indexPath];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
MatrixSDKHandler *mxHandler = [MatrixSDKHandler sharedHandler];
// Check table view members vs messages
if (tableView == self.membersTableView) {
RoomMemberTableCell *memberCell = [tableView dequeueReusableCellWithIdentifier:@"RoomMemberCell" forIndexPath:indexPath];
if (indexPath.row < members.count) {
MXRoomMember *roomMember = [members objectAtIndex:indexPath.row];
2015-04-07 14:22:40 +00:00
[memberCell setRoomMember:roomMember withRoom:self.roomDataSource.room];
if ([roomMember.userId isEqualToString:mxHandler.userId]) {
memberCell.typingBadge.hidden = YES; //hide typing badge for the current user
} else {
memberCell.typingBadge.hidden = YES; //TODO ([currentTypingUsers indexOfObject:roomMember.userId] == NSNotFound);
if (!memberCell.typingBadge.hidden) {
[memberCell.typingBadge.superview bringSubviewToFront:memberCell.typingBadge];
}
}
}
return memberCell;
}
return nil;
}
#pragma mark - UITableView delegate
2014-10-14 15:56:03 +00:00
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (tableView == self.membersTableView) {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
} else {
[super tableView:tableView didSelectRowAtIndexPath:indexPath];
}
2014-10-14 15:56:03 +00:00
}
- (void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath*)indexPath {
// Release here resources, and restore reusable cells
// Check table view members vs messages
if ([cell isKindOfClass:[RoomMemberTableCell class]]) {
RoomMemberTableCell *memberCell = (RoomMemberTableCell*)cell;
// Stop potential timer used to refresh member's presence
[memberCell setRoomMember:nil withRoom:nil];
} else {
[super tableView:tableView didEndDisplayingCell:cell forRowAtIndexPath:indexPath];
2014-10-13 16:53:33 +00:00
}
}
#pragma mark - UITextField delegate
2014-11-21 17:56:12 +00:00
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
NSString *alertMsg = nil;
if (textField == _roomTitleView.displayNameTextField) {
// Check whether the user has enough power to rename the room
2015-04-07 14:22:40 +00:00
MXRoomPowerLevels *powerLevels = [self.roomDataSource.room.state powerLevels];
NSUInteger userPowerLevel = [powerLevels powerLevelOfUserWithUserID:[MatrixSDKHandler sharedHandler].userId];
if (userPowerLevel >= [powerLevels minimumPowerLevelForSendingEventAsStateEvent:kMXEventTypeStringRoomName]) {
// Only the room name is edited here, update the text field with the room name
2015-04-07 14:22:40 +00:00
textField.text = self.roomDataSource.room.state.name;
textField.backgroundColor = [UIColor whiteColor];
} else {
alertMsg = @"You are not authorized to edit this room name";
}
// Check whether the user is allowed to change room topic
if (userPowerLevel >= [powerLevels minimumPowerLevelForSendingEventAsStateEvent:kMXEventTypeStringRoomTopic]) {
// Show topic text field even if the current value is nil
_roomTitleView.hiddenTopic = NO;
if (alertMsg) {
// Here the user can only update the room topic, switch on room topic field (without displaying alert)
alertMsg = nil;
[_roomTitleView.topicTextField becomeFirstResponder];
return NO;
}
}
} else if (textField == _roomTitleView.topicTextField) {
// Check whether the user has enough power to edit room topic
2015-04-07 14:22:40 +00:00
MXRoomPowerLevels *powerLevels = [self.roomDataSource.room.state powerLevels];
NSUInteger userPowerLevel = [powerLevels powerLevelOfUserWithUserID:[MatrixSDKHandler sharedHandler].userId];
if (userPowerLevel >= [powerLevels minimumPowerLevelForSendingEventAsStateEvent:kMXEventTypeStringRoomTopic]) {
textField.backgroundColor = [UIColor whiteColor];
[self.roomTitleView stopTopicAnimation];
} else {
alertMsg = @"You are not authorized to edit this room topic";
}
}
if (alertMsg) {
// Alert user
__weak typeof(self) weakSelf = self;
if (self.actionMenu) {
[self.actionMenu dismiss:NO];
}
self.actionMenu = [[MXKAlert alloc] initWithTitle:nil message:alertMsg style:MXKAlertStyleAlert];
self.actionMenu.cancelButtonIndex = [self.actionMenu addActionWithTitle:@"Cancel" style:MXKAlertActionStyleDefault handler:^(MXKAlert *alert) {
weakSelf.actionMenu = nil;
}];
[self.actionMenu showInViewController:self];
return NO;
2014-11-21 17:56:12 +00:00
}
return YES;
}
- (void)textFieldDidEndEditing:(UITextField *)textField {
if (textField == _roomTitleView.displayNameTextField) {
textField.backgroundColor = [UIColor clearColor];
NSString *roomName = textField.text;
2015-04-07 14:22:40 +00:00
if ((roomName.length || self.roomDataSource.room.state.name.length) && [roomName isEqualToString:self.roomDataSource.room.state.name] == NO) {
[self.activityIndicator startAnimating];
__weak typeof(self) weakSelf = self;
2015-04-07 14:22:40 +00:00
[self.roomDataSource.room setName:roomName success:^{
// Here the activityIndicator should be stopped, we call `didMatrixSessionStateChange` to take
// into account mxSession state before stopping activity indicator.
[super didMatrixSessionStateChange];
// Refresh title display
2015-04-07 14:22:40 +00:00
textField.text = weakSelf.roomDataSource.room.state.displayname;
2014-11-21 17:56:12 +00:00
} failure:^(NSError *error) {
[super didMatrixSessionStateChange];
2014-11-21 17:56:12 +00:00
// Revert change
2015-04-07 14:22:40 +00:00
textField.text = weakSelf.roomDataSource.room.state.displayname;
NSLog(@"[Console RoomVC] Rename room failed: %@", error);
// Alert user
2014-11-21 17:56:12 +00:00
[[AppDelegate theDelegate] showErrorAsAlert:error];
}];
} else {
// No change on room name, restore title with room displayName
2015-04-07 14:22:40 +00:00
textField.text = self.roomDataSource.room.state.displayname;
}
} else if (textField == _roomTitleView.topicTextField) {
textField.backgroundColor = [UIColor clearColor];
NSString *topic = textField.text;
2015-04-07 14:22:40 +00:00
if ((topic.length || self.roomDataSource.room.state.topic.length) && [topic isEqualToString:self.roomDataSource.room.state.topic] == NO) {
[self.activityIndicator startAnimating];
__weak typeof(self) weakSelf = self;
2015-04-07 14:22:40 +00:00
[self.roomDataSource.room setTopic:topic success:^{
// Here the activityIndicator should be stopped, we call `didMatrixSessionStateChange` to take
// into account mxSession state before stopping activity indicator.
[super didMatrixSessionStateChange];
// Hide topic field if empty
weakSelf.roomTitleView.hiddenTopic = !textField.text.length;
} failure:^(NSError *error) {
[super didMatrixSessionStateChange];
// Revert change
2015-04-07 14:22:40 +00:00
textField.text = weakSelf.roomDataSource.room.state.topic;
// Hide topic field if empty
weakSelf.roomTitleView.hiddenTopic = !textField.text.length;
2015-02-24 12:49:05 +00:00
NSLog(@"[RoomVC] Topic room change failed: %@", error);
//Alert user
[[AppDelegate theDelegate] showErrorAsAlert:error];
}];
} else {
// Hide topic field if empty
_roomTitleView.hiddenTopic = !topic.length;
2014-11-21 17:56:12 +00:00
}
}
}
- (BOOL)textFieldShouldReturn:(UITextField*) textField {
if (textField == _roomTitleView.displayNameTextField) {
// "Next" key has been pressed
[_roomTitleView.topicTextField becomeFirstResponder];
} else {
// "Done" key has been pressed
[textField resignFirstResponder];
}
2014-10-13 16:53:33 +00:00
return YES;
}
// TODO GFO move this method into dataSource
- (BOOL)isIRCStyleCommand:(NSString*)string {
// Override the default behavior for `/join` command in order to open automatically the joined room
if ([string hasPrefix:kCmdJoinRoom]) {
// Join a room
NSString *roomAlias = [string substringFromIndex:kCmdJoinRoom.length + 1];
// Remove white space from both ends
roomAlias = [roomAlias stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
// Check
if (roomAlias.length) {
[[MatrixSDKHandler sharedHandler].mxSession joinRoom:roomAlias success:^(MXRoom *room) {
// Show the room
[[AppDelegate theDelegate].masterTabBarController showRoom:room.state.roomId];
} failure:^(NSError *error) {
NSLog(@"[Console RoomVC] Join roomAlias (%@) failed: %@", roomAlias, error);
//Alert user
[[AppDelegate theDelegate] showErrorAsAlert:error];
}];
} else {
// Display cmd usage in text input as placeholder
self.inputToolbarView.placeholder = @"Usage: /join <room_alias>";
2014-11-17 16:32:46 +00:00
}
return YES;
}
return [super isIRCStyleCommand:string];
}
2014-12-23 17:51:49 +00:00
#pragma mark - Segues
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:@"showMemberSheet"]) {
MemberViewController* controller = [segue destinationViewController];
if (selectedRoomMember) {
controller.mxRoomMember = selectedRoomMember;
selectedRoomMember = nil;
} else {
NSIndexPath *indexPath = [self.membersTableView indexPathForSelectedRow];
controller.mxRoomMember = [members objectAtIndex:indexPath.row];
}
2015-04-07 14:22:40 +00:00
controller.mxRoom = self.roomDataSource.room;
2014-12-23 17:51:49 +00:00
}
}
@end