Feature - Improve the people invite screens

#904.

+"Add contact" button should be added on Room Member list #905
This commit is contained in:
giomfo 2017-01-13 12:08:24 +01:00
parent 8efbbdfbda
commit c03638ad4d
11 changed files with 103 additions and 53 deletions

View file

@ -209,6 +209,9 @@
F03DE2A51D0EFA6A00E8B65C /* AttachmentsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F03DE2A41D0EFA6A00E8B65C /* AttachmentsViewController.m */; };
F046528D1E250B0A00EA4E77 /* ContactsTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F046528C1E250B0A00EA4E77 /* ContactsTableViewController.m */; };
F046528F1E28439E00EA4E77 /* ContactsTableViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = F046528E1E28439E00EA4E77 /* ContactsTableViewController.xib */; };
F04652931E28E0E300EA4E77 /* add_participant.png in Resources */ = {isa = PBXBuildFile; fileRef = F04652901E28E0E300EA4E77 /* add_participant.png */; };
F04652941E28E0E300EA4E77 /* add_participant@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = F04652911E28E0E300EA4E77 /* add_participant@2x.png */; };
F04652951E28E0E300EA4E77 /* add_participant@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = F04652921E28E0E300EA4E77 /* add_participant@3x.png */; };
F047DBB51C576F2200952DA2 /* AuthenticationViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = F047DBB41C576F2200952DA2 /* AuthenticationViewController.xib */; };
F047DBB91C576F6600952DA2 /* AuthInputsView.m in Sources */ = {isa = PBXBuildFile; fileRef = F047DBB71C576F6600952DA2 /* AuthInputsView.m */; };
F047DBBA1C576F6600952DA2 /* AuthInputsView.xib in Resources */ = {isa = PBXBuildFile; fileRef = F047DBB81C576F6600952DA2 /* AuthInputsView.xib */; };
@ -644,6 +647,9 @@
F046528B1E250B0A00EA4E77 /* ContactsTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContactsTableViewController.h; sourceTree = "<group>"; };
F046528C1E250B0A00EA4E77 /* ContactsTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ContactsTableViewController.m; sourceTree = "<group>"; };
F046528E1E28439E00EA4E77 /* ContactsTableViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ContactsTableViewController.xib; sourceTree = "<group>"; };
F04652901E28E0E300EA4E77 /* add_participant.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = add_participant.png; sourceTree = "<group>"; };
F04652911E28E0E300EA4E77 /* add_participant@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "add_participant@2x.png"; sourceTree = "<group>"; };
F04652921E28E0E300EA4E77 /* add_participant@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "add_participant@3x.png"; sourceTree = "<group>"; };
F047DBB41C576F2200952DA2 /* AuthenticationViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = AuthenticationViewController.xib; sourceTree = "<group>"; };
F047DBB61C576F6600952DA2 /* AuthInputsView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AuthInputsView.h; sourceTree = "<group>"; };
F047DBB71C576F6600952DA2 /* AuthInputsView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AuthInputsView.m; sourceTree = "<group>"; };
@ -1144,6 +1150,9 @@
F03BF5B41D8BF5B1002EF6A7 /* Images */ = {
isa = PBXGroup;
children = (
F04652901E28E0E300EA4E77 /* add_participant.png */,
F04652911E28E0E300EA4E77 /* add_participant@2x.png */,
F04652921E28E0E300EA4E77 /* add_participant@3x.png */,
F04ACE001E154C540000B970 /* riot_icon.png */,
F04ACE011E154C540000B970 /* riot_icon@2x.png */,
F04ACE021E154C540000B970 /* riot_icon@3x.png */,
@ -1793,6 +1802,7 @@
files = (
F0D2D9881C197DCB007B8C96 /* RoomIncomingTextMsgBubbleCell.xib in Resources */,
F03BF6CB1D8BF5B1002EF6A7 /* settings_icon.png in Resources */,
F04652931E28E0E300EA4E77 /* add_participant.png in Resources */,
F03BF6791D8BF5B1002EF6A7 /* chevron@3x.png in Resources */,
F03BF64B1D8BF5B1002EF6A7 /* admin_icon@3x.png in Resources */,
F09EAFB61DD2109B009C7EFB /* RoomOutgoingEncryptedTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.xib in Resources */,
@ -1828,6 +1838,7 @@
7165A25C1C05CD42003635D7 /* SegmentedViewController.xib in Resources */,
F03BF65F1D8BF5B1002EF6A7 /* call_speaker_off_icon@2x.png in Resources */,
F0A4B2F11E0073A30072D355 /* animatedLogo-1.png in Resources */,
F04652941E28E0E300EA4E77 /* add_participant@2x.png in Resources */,
F03BF6B41D8BF5B1002EF6A7 /* priorityLow@2x.png in Resources */,
F08294691DB503FE00CEAB63 /* direct_icon@2x.png in Resources */,
F04ACE041E154C540000B970 /* riot_icon@2x.png in Resources */,
@ -1889,6 +1900,7 @@
F0BE3DF21C6CE28300AC3111 /* RoomMemberDetailsViewController.xib in Resources */,
F09EAF9C1DD2109B009C7EFB /* RoomIncomingEncryptedAttachmentWithPaginationTitleBubbleCell.xib in Resources */,
F023A0161D9034FE00C517FB /* call_video_mute_on_icon.png in Resources */,
F04652951E28E0E300EA4E77 /* add_participant@3x.png in Resources */,
F03BF66A1D8BF5B1002EF6A7 /* camera_capture.png in Resources */,
F0AF11F61D1029CF00FEE52F /* RoomIdOrAliasTableViewCell.xib in Resources */,
F08714CC1DB9EFEE0075F633 /* directChatOff@3x.png in Resources */,

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

View file

@ -95,7 +95,7 @@
"room_creation_keep_private" = "Keep private";
"room_creation_make_private" = "Make private";
"room_creation_wait_for_creation" = "A room is already being created. Please wait.";
"room_creation_invite_another_user" = "Search / invite by name, email, id";
"room_creation_invite_another_user" = "Search / invite by User ID, Name or email";
// Room recents
"room_recents_directory" = "DIRECTORY";
@ -111,6 +111,8 @@
"search_messages" = "Messages";
"search_people" = "People";
"search_files" = "Files";
"search_default_placeholder" = "Search...";
"search_people_placeholder" = "Search by User ID, Name or email";
// Directory
"directory_cell_title" = "Browse directory";
@ -136,7 +138,7 @@
"room_participants_invite_prompt_title" = "Invite?";
"room_participants_invite_prompt_msg" = "Are you sure you want to invite %@ to this chat?";
"room_participants_filter_room_members" = "Filter room members";
"room_participants_invite_another_user" = "Search / invite by name, email, id";
"room_participants_invite_another_user" = "Search / invite by User ID, Name or email";
"room_participants_invite_malformed_id_title" = "Invite Error";
"room_participants_invite_malformed_id" = "Malformed ID. Should be an email address or a Matrix ID like '@localpart:domain'";
"room_participants_invited_section" = "INVITED";

View file

@ -84,6 +84,18 @@
*/
@property (nonatomic) BOOL forceMatrixIdInDisplayName;
/**
The type of standard accessory view the contact cells should use
Default is UITableViewCellAccessoryNone.
*/
@property (nonatomic) UITableViewCellAccessoryType contactCellAccessoryType;
/**
An image used to create a custom accessy view on the right side of the contact cells.
If set, use custom view. ignore accessoryType
*/
@property (nonatomic) UIImage *contactCellAccessoryImage;
/**
The dictionary of the ignored local contacts, the keys are their email. Empty by default.
*/

View file

@ -122,6 +122,8 @@
isMultiUseNameByDisplayName = nil;
_contactCellAccessoryImage = nil;
[super destroy];
}
@ -466,6 +468,8 @@
contactCell.accessoryView = nil;
contactCell.contentView.alpha = 1;
contactCell.userInteractionEnabled = YES;
contactCell.accessoryType = UITableViewCellAccessoryNone;
contactCell.accessoryView = nil;
}
MXKContact *contact;
@ -502,16 +506,17 @@
{
[contactCell render:contact];
// The search displays contacts to invite. Add a plus icon to the cell
// in order to make it more understandable for the end user
// The search displays contacts to invite.
if (indexPath.section == filteredLocalContactsSection || indexPath.section == filteredMatrixContactsSection)
{
contactCell.accessoryView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"plus_icon"]];
// Add the right accessory view if any
contactCell.accessoryType = self.contactCellAccessoryType;
contactCell.accessoryView = [[UIImageView alloc] initWithImage:self.contactCellAccessoryImage];
}
else if (indexPath.section == searchInputSection)
{
// This is the text entered by the user
// Check whether the search input is a valid email or a Matrix user ID before adding the plus icon.
// Check whether the search input is a valid email or a Matrix user ID before adding the accessory view.
if (![MXTools isEmailAddress:currentSearchText] && ![MXTools isMatrixUserIdentifier:currentSearchText])
{
contactCell.contentView.alpha = 0.5;
@ -519,7 +524,9 @@
}
else
{
contactCell.accessoryView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"plus_icon"]];
// Add the right accessory view if any
contactCell.accessoryType = self.contactCellAccessoryType;
contactCell.accessoryView = [[UIImageView alloc] initWithImage:self.contactCellAccessoryImage];
}
}
}

View file

@ -46,7 +46,7 @@
HomeFilesSearchViewController *filesSearchViewController;
MXKSearchDataSource *filesSearchDataSource;
ContactsTableViewController *contactsViewController;
ContactsTableViewController *peopleSearchViewController;
MXKContact *selectedContact;
// Display a gradient view above the screen
@ -104,9 +104,10 @@
// Add search People tab
[titles addObject: NSLocalizedStringFromTable(@"search_people", @"Vector", nil)];
contactsViewController = [ContactsTableViewController contactsTableViewController];
contactsViewController.contactsTableViewControllerDelegate = self;
[viewControllers addObject:contactsViewController];
peopleSearchViewController = [ContactsTableViewController contactsTableViewController];
peopleSearchViewController.contactsTableViewControllerDelegate = self;
peopleSearchViewController.contactCellAccessoryType = UITableViewCellAccessoryDisclosureIndicator;
[viewControllers addObject:peopleSearchViewController];
// add Files tab
[titles addObject: NSLocalizedStringFromTable(@"search_files", @"Vector", nil)];
@ -129,6 +130,7 @@
[self initializeDataSources];
self.searchBar.autocapitalizationType = UITextAutocapitalizationTypeNone;
self.searchBar.placeholder = NSLocalizedStringFromTable(@"search_default_placeholder", @"Vector", nil);
}
- (void)dealloc
@ -511,9 +513,9 @@
{
self.backgroundImageView.hidden = ((messagesSearchDataSource.serverCount != 0) || !messagesSearchViewController.noResultsLabel.isHidden || (self.keyboardHeight == 0));
}
else if (self.selectedViewController == contactsViewController)
else if (self.selectedViewController == peopleSearchViewController)
{
self.backgroundImageView.hidden = (([contactsViewController.tableView numberOfRowsInSection:0] != 0) || (self.keyboardHeight == 0));
self.backgroundImageView.hidden = (([peopleSearchViewController.tableView numberOfRowsInSection:0] != 0) || (self.keyboardHeight == 0));
}
else if (self.selectedViewController == filesSearchViewController)
{
@ -546,6 +548,15 @@
if (!self.searchBarHidden)
{
if (self.selectedViewController == peopleSearchViewController)
{
self.searchBar.placeholder = NSLocalizedStringFromTable(@"search_people_placeholder", @"Vector", nil);
}
else
{
self.searchBar.placeholder = NSLocalizedStringFromTable(@"search_default_placeholder", @"Vector", nil);
}
[self updateSearch];
}
}
@ -1108,9 +1119,9 @@
});
}
}
else if (self.selectedViewController == contactsViewController)
else if (self.selectedViewController == peopleSearchViewController)
{
[contactsViewController searchWithPattern:self.searchBar.text forceReset:NO];
[peopleSearchViewController searchWithPattern:self.searchBar.text forceReset:NO];
}
else if (self.selectedViewController == filesSearchViewController)
{
@ -1138,7 +1149,7 @@
{
[messagesSearchDataSource searchMessages:nil force:NO];
}
[contactsViewController searchWithPattern:nil forceReset:NO];
[peopleSearchViewController searchWithPattern:nil forceReset:NO];
if (filesSearchDataSource.searchText.length)
{
[filesSearchDataSource searchMessages:nil force:NO];
@ -1157,7 +1168,7 @@
// As the public room search is local, it can be updated on each text change
[self updateSearch];
}
else if (self.selectedViewController == contactsViewController)
else if (self.selectedViewController == peopleSearchViewController)
{
// As the contact search is local, it can be updated on each text change
[self updateSearch];

View file

@ -495,7 +495,7 @@
addParticipantButtonImageView.backgroundColor = [UIColor clearColor];
addParticipantButtonImageView.contentMode = UIViewContentModeCenter;
addParticipantButtonImageView.image = [UIImage imageNamed:@"create_room"];
addParticipantButtonImageView.image = [UIImage imageNamed:@"add_participant"];
CGFloat side = 78.0f;
NSLayoutConstraint* widthConstraint = [NSLayoutConstraint constraintWithItem:addParticipantButtonImageView
@ -545,12 +545,14 @@
- (void)onAddParticipantButtonPressed
{
// Push the contacts table screen.
// Push the contacts picker.
contactsPickerViewController = [ContactsTableViewController contactsTableViewController];
// Set delegate to handle action on member (start chat, mention)
contactsPickerViewController.contactsTableViewControllerDelegate = self;
contactsPickerViewController.forceMatrixIdInDisplayName = YES;
// Add a plus icon to the contact cell in the contacts picker, in order to make it more understandable for the end user.
contactsPickerViewController.contactCellAccessoryImage = [UIImage imageNamed:@"plus_icon"];
// List all the participants by their matrix user id, or a room 3pid invite token to ignore them during the contacts search.
[contactsPickerViewController.ignoredContactsByMatrixId removeAllObjects];

View file

@ -19,7 +19,7 @@
/**
'StartChatViewController' instance is used to prepare new room creation.
*/
@interface StartChatViewController : ContactsTableViewController <UISearchBarDelegate>
@interface StartChatViewController : ContactsTableViewController <UISearchBarDelegate, ContactsTableViewControllerDelegate>
@property (weak, nonatomic) IBOutlet UIView *searchBarHeader;
@property (weak, nonatomic) IBOutlet UISearchBar *searchBarView;

View file

@ -67,6 +67,13 @@
// Prepare room participants
participants = [NSMutableArray array];
// Assign itself as delegate
self.contactsTableViewControllerDelegate = self;
// Add a plus icon to the contact cell when a search session is in progress,
// in order to make it more understandable for the end user.
self.contactCellAccessoryImage = [UIImage imageNamed:@"plus_icon"];;
}
- (void)viewDidLoad
@ -269,14 +276,14 @@
{
NSInteger count = 0;
if (section == participantsSection)
{
count = participants.count + 1;
}
else
if (_isAddParticipantSearchBarEditing)
{
count = [super tableView:self.tableView numberOfRowsInSection:section];
}
else if (section == participantsSection)
{
count = participants.count + 1;
}
return count;
}
@ -285,7 +292,11 @@
{
UITableViewCell *cell;
if (indexPath.section == participantsSection)
if (_isAddParticipantSearchBarEditing)
{
cell = [super tableView:self.tableView cellForRowAtIndexPath:indexPath];
}
else if (indexPath.section == participantsSection)
{
ContactTableViewCell* participantCell = [tableView dequeueReusableCellWithIdentifier:@"ParticipantTableViewCellId" forIndexPath:indexPath];
@ -317,10 +328,6 @@
cell = participantCell;
}
else
{
cell = [super tableView:self.tableView cellForRowAtIndexPath:indexPath];
}
return cell;
}
@ -345,7 +352,7 @@
{
CGFloat height = 0.0;
if (section != participantsSection)
if (_isAddParticipantSearchBarEditing)
{
height = [super tableView:self.tableView heightForHeaderInSection:section];
}
@ -355,32 +362,15 @@
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSInteger row = indexPath.row;
MXKContact *mxkContact;
if (indexPath.section == searchInputSection)
if (_isAddParticipantSearchBarEditing)
{
mxkContact = [[MXKContact alloc] initMatrixContactWithDisplayName:currentSearchText andMatrixID:nil];
[super tableView:tableView didSelectRowAtIndexPath:indexPath];
}
else if (indexPath.section == filteredLocalContactsSection)
else
{
mxkContact = filteredLocalContacts[row];
// Do nothing
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
else if (indexPath.section == filteredMatrixContactsSection)
{
mxkContact = filteredMatrixContacts[row];
}
if (mxkContact)
{
// Update here the mutable list of participants
[participants addObject:mxkContact];
// Refresh display by leaving search session
[self searchBarCancelButtonClicked:_searchBarView];
}
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
- (NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath
@ -648,4 +638,18 @@
[searchBar resignFirstResponder];
}
#pragma mark - ContactsTableViewControllerDelegate
- (void)contactsTableViewController:(ContactsTableViewController *)contactsTableViewController didSelectContact:(MXKContact*)contact
{
if (contact)
{
// Update here the mutable list of participants
[participants addObject:contact];
}
// Refresh display by leaving search session
[self searchBarCancelButtonClicked:_searchBarView];
}
@end