element-ios/matrixConsole/ViewController/HomeViewController.m

387 lines
14 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.
*/
#import "HomeViewController.h"
#import "MatrixHandler.h"
#import "AppDelegate.h"
@interface HomeViewController () {
NSArray *publicRooms;
// List of public room names to highlight in displayed list
NSArray* highlightedPublicRooms;
}
@property (weak, nonatomic) IBOutlet UITableView *publicRoomsTable;
@property (weak, nonatomic) IBOutlet UILabel *roomCreationLabel;
@property (weak, nonatomic) IBOutlet UILabel *roomNameLabel;
@property (weak, nonatomic) IBOutlet UILabel *roomAliasLabel;
@property (weak, nonatomic) IBOutlet UILabel *participantsLabel;
@property (weak, nonatomic) IBOutlet UITextField *roomNameTextField;
@property (weak, nonatomic) IBOutlet UITextField *roomAliasTextField;
@property (weak, nonatomic) IBOutlet UITextField *participantsTextField;
@property (weak, nonatomic) IBOutlet UISegmentedControl *roomVisibilityControl;
@property (weak, nonatomic) IBOutlet UIButton *createRoomBtn;
- (IBAction)onButtonPressed:(id)sender;
@end
@implementation HomeViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
_roomCreationLabel.backgroundColor = [UIColor colorWithRed:0.9 green:0.9 blue:0.9 alpha:1.0];
_createRoomBtn.enabled = NO;
_createRoomBtn.alpha = 0.5;
// Init
publicRooms = nil;
highlightedPublicRooms = @[@"#matrix:matrix.org"]; // Add here a room name to highlight its display in public room list
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)dealloc{
publicRooms = nil;
highlightedPublicRooms = nil;
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
// Ensure to display room creation section
[self.tableView scrollRectToVisible:_roomCreationLabel.frame animated:NO];
if ([[MatrixHandler sharedHandler] isLogged]) {
// Update alias placeholder
_roomAliasTextField.placeholder = [NSString stringWithFormat:@"(e.g. #foo:%@)", [MatrixHandler sharedHandler].homeServer];
// Refresh listed public rooms
[self refreshPublicRooms];
}
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onTextFieldChange:) name:UITextFieldTextDidChangeNotification object:nil];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UITextFieldTextDidChangeNotification object:nil];
}
#pragma mark - Internals
- (void)refreshPublicRooms {
// Retrieve public rooms
[[MatrixHandler sharedHandler].mxRestClient publicRooms:^(NSArray *rooms){
publicRooms = [rooms sortedArrayUsingComparator:^NSComparisonResult(id a, id b) {
MXPublicRoom *firstRoom = (MXPublicRoom*)a;
MXPublicRoom *secondRoom = (MXPublicRoom*)b;
return [firstRoom.displayname compare:secondRoom.displayname options:NSCaseInsensitiveSearch];
}];
[_publicRoomsTable reloadData];
}
failure:^(NSError *error){
NSLog(@"GET public rooms failed: %@", error);
//Alert user
[[AppDelegate theDelegate] showErrorAsAlert:error];
}];
}
- (void)dismissKeyboard {
// Hide the keyboard
[_roomNameTextField resignFirstResponder];
[_roomAliasTextField resignFirstResponder];
[_participantsTextField resignFirstResponder];
}
- (NSString*)alias {
// Extract alias name from alias text field
NSString *alias = _roomAliasTextField.text;
if (alias.length > 1) {
// Remove '#' character
alias = [alias substringFromIndex:1];
// Remove homeserver
NSString *suffix = [NSString stringWithFormat:@":%@",[MatrixHandler sharedHandler].homeServer];
NSRange range = [alias rangeOfString:suffix];
alias = [alias stringByReplacingCharactersInRange:range withString:@""];
}
if (! alias.length) {
alias = nil;
}
return alias;
}
- (NSArray*)participantsList {
NSMutableArray *participants = [NSMutableArray array];
if (_participantsTextField.text.length) {
NSArray *components = [_participantsTextField.text componentsSeparatedByString:@";"];
for (NSString *component in components) {
// Remove white space from both ends
NSString *user = [component stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
if (user.length > 1 && [user hasPrefix:@"@"]) {
[participants addObject:user];
}
}
}
if (participants.count == 0) {
participants = nil;
}
return participants;
}
#pragma mark - UITextField delegate
- (void)onTextFieldChange:(NSNotification *)notif {
NSString *roomName = _roomNameTextField.text;
NSString *roomAlias = _roomAliasTextField.text;
NSString *participants = _participantsTextField.text;
if (roomName.length || roomAlias.length || participants.length) {
_createRoomBtn.enabled = YES;
_createRoomBtn.alpha = 1;
} else {
_createRoomBtn.enabled = NO;
_createRoomBtn.alpha = 0.5;
}
}
- (void)textFieldDidBeginEditing:(UITextField *)textField {
if (textField == _roomAliasTextField) {
textField.text = self.alias;
textField.placeholder = @"foo";
} else if (textField == _participantsTextField) {
if (textField.text.length == 0) {
textField.text = @"@";
}
}
}
- (void)textFieldDidEndEditing:(UITextField *)textField {
if (textField == _roomAliasTextField) {
// Compute the new phone number with this string change
NSString * alias = textField.text;
if (alias.length) {
// add homeserver as suffix
textField.text = [NSString stringWithFormat:@"#%@:%@", alias, [MatrixHandler sharedHandler].homeServer];
}
textField.placeholder = [NSString stringWithFormat:@"(e.g. #foo:%@)", [MatrixHandler sharedHandler].homeServer];
} else if (textField == _participantsTextField) {
NSArray *participants = self.participantsList;
textField.text = [participants componentsJoinedByString:@"; "];
}
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
// Auto complete participant IDs
if (textField == _participantsTextField) {
// Auto completion is active only when the change concerns the end of the current string
if (range.location == textField.text.length) {
NSString *participants = [textField.text stringByReplacingCharactersInRange:range withString:string];
if ([string isEqualToString:@";"]) {
// Add '@' character
participants = [participants stringByAppendingString:@" @"];
} else if ([string isEqualToString:@":"]) {
// Add homeserver
participants = [participants stringByAppendingString:[MatrixHandler sharedHandler].homeServer];
}
textField.text = participants;
// Update Create button status
[self onTextFieldChange:nil];
return NO;
}
}
return YES;
}
- (BOOL)textFieldShouldReturn:(UITextField*) textField {
// "Done" key has been pressed
[textField resignFirstResponder];
return YES;
}
#pragma mark - Actions
- (IBAction)onButtonPressed:(id)sender {
[self dismissKeyboard];
if (sender == _createRoomBtn) {
// Disable button to prevent multiple request
_createRoomBtn.enabled = NO;
NSString *roomName = _roomNameTextField.text;
if (! roomName.length) {
roomName = nil;
}
// Create new room
MatrixHandler *mxHandler = [MatrixHandler sharedHandler];
[mxHandler.mxRestClient createRoom:roomName
visibility:(_roomVisibilityControl.selectedSegmentIndex == 0) ? kMXRoomVisibilityPublic : kMXRoomVisibilityPrivate
room_alias_name:self.alias
topic:nil
success:^(MXCreateRoomResponse *response) {
// Check whether some users must be invited
NSArray *invitedUsers = self.participantsList;
for (NSString *userId in invitedUsers) {
[mxHandler.mxRestClient inviteUser:userId toRoom:response.roomId success:^{
NSLog(@"%@ has been invited (roomId: %@)", userId, response.roomId);
} failure:^(NSError *error) {
NSLog(@"%@ invitation failed (roomId: %@): %@", userId, response.roomId, error);
//Alert user
[[AppDelegate theDelegate] showErrorAsAlert:error];
}];
}
// Reset text fields
_roomNameTextField.text = nil;
_roomAliasTextField.text = nil;
_participantsTextField.text = nil;
// Open created room
[[AppDelegate theDelegate].masterTabBarController showRoom:response.roomId];
} failure:^(NSError *error) {
_createRoomBtn.enabled = YES;
NSLog(@"Create room (%@ %@ (%@)) failed: %@", _roomNameTextField.text, self.alias, (_roomVisibilityControl.selectedSegmentIndex == 0) ? @"Public":@"Private", error);
//Alert user
[[AppDelegate theDelegate] showErrorAsAlert:error];
}];
}
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return publicRooms.count;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
UILabel *sectionHeader = [[UILabel alloc] initWithFrame:[tableView rectForHeaderInSection:section]];
sectionHeader.font = [UIFont boldSystemFontOfSize:16];
sectionHeader.backgroundColor = [UIColor colorWithRed:0.9 green:0.9 blue:0.9 alpha:1.0];
if (publicRooms) {
NSString *homeserver = [MatrixHandler sharedHandler].homeServerURL;
if (homeserver.length) {
sectionHeader.text = [NSString stringWithFormat:@" Public Rooms (at %@):", homeserver];
} else {
sectionHeader.text = @" Public Rooms:";
}
} else {
sectionHeader.text = @" No Public Rooms";
}
return sectionHeader;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Cell is larger for public room with topic
MXPublicRoom *publicRoom = [publicRooms objectAtIndex:indexPath.row];
if (publicRoom.topic) {
return 60;
}
return 44;
}
- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
MXPublicRoom *publicRoom = [publicRooms objectAtIndex:indexPath.row];
UITableViewCell *cell;
// Check whether this public room has topic
if (publicRoom.topic) {
cell = [_publicRoomsTable dequeueReusableCellWithIdentifier:@"PublicRoomCellSubtitle" forIndexPath:indexPath];
cell.detailTextLabel.text = publicRoom.topic;
} else {
cell = [_publicRoomsTable dequeueReusableCellWithIdentifier:@"PublicRoomCellBasic" forIndexPath:indexPath];
}
// Set room display name
cell.textLabel.text = [publicRoom displayname];
// Highlight?
if (cell.textLabel.text && [highlightedPublicRooms indexOfObject:cell.textLabel.text] != NSNotFound) {
cell.textLabel.font = [UIFont boldSystemFontOfSize:20];
cell.detailTextLabel.font = [UIFont boldSystemFontOfSize:17];
} else {
cell.textLabel.font = [UIFont systemFontOfSize:19];
cell.detailTextLabel.font = [UIFont systemFontOfSize:16];
}
return cell;
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
MatrixHandler *mxHandler = [MatrixHandler sharedHandler];
// Check whether the user has already joined the selected public room
MXPublicRoom *publicRoom = [publicRooms objectAtIndex:indexPath.row];
if ([mxHandler.mxSession room:publicRoom.roomId]) {
// Open selected room
[[AppDelegate theDelegate].masterTabBarController showRoom:publicRoom.roomId];
} else {
// Join the selected room
UIActivityIndicatorView *loadingWheel = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];
if (selectedCell) {
CGPoint center = CGPointMake(selectedCell.frame.size.width / 2, selectedCell.frame.size.height / 2);
loadingWheel.center = center;
[selectedCell addSubview:loadingWheel];
}
[loadingWheel startAnimating];
[mxHandler.mxSession joinRoom:publicRoom.roomId success:^(MXRoom *room) {
// Show joined room
[loadingWheel stopAnimating];
[loadingWheel removeFromSuperview];
[[AppDelegate theDelegate].masterTabBarController showRoom:publicRoom.roomId];
} failure:^(NSError *error) {
NSLog(@"Failed to join public room (%@) failed: %@", publicRoom.displayname, error);
//Alert user
[loadingWheel stopAnimating];
[loadingWheel removeFromSuperview];
[[AppDelegate theDelegate] showErrorAsAlert:error];
}];
}
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
@end