From 19f40ef6aa530241bf0a770981d2f1c7eda7fa64 Mon Sep 17 00:00:00 2001 From: giomfo Date: Mon, 13 Oct 2014 14:45:29 +0200 Subject: [PATCH] Support new room creation --- .../syMessaging/Base.lproj/Main.storyboard | 116 ++++++++-- syMessaging/syMessaging/HomeViewController.h | 2 +- syMessaging/syMessaging/HomeViewController.m | 206 ++++++++++++++++-- syMessaging/syMessaging/LoginViewController.m | 7 +- .../syMessaging/MasterTabBarController.h | 2 + .../syMessaging/MasterTabBarController.m | 10 +- syMessaging/syMessaging/MatrixHandler.h | 3 +- syMessaging/syMessaging/MatrixHandler.m | 26 ++- .../syMessaging/RecentsViewController.m | 11 +- 9 files changed, 332 insertions(+), 51 deletions(-) diff --git a/syMessaging/syMessaging/Base.lproj/Main.storyboard b/syMessaging/syMessaging/Base.lproj/Main.storyboard index c181ce6f9..811afaf9a 100644 --- a/syMessaging/syMessaging/Base.lproj/Main.storyboard +++ b/syMessaging/syMessaging/Base.lproj/Main.storyboard @@ -62,28 +62,34 @@ - + - + - - + + - + + + + - + @@ -91,17 +97,88 @@ + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - + + + + + + + + + + + + + + + + + + + + + + @@ -128,7 +205,16 @@ + + + + + + + + + diff --git a/syMessaging/syMessaging/HomeViewController.h b/syMessaging/syMessaging/HomeViewController.h index e4ef94f0a..bd553f069 100644 --- a/syMessaging/syMessaging/HomeViewController.h +++ b/syMessaging/syMessaging/HomeViewController.h @@ -16,7 +16,7 @@ #import -@interface HomeViewController : UITableViewController +@interface HomeViewController : UITableViewController @property (strong, nonatomic) NSArray *publicRooms; @property (weak, nonatomic) IBOutlet UITableView *publicRoomsTable; diff --git a/syMessaging/syMessaging/HomeViewController.m b/syMessaging/syMessaging/HomeViewController.m index a125f284a..50b28a67e 100644 --- a/syMessaging/syMessaging/HomeViewController.m +++ b/syMessaging/syMessaging/HomeViewController.m @@ -20,6 +20,16 @@ #import "AppDelegate.h" @interface HomeViewController () +@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 @@ -28,10 +38,12 @@ - (void)viewDidLoad { [super viewDidLoad]; -// UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(addPublicRoom:)]; -// self.navigationItem.rightBarButtonItem = addButton; - // 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; } @@ -40,17 +52,26 @@ // Dispose of any resources that can be recreated. } -- (void)viewWillAppear:(BOOL)animated -{ +- (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)addPublicRoom:(id)sender { - // TODO +- (void)viewWillDisappear:(BOOL)animated { + [super viewWillDisappear:animated]; + + [[NSNotificationCenter defaultCenter] removeObserver:self name:UITextFieldTextDidChangeNotification object:nil]; } #pragma mark - Table view data source @@ -66,15 +87,23 @@ return 0; } -- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { +- (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) { - return [NSString stringWithFormat:@"Public Rooms (at %@)", homeserver]; + sectionHeader.text = [NSString stringWithFormat:@" Public Rooms (at %@):", homeserver]; + } else { + sectionHeader.text = @" Public Rooms:"; } - return @"Public Rooms"; + } else { + sectionHeader.text = @" No Public Rooms"; } - return @"No Public Rooms"; + + return sectionHeader; } - (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { @@ -106,10 +135,9 @@ #pragma mark - Internals -- (void)refreshPublicRooms -{ +- (void)refreshPublicRooms { // Retrieve public rooms - [[[MatrixHandler sharedHandler] homeServer] publicRooms:^(NSArray *rooms){ + [[[MatrixHandler sharedHandler] mxHomeServer] publicRooms:^(NSArray *rooms){ _publicRooms = rooms; [_publicRoomsTable reloadData]; } @@ -121,4 +149,154 @@ } +- (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 - + +- (IBAction)onButtonPressed:(id)sender { + [self dismissKeyboard]; + + if (sender == _createRoomBtn) { + NSString *roomName = _roomNameTextField.text; + if (! roomName.length) { + roomName = nil; + } + // Create new room + [[[MatrixHandler sharedHandler] mxSession] + createRoom:roomName + visibility:(_roomVisibilityControl.selectedSegmentIndex == 0) ? kMXRoomVisibilityPublic : kMXRoomVisibilityPrivate + room_alias_name:self.alias + topic:nil + invite:self.participantsList + success:^(MXCreateRoomResponse *response) { + // Open created room + [[AppDelegate theDelegate].masterTabBarController showRoomDetails:response.room_id]; + } failure:^(NSError *error) { + NSLog(@"Create room (%@ %@ %@ (%d)) failed: %@", _roomNameTextField.text, self.alias, self.participantsList, _roomVisibilityControl.selectedSegmentIndex, error); + //Alert user + [[AppDelegate theDelegate] showErrorAsAlert:error]; + }]; + } +} + @end diff --git a/syMessaging/syMessaging/LoginViewController.m b/syMessaging/syMessaging/LoginViewController.m index 25db0dbb7..18bbeb5bb 100644 --- a/syMessaging/syMessaging/LoginViewController.m +++ b/syMessaging/syMessaging/LoginViewController.m @@ -19,7 +19,7 @@ #import "MatrixHandler.h" #import "AppDelegate.h" -NSString* const defaultHomeserver = @"http://www.matrix.org"; +NSString* const defaultHomeserver = @"http://matrix.org"; @interface LoginViewController () @property (weak, nonatomic) IBOutlet NSLayoutConstraint *contentViewBottomConstraint; @@ -190,17 +190,18 @@ NSString* const defaultHomeserver = @"http://www.matrix.org"; if (sender == _loginBtn) { MatrixHandler *matrix = [MatrixHandler sharedHandler]; - if (matrix.homeServer) + if (matrix.mxHomeServer) { [_activityIndicator startAnimating]; - [matrix.homeServer loginWithUser:matrix.userLogin andPassword:_passWordTextField.text + [matrix.mxHomeServer loginWithUser:matrix.userLogin andPassword:_passWordTextField.text success:^(MXLoginResponse *credentials){ [_activityIndicator stopAnimating]; // Report credentials [matrix setUserId:credentials.user_id]; [matrix setAccessToken:credentials.access_token]; + [matrix setHomeServer:credentials.home_server]; [self dismissViewControllerAnimated:YES completion:nil]; } diff --git a/syMessaging/syMessaging/MasterTabBarController.h b/syMessaging/syMessaging/MasterTabBarController.h index c901630fc..9f35ae242 100644 --- a/syMessaging/syMessaging/MasterTabBarController.h +++ b/syMessaging/syMessaging/MasterTabBarController.h @@ -25,6 +25,8 @@ - (void)showLoginScreen; +- (void)showRoomCreationForm; + - (void)showRoomDetails:(NSString*)roomId; @end diff --git a/syMessaging/syMessaging/MasterTabBarController.m b/syMessaging/syMessaging/MasterTabBarController.m index 99f74b0e1..4e2472e86 100644 --- a/syMessaging/syMessaging/MasterTabBarController.m +++ b/syMessaging/syMessaging/MasterTabBarController.m @@ -28,8 +28,7 @@ // Do any additional setup after loading the view, typically from a nib. } -- (void)viewDidAppear:(BOOL)animated -{ +- (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; if (! [[MatrixHandler sharedHandler] isLogged]) { @@ -42,10 +41,17 @@ // Dispose of any resources that can be recreated. } +#pragma mark - + - (void)showLoginScreen { [self performSegueWithIdentifier:@"showLogin" sender:self]; } +- (void)showRoomCreationForm { + // Switch in Home Tab + [self setSelectedIndex:TABBAR_HOME_INDEX]; +} + - (void)showRoomDetails:(NSString*)roomId { // Switch on recent [self setSelectedIndex:TABBAR_RECENTS_INDEX]; diff --git a/syMessaging/syMessaging/MatrixHandler.h b/syMessaging/syMessaging/MatrixHandler.h index 74cbd9384..f4a165625 100644 --- a/syMessaging/syMessaging/MatrixHandler.h +++ b/syMessaging/syMessaging/MatrixHandler.h @@ -18,12 +18,13 @@ @interface MatrixHandler : NSObject -@property (strong, nonatomic) MXHomeServer *homeServer; +@property (strong, nonatomic) MXHomeServer *mxHomeServer; @property (strong, nonatomic) MXSession *mxSession; @property (strong, nonatomic) MXData *mxData; @property (strong, nonatomic) NSString *homeServerURL; +@property (strong, nonatomic) NSString *homeServer; @property (strong, nonatomic) NSString *userLogin; @property (strong, nonatomic) NSString *userId; @property (strong, nonatomic) NSString *accessToken; diff --git a/syMessaging/syMessaging/MatrixHandler.m b/syMessaging/syMessaging/MatrixHandler.m index 59927390d..82904c573 100644 --- a/syMessaging/syMessaging/MatrixHandler.m +++ b/syMessaging/syMessaging/MatrixHandler.m @@ -27,7 +27,7 @@ static MatrixHandler *sharedHandler = nil; @implementation MatrixHandler -@synthesize homeServerURL, userLogin, userId, accessToken; +@synthesize homeServerURL, homeServer, userLogin, userId, accessToken; + (id)sharedHandler { @synchronized(self) { @@ -45,9 +45,9 @@ static MatrixHandler *sharedHandler = nil; if (self = [super init]) { _isInitialSyncDone = NO; - // Read potential homeserver in shared defaults object + // Read potential homeserver url in shared defaults object if (self.homeServerURL) { - self.homeServer = [[MXHomeServer alloc] initWithHomeServer:self.homeServerURL]; + self.mxHomeServer = [[MXHomeServer alloc] initWithHomeServer:self.homeServerURL]; if (self.accessToken) { [self openSession]; @@ -81,7 +81,7 @@ static MatrixHandler *sharedHandler = nil; - (void)dealloc { [self closeSession]; - self.homeServer = nil; + self.mxHomeServer = nil; } #pragma mark - @@ -96,16 +96,28 @@ static MatrixHandler *sharedHandler = nil; } - (NSString *)homeServerURL { + return [[NSUserDefaults standardUserDefaults] objectForKey:@"homeserverurl"]; +} + +- (void)setHomeServerURL:(NSString *)inHomeserverURL { + if (inHomeserverURL.length) { + [[NSUserDefaults standardUserDefaults] setObject:inHomeserverURL forKey:@"homeserverurl"]; + self.mxHomeServer = [[MXHomeServer alloc] initWithHomeServer:inHomeserverURL]; + } else { + [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"homeserverurl"]; + self.mxHomeServer = nil; + } +} + +- (NSString *)homeServer { return [[NSUserDefaults standardUserDefaults] objectForKey:@"homeserver"]; } -- (void)setHomeServerURL:(NSString *)inHomeserver { +- (void)setHomeServer:(NSString *)inHomeserver { if (inHomeserver.length) { [[NSUserDefaults standardUserDefaults] setObject:inHomeserver forKey:@"homeserver"]; - self.homeServer = [[MXHomeServer alloc] initWithHomeServer:self.homeServerURL]; } else { [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"homeserver"]; - self.homeServer = nil; } } diff --git a/syMessaging/syMessaging/RecentsViewController.m b/syMessaging/syMessaging/RecentsViewController.m index 27301fb0d..c63139a3f 100644 --- a/syMessaging/syMessaging/RecentsViewController.m +++ b/syMessaging/syMessaging/RecentsViewController.m @@ -52,7 +52,7 @@ // Do any additional setup after loading the view, typically from a nib. self.navigationItem.leftBarButtonItem = self.editButtonItem; - UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(insertNewObject:)]; + UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(createNewRoom:)]; self.navigationItem.rightBarButtonItem = addButton; self.roomViewController = (RoomViewController *)[[self.splitViewController.viewControllers lastObject] topViewController]; @@ -103,13 +103,8 @@ } } -- (void)insertNewObject:(id)sender { -// if (!self.recents) { -// self.recents = [[NSMutableArray alloc] init]; -// } -// [self.recents insertObject:[NSDate date] atIndex:0]; -// NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0]; -// [self.tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic]; +- (void)createNewRoom:(id)sender { + [[AppDelegate theDelegate].masterTabBarController showRoomCreationForm]; } #pragma mark - KVO