From 79673b84dc1175225f938795ae5d312d1629c7d0 Mon Sep 17 00:00:00 2001 From: giomfo Date: Tue, 5 Jul 2016 00:29:35 +0200 Subject: [PATCH 01/18] BugFix: App crashes when the user leaves Settings whereas an email binding is in progress. Reported crash: [SettingsViewController showValidationEmailDialogWithMessage:for3PID:]_block_invoke190 (in Vector) (SettingsViewController.m:416). --- .../ViewController/SettingsViewController.m | 125 ++++++++++++------ 1 file changed, 84 insertions(+), 41 deletions(-) diff --git a/Vector/ViewController/SettingsViewController.m b/Vector/ViewController/SettingsViewController.m index 62d8a8e6c5..e89f006845 100644 --- a/Vector/ViewController/SettingsViewController.m +++ b/Vector/ViewController/SettingsViewController.m @@ -105,9 +105,10 @@ @interface SettingsViewController () // Observe kAppDelegateDidTapStatusBarNotification to handle tap on clock status bar. id kAppDelegateDidTapStatusBarNotificationObserver; - // Postpone destroy operation when saving or pwd reset is in progress + // Postpone destroy operation when saving, pwd reset or email binding is in progress BOOL isSavingInProgress; BOOL isResetPwdInProgress; + BOOL isEmailBindingInProgress; blockSettingsViewController_onReadyToDestroy onReadyToDestroyHandler; // @@ -181,7 +182,7 @@ - (void)didReceiveMemoryWarning - (void)destroy { - if (isSavingInProgress || isResetPwdInProgress) + if (isSavingInProgress || isResetPwdInProgress || isEmailBindingInProgress) { __weak typeof(self) weakSelf = self; onReadyToDestroyHandler = ^() { @@ -384,54 +385,96 @@ - (void)showValidationEmailDialogWithMessage:(NSString*)message for3PID:(MXK3PID currentAlert.cancelButtonIndex = [currentAlert addActionWithTitle:[NSBundle mxk_localizedStringForKey:@"abort"] style:MXKAlertActionStyleDefault handler:^(MXKAlert *alert){ - __strong __typeof(weakSelf)strongSelf = weakSelf; - strongSelf->currentAlert = nil; - - [strongSelf stopActivityIndicator]; - - // Reset new email adding - strongSelf.newEmailEditingEnabled = NO; - }]; - - __strong __typeof(threePID)strongThreePID = threePID; - - [currentAlert addActionWithTitle:[NSBundle mxk_localizedStringForKey:@"continue"] style:MXKAlertActionStyleDefault handler:^(MXKAlert *alert) { - - // We always bind emails when registering, so let's do the same here - [threePID add3PIDToUser:YES success:^{ - + if (weakSelf) + { __strong __typeof(weakSelf)strongSelf = weakSelf; strongSelf->currentAlert = nil; - + [strongSelf stopActivityIndicator]; - + // Reset new email adding strongSelf.newEmailEditingEnabled = NO; + } + + }]; - // Update linked emails - [strongSelf loadLinkedEmails]; + __strong __typeof(threePID)strongThreePID = threePID; - } failure:^(NSError *error) { + [currentAlert addActionWithTitle:[NSBundle mxk_localizedStringForKey:@"continue"] style:MXKAlertActionStyleDefault handler:^(MXKAlert *alert) { + if (weakSelf) + { __strong __typeof(weakSelf)strongSelf = weakSelf; - strongSelf->currentAlert = nil; - - NSLog(@"[SettingsViewController] Failed to bind email: %@", error); - - // Display the same popup again if the error is M_THREEPID_AUTH_FAILED - MXError *mxError = [[MXError alloc] initWithNSError:error]; - if (mxError && [mxError.errcode isEqualToString:kMXErrCodeStringThreePIDAuthFailed]) - { - [strongSelf showValidationEmailDialogWithMessage:[NSBundle mxk_localizedStringForKey:@"account_email_validation_error"] for3PID:strongThreePID]; - } - else - { - [strongSelf stopActivityIndicator]; - - // Notify MatrixKit user - [[NSNotificationCenter defaultCenter] postNotificationName:kMXKErrorNotification object:error]; - } - }]; + strongSelf->isEmailBindingInProgress = YES; + + // We always bind emails when registering, so let's do the same here + [threePID add3PIDToUser:YES success:^{ + + if (weakSelf) + { + __strong __typeof(weakSelf)strongSelf = weakSelf; + strongSelf->isEmailBindingInProgress = NO; + + // Check whether destroy has been called during email binding + if (strongSelf->onReadyToDestroyHandler) + { + // Ready to destroy + strongSelf->onReadyToDestroyHandler(); + strongSelf->onReadyToDestroyHandler = nil; + } + else + { + strongSelf->currentAlert = nil; + + [strongSelf stopActivityIndicator]; + + // Reset new email adding + strongSelf.newEmailEditingEnabled = NO; + + // Update linked emails + [strongSelf loadLinkedEmails]; + } + } + + } failure:^(NSError *error) { + + NSLog(@"[SettingsViewController] Failed to bind email: %@", error); + + if (weakSelf) + { + __strong __typeof(weakSelf)strongSelf = weakSelf; + strongSelf->isEmailBindingInProgress = NO; + + // Check whether destroy has been called during email binding + if (strongSelf->onReadyToDestroyHandler) + { + // Ready to destroy + strongSelf->onReadyToDestroyHandler(); + strongSelf->onReadyToDestroyHandler = nil; + } + else + { + strongSelf->currentAlert = nil; + + // Display the same popup again if the error is M_THREEPID_AUTH_FAILED + MXError *mxError = [[MXError alloc] initWithNSError:error]; + if (mxError && [mxError.errcode isEqualToString:kMXErrCodeStringThreePIDAuthFailed]) + { + [strongSelf showValidationEmailDialogWithMessage:[NSBundle mxk_localizedStringForKey:@"account_email_validation_error"] for3PID:strongThreePID]; + } + else + { + [strongSelf stopActivityIndicator]; + + // Notify MatrixKit user + [[NSNotificationCenter defaultCenter] postNotificationName:kMXKErrorNotification object:error]; + } + } + } + + }]; + } + }]; [currentAlert showInViewController:self]; From 4ad1981ede95f3e222c94e3f17007422e9248d73 Mon Sep 17 00:00:00 2001 From: giomfo Date: Tue, 5 Jul 2016 10:53:38 +0200 Subject: [PATCH 02/18] Messages: Add pink red badge on each invitation https://github.com/vector-im/vector-ios/issues/426 --- .../RoomList/InviteRecentTableViewCell.h | 3 +++ .../RoomList/InviteRecentTableViewCell.m | 3 +++ .../RoomList/InviteRecentTableViewCell.xib | 26 +++++++++++++++++-- 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/Vector/Views/RoomList/InviteRecentTableViewCell.h b/Vector/Views/RoomList/InviteRecentTableViewCell.h index 87977dae4a..1b4ca9d937 100644 --- a/Vector/Views/RoomList/InviteRecentTableViewCell.h +++ b/Vector/Views/RoomList/InviteRecentTableViewCell.h @@ -45,4 +45,7 @@ extern NSString *const kInviteRecentTableViewCellRoomKey; @property (weak, nonatomic) IBOutlet UIButton *leftButton; @property (weak, nonatomic) IBOutlet UIButton *rightButton; +@property (weak, nonatomic) IBOutlet UIView *noticeBadgeView; + + @end diff --git a/Vector/Views/RoomList/InviteRecentTableViewCell.m b/Vector/Views/RoomList/InviteRecentTableViewCell.m index 198d517566..342f2a8e02 100644 --- a/Vector/Views/RoomList/InviteRecentTableViewCell.m +++ b/Vector/Views/RoomList/InviteRecentTableViewCell.m @@ -52,6 +52,9 @@ - (void)awakeFromNib [self.rightButton setTitle:NSLocalizedStringFromTable(@"decline", @"Vector", nil) forState:UIControlStateHighlighted]; [self.rightButton addTarget:self action:@selector(onDeclinePressed:) forControlEvents:UIControlEventTouchUpInside]; + self.noticeBadgeView.backgroundColor = kVectorColorPinkRed; + [self.noticeBadgeView.layer setCornerRadius:10]; + self.selectionStyle = UITableViewCellSelectionStyleNone; } diff --git a/Vector/Views/RoomList/InviteRecentTableViewCell.xib b/Vector/Views/RoomList/InviteRecentTableViewCell.xib index fbd8b60208..95ca5ab1a8 100644 --- a/Vector/Views/RoomList/InviteRecentTableViewCell.xib +++ b/Vector/Views/RoomList/InviteRecentTableViewCell.xib @@ -1,8 +1,8 @@ - + - + @@ -71,12 +71,33 @@ + + + + + + + + + + + + + + + + @@ -91,6 +112,7 @@ + From 9ce530f0468a4be1b6e4b5a305c9f2114f284ee6 Mon Sep 17 00:00:00 2001 From: giomfo Date: Tue, 5 Jul 2016 16:31:07 +0200 Subject: [PATCH 03/18] Room Settings - Room tag: replace switches by check boxes Improve closed issue: https://github.com/vector-im/vector-ios/issues/218 --- Vector.xcodeproj/project.pbxproj | 20 +- .../RoomSettingsViewController.h | 3 +- .../RoomSettingsViewController.m | 176 ++++++--------- .../TableViewCellWithCheckBoxes.h | 91 ++++++++ ...itches.m => TableViewCellWithCheckBoxes.m} | 202 ++++++++++++++---- ...es.xib => TableViewCellWithCheckBoxes.xib} | 2 +- .../TableViewCell/TableViewCellWithSwitches.h | 50 ----- 7 files changed, 330 insertions(+), 214 deletions(-) create mode 100644 Vector/Views/TableViewCell/TableViewCellWithCheckBoxes.h rename Vector/Views/TableViewCell/{TableViewCellWithSwitches.m => TableViewCellWithCheckBoxes.m} (53%) rename Vector/Views/TableViewCell/{TableViewCellWithSwitches.xib => TableViewCellWithCheckBoxes.xib} (99%) delete mode 100644 Vector/Views/TableViewCell/TableViewCellWithSwitches.h diff --git a/Vector.xcodeproj/project.pbxproj b/Vector.xcodeproj/project.pbxproj index b41fa716bd..fab4b06e0b 100644 --- a/Vector.xcodeproj/project.pbxproj +++ b/Vector.xcodeproj/project.pbxproj @@ -164,8 +164,8 @@ F05641941C7DF9DE002276ED /* error@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = F05641911C7DF9DE002276ED /* error@3x.png */; }; F05895001B8B7E6600B73E85 /* RoomBubbleCellData.m in Sources */ = {isa = PBXBuildFile; fileRef = F05894FF1B8B7E6600B73E85 /* RoomBubbleCellData.m */; }; F067F2BC1CF6F0EA00F35EE8 /* third_party_licenses.html in Resources */ = {isa = PBXBuildFile; fileRef = F067F2BB1CF6F0EA00F35EE8 /* third_party_licenses.html */; }; - F072E9A01D217C2C002921AF /* TableViewCellWithSwitches.m in Sources */ = {isa = PBXBuildFile; fileRef = F072E99F1D217C2C002921AF /* TableViewCellWithSwitches.m */; }; - F072E9A21D217EA0002921AF /* TableViewCellWithSwitches.xib in Resources */ = {isa = PBXBuildFile; fileRef = F072E9A11D217EA0002921AF /* TableViewCellWithSwitches.xib */; }; + F07ECA4D1D2BB0A60060C09F /* TableViewCellWithCheckBoxes.m in Sources */ = {isa = PBXBuildFile; fileRef = F07ECA4B1D2BB0A60060C09F /* TableViewCellWithCheckBoxes.m */; }; + F07ECA4E1D2BB0A60060C09F /* TableViewCellWithCheckBoxes.xib in Resources */ = {isa = PBXBuildFile; fileRef = F07ECA4C1D2BB0A60060C09F /* TableViewCellWithCheckBoxes.xib */; }; F08BE09E1B87025B00C480FB /* EventFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = F08BE09D1B87025B00C480FB /* EventFormatter.m */; }; F08BE0A21B87064000C480FB /* RoomDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = F08BE0A11B87064000C480FB /* RoomDataSource.m */; }; F094A9A81B78D8F000B1FBBF /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = F094A9A71B78D8F000B1FBBF /* main.m */; }; @@ -466,9 +466,9 @@ F05894FE1B8B7E6600B73E85 /* RoomBubbleCellData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RoomBubbleCellData.h; sourceTree = ""; }; F05894FF1B8B7E6600B73E85 /* RoomBubbleCellData.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RoomBubbleCellData.m; sourceTree = ""; }; F067F2BB1CF6F0EA00F35EE8 /* third_party_licenses.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = third_party_licenses.html; sourceTree = ""; }; - F072E99E1D217C2C002921AF /* TableViewCellWithSwitches.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TableViewCellWithSwitches.h; path = TableViewCell/TableViewCellWithSwitches.h; sourceTree = ""; }; - F072E99F1D217C2C002921AF /* TableViewCellWithSwitches.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TableViewCellWithSwitches.m; path = TableViewCell/TableViewCellWithSwitches.m; sourceTree = ""; }; - F072E9A11D217EA0002921AF /* TableViewCellWithSwitches.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = TableViewCellWithSwitches.xib; path = TableViewCell/TableViewCellWithSwitches.xib; sourceTree = ""; }; + F07ECA4A1D2BB0A60060C09F /* TableViewCellWithCheckBoxes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TableViewCellWithCheckBoxes.h; path = TableViewCell/TableViewCellWithCheckBoxes.h; sourceTree = ""; }; + F07ECA4B1D2BB0A60060C09F /* TableViewCellWithCheckBoxes.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TableViewCellWithCheckBoxes.m; path = TableViewCell/TableViewCellWithCheckBoxes.m; sourceTree = ""; }; + F07ECA4C1D2BB0A60060C09F /* TableViewCellWithCheckBoxes.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = TableViewCellWithCheckBoxes.xib; path = TableViewCell/TableViewCellWithCheckBoxes.xib; sourceTree = ""; }; F08BE09C1B87025B00C480FB /* EventFormatter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EventFormatter.h; sourceTree = ""; }; F08BE09D1B87025B00C480FB /* EventFormatter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EventFormatter.m; sourceTree = ""; }; F08BE0A01B87064000C480FB /* RoomDataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RoomDataSource.h; sourceTree = ""; }; @@ -660,12 +660,12 @@ 7179283B1C0384DE00407D96 /* TableViewCell */ = { isa = PBXGroup; children = ( + F07ECA4A1D2BB0A60060C09F /* TableViewCellWithCheckBoxes.h */, + F07ECA4B1D2BB0A60060C09F /* TableViewCellWithCheckBoxes.m */, + F07ECA4C1D2BB0A60060C09F /* TableViewCellWithCheckBoxes.xib */, F0B7037B1D22D4AD00B63766 /* TableViewCellWithTickAndLabel.h */, F0B7037C1D22D4AD00B63766 /* TableViewCellWithTickAndLabel.m */, F0B7037D1D22D4AD00B63766 /* TableViewCellWithTickAndLabel.xib */, - F072E99E1D217C2C002921AF /* TableViewCellWithSwitches.h */, - F072E99F1D217C2C002921AF /* TableViewCellWithSwitches.m */, - F072E9A11D217EA0002921AF /* TableViewCellWithSwitches.xib */, F05641781C7C9FD7002276ED /* TableViewCellWithButton.h */, F05641791C7C9FD7002276ED /* TableViewCellWithButton.m */, F056417A1C7C9FD7002276ED /* TableViewCellWithButton.xib */, @@ -1434,10 +1434,10 @@ F0026B521C916E68001D2C04 /* favouriteOff.png in Resources */, 32A887221C89B9580037DC17 /* SimpleRoomTitleView.xib in Resources */, F02528FD1C11B6FC00E1FE1B /* selection_untick.png in Resources */, + F07ECA4E1D2BB0A60060C09F /* TableViewCellWithCheckBoxes.xib in Resources */, F0026B5C1C916E68001D2C04 /* notificationsOff@2x.png in Resources */, F0CC4DC11C4E26FA003BBE45 /* MediaAlbumTableCell.xib in Resources */, F02528DD1C11B6FC00E1FE1B /* camera_switch@2x.png in Resources */, - F072E9A21D217EA0002921AF /* TableViewCellWithSwitches.xib in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1508,7 +1508,6 @@ F094A9AB1B78D8F000B1FBBF /* AppDelegate.m in Sources */, 32C52BF61CBE4B0A00863B33 /* RoomEmailInvitation.m in Sources */, F047DBB91C576F6600952DA2 /* AuthInputsView.m in Sources */, - F072E9A01D217C2C002921AF /* TableViewCellWithSwitches.m in Sources */, 323A520B1C3183CC00010773 /* UIViewController+VectorSearch.m in Sources */, 32A887211C89B9580037DC17 /* SimpleRoomTitleView.m in Sources */, F056417B1C7C9FD7002276ED /* TableViewCellWithButton.m in Sources */, @@ -1569,6 +1568,7 @@ F0C34CB31C16269D00C36F09 /* RoomIncomingTextMsgWithPaginationTitleBubbleCell.m in Sources */, F0D2D9851C197DCB007B8C96 /* RoomIncomingAttachmentWithoutSenderInfoBubbleCell.m in Sources */, 71046D5E1C0C639300DCA984 /* RoomTitleView.m in Sources */, + F07ECA4D1D2BB0A60060C09F /* TableViewCellWithCheckBoxes.m in Sources */, F02BB04B1CBE2EE70022A025 /* PreviewRoomTitleView.m in Sources */, F0C34B631C15C28300C36F09 /* RoomOutgoingAttachmentWithoutSenderInfoBubbleCell.m in Sources */, F09EE0061C5134BE0078712F /* RoomOutgoingTextMsgWithoutSenderNameBubbleCell.m in Sources */, diff --git a/Vector/ViewController/RoomSettingsViewController.h b/Vector/ViewController/RoomSettingsViewController.h index a2f407baf6..981517bc1a 100644 --- a/Vector/ViewController/RoomSettingsViewController.h +++ b/Vector/ViewController/RoomSettingsViewController.h @@ -17,8 +17,9 @@ #import #import "MediaPickerViewController.h" +#import "TableViewCellWithCheckBoxes.h" -@interface RoomSettingsViewController : MXKRoomSettingsViewController +@interface RoomSettingsViewController : MXKRoomSettingsViewController @end diff --git a/Vector/ViewController/RoomSettingsViewController.m b/Vector/ViewController/RoomSettingsViewController.m index 4e18a7d42c..06efc5bcf5 100644 --- a/Vector/ViewController/RoomSettingsViewController.m +++ b/Vector/ViewController/RoomSettingsViewController.m @@ -17,7 +17,6 @@ #import "RoomSettingsViewController.h" #import "TableViewCellWithLabelAndLargeTextView.h" -#import "TableViewCellWithSwitches.h" #import "TableViewCellWithTickAndLabel.h" #import "SegmentedViewController.h" @@ -77,8 +76,9 @@ @interface RoomSettingsViewController () // The current table items UITextField* nameTextField; UITextView* topicTextView; - UISwitch *favouriteTagSwitch; - UISwitch *lowPriorityTagSwitch; + + // The room tag items + TableViewCellWithCheckBoxes *roomTagCell; // Room Access items TableViewCellWithTickAndLabel *accessInvitedOnlyTickCell; @@ -148,7 +148,7 @@ - (void)viewDidLoad [self.tableView registerClass:MXKTableViewCellWithLabelAndMXKImageView.class forCellReuseIdentifier:[MXKTableViewCellWithLabelAndMXKImageView defaultReuseIdentifier]]; [self.tableView registerClass:TableViewCellWithLabelAndLargeTextView.class forCellReuseIdentifier:[TableViewCellWithLabelAndLargeTextView defaultReuseIdentifier]]; [self.tableView registerClass:MXKTableViewCellWithLabelAndTextField.class forCellReuseIdentifier:[MXKTableViewCellWithLabelAndTextField defaultReuseIdentifier]]; - [self.tableView registerClass:TableViewCellWithSwitches.class forCellReuseIdentifier:[TableViewCellWithSwitches defaultReuseIdentifier]]; + [self.tableView registerClass:TableViewCellWithCheckBoxes.class forCellReuseIdentifier:[TableViewCellWithCheckBoxes defaultReuseIdentifier]]; [self.tableView registerClass:TableViewCellWithTickAndLabel.class forCellReuseIdentifier:[TableViewCellWithTickAndLabel defaultReuseIdentifier]]; [self setNavBarButtons]; @@ -1076,22 +1076,18 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N } else if (row == ROOM_SETTINGS_MAIN_SECTION_ROW_TAG) { - TableViewCellWithSwitches *tagCell = [tableView dequeueReusableCellWithIdentifier:[TableViewCellWithSwitches defaultReuseIdentifier] forIndexPath:indexPath]; - - tagCell.switchesNumber = 2; + roomTagCell = [tableView dequeueReusableCellWithIdentifier:[TableViewCellWithCheckBoxes defaultReuseIdentifier] forIndexPath:indexPath]; - favouriteTagSwitch = tagCell.switches[0]; - [favouriteTagSwitch addTarget:self action:@selector(onSwitchUpdate:) forControlEvents:UIControlEventValueChanged]; - favouriteTagSwitch.onTintColor = kVectorColorGreen; + roomTagCell.checkboxesNumber = 2; - lowPriorityTagSwitch = tagCell.switches[1]; - [lowPriorityTagSwitch addTarget:self action:@selector(onSwitchUpdate:) forControlEvents:UIControlEventValueChanged]; - lowPriorityTagSwitch.onTintColor = kVectorColorGreen; + roomTagCell.allowsMultipleSelection = NO; + roomTagCell.delegate = self; + NSArray *labels = roomTagCell.labels; UILabel *label; - label = tagCell.labels[0]; + label = labels[0]; label.text = NSLocalizedStringFromTable(@"room_details_favourite_tag", @"Vector", nil); - label = tagCell.labels[1]; + label = labels[1]; label.text = NSLocalizedStringFromTable(@"room_details_low_priority_tag", @"Vector", nil); if ([updatedItemsDict objectForKey:kRoomSettingsTagKey]) @@ -1099,27 +1095,26 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N NSString *roomTag = [updatedItemsDict objectForKey:kRoomSettingsTagKey]; if ([roomTag isEqualToString:kMXRoomTagFavourite]) { - favouriteTagSwitch.on = YES; - lowPriorityTagSwitch.on = NO; + [roomTagCell setCheckBoxValue:YES atIndex:0]; } else if ([roomTag isEqualToString:kMXRoomTagLowPriority]) { - favouriteTagSwitch.on = NO; - lowPriorityTagSwitch.on = YES; - } - else - { - favouriteTagSwitch.on = NO; - lowPriorityTagSwitch.on = NO; + [roomTagCell setCheckBoxValue:YES atIndex:1]; } } else { - favouriteTagSwitch.on = (mxRoom.accountData.tags[kMXRoomTagFavourite] != 0); - lowPriorityTagSwitch.on = (mxRoom.accountData.tags[kMXRoomTagLowPriority] != 0); + if (mxRoom.accountData.tags[kMXRoomTagFavourite] != nil) + { + [roomTagCell setCheckBoxValue:YES atIndex:0]; + } + else if (mxRoom.accountData.tags[kMXRoomTagLowPriority] != nil) + { + [roomTagCell setCheckBoxValue:YES atIndex:1]; + } } - cell = tagCell; + cell = roomTagCell; } } else if (indexPath.section == ROOM_SETTINGS_ROOM_ACCESS_SECTION_INDEX) @@ -1669,75 +1664,60 @@ - (void)onRoomAvatarTap:(UITapGestureRecognizer *)recognizer - (void)onSwitchUpdate:(UISwitch*)theSwitch { - if (theSwitch == favouriteTagSwitch) + if (theSwitch == roomNotifSwitch) { - if (favouriteTagSwitch.on) + if (roomNotifSwitch.on == mxRoom.isMute) { - // Check the actual tag on mxRoom - if (mxRoom.accountData.tags[kMXRoomTagFavourite]) - { - [updatedItemsDict removeObjectForKey:kRoomSettingsTagKey]; - } - else - { - [updatedItemsDict setObject:kMXRoomTagFavourite forKey:kRoomSettingsTagKey]; - } - - // Force off the low priority toggle - lowPriorityTagSwitch.on = NO; + [updatedItemsDict removeObjectForKey:kRoomSettingsMuteNotifKey]; } else { - // Retrieve the current change on room tag (if any) - NSString *updatedRoomTag = [updatedItemsDict objectForKey:kRoomSettingsTagKey]; - - // Check the actual tag on mxRoom - if (mxRoom.accountData.tags[kMXRoomTagFavourite]) - { - // The actual tag must be updated, check whether another tag is already set - if (!updatedRoomTag) - { - [updatedItemsDict setObject:@"" forKey:kRoomSettingsTagKey]; - } - } - else if (updatedRoomTag && [updatedRoomTag isEqualToString:kMXRoomTagFavourite]) - { - // Cancel the updated tag, but take into account the cancellation of the another tag (low priority) when favourite was selected - if (mxRoom.accountData.tags[kMXRoomTagLowPriority]) - { - [updatedItemsDict setObject:@"" forKey:kRoomSettingsTagKey]; - } - else - { - [updatedItemsDict removeObjectForKey:kRoomSettingsTagKey]; - } - } + [updatedItemsDict setObject:[NSNumber numberWithBool:roomNotifSwitch.on] forKey:kRoomSettingsMuteNotifKey]; } } - else if (theSwitch == lowPriorityTagSwitch) + else if (theSwitch == directoryVisibilitySwitch) { - if (lowPriorityTagSwitch.on) + MXRoomDirectoryVisibility visibility = directoryVisibilitySwitch.on ? kMXRoomDirectoryVisibilityPublic : kMXRoomDirectoryVisibilityPrivate; + + // Check whether the actual settings has been retrieved + if (actualDirectoryVisibility) { - // Check the actual tag on mxRoom - if (mxRoom.accountData.tags[kMXRoomTagLowPriority]) + if ([visibility isEqualToString:actualDirectoryVisibility]) { - [updatedItemsDict removeObjectForKey:kRoomSettingsTagKey]; + [updatedItemsDict removeObjectForKey:kRoomSettingsDirectoryKey]; } else { - [updatedItemsDict setObject:kMXRoomTagLowPriority forKey:kRoomSettingsTagKey]; + [updatedItemsDict setObject:visibility forKey:kRoomSettingsDirectoryKey]; } - - // Force off the favourite toggle - favouriteTagSwitch.on = NO; } else { + [updatedItemsDict setObject:visibility forKey:kRoomSettingsDirectoryKey]; + } + } + + + [self getNavigationItem].rightBarButtonItem.enabled = (updatedItemsDict.count != 0); +} + +#pragma mark - TableViewCellWithCheckBoxesDelegate + +- (void)tableViewCellWithCheckBoxes:(TableViewCellWithCheckBoxes *)tableViewCellWithCheckBoxes didTapOnCheckBoxAtIndex:(NSUInteger)index +{ + if (tableViewCellWithCheckBoxes == roomTagCell) + { + NSString *tappedRoomTag = (index == 0) ? kMXRoomTagFavourite : kMXRoomTagLowPriority; + BOOL isCurrentlySelected = [roomTagCell checkBoxValueAtIndex:index]; + + if (isCurrentlySelected) + { + // The user wants to unselect this tag // Retrieve the current change on room tag (if any) NSString *updatedRoomTag = [updatedItemsDict objectForKey:kRoomSettingsTagKey]; // Check the actual tag on mxRoom - if (mxRoom.accountData.tags[kMXRoomTagLowPriority]) + if (mxRoom.accountData.tags[tappedRoomTag]) { // The actual tag must be updated, check whether another tag is already set if (!updatedRoomTag) @@ -1745,10 +1725,10 @@ - (void)onSwitchUpdate:(UISwitch*)theSwitch [updatedItemsDict setObject:@"" forKey:kRoomSettingsTagKey]; } } - else if (updatedRoomTag && [updatedRoomTag isEqualToString:kMXRoomTagLowPriority]) + else if (updatedRoomTag && [updatedRoomTag isEqualToString:tappedRoomTag]) { - // Cancel the updated tag, but take into account the cancellation of the another tag (favourite) when low priority was selected - if (mxRoom.accountData.tags[kMXRoomTagFavourite]) + // Cancel the updated tag, but take into account the cancellation of another tag when 'tappedRoomTag' was selected. + if (mxRoom.accountData.tags.count) { [updatedItemsDict setObject:@"" forKey:kRoomSettingsTagKey]; } @@ -1757,43 +1737,29 @@ - (void)onSwitchUpdate:(UISwitch*)theSwitch [updatedItemsDict removeObjectForKey:kRoomSettingsTagKey]; } } - } - } - else if (theSwitch == roomNotifSwitch) - { - if (roomNotifSwitch.on == mxRoom.isMute) - { - [updatedItemsDict removeObjectForKey:kRoomSettingsMuteNotifKey]; + + // Unselect the tag + [roomTagCell setCheckBoxValue:NO atIndex:index]; } else { - [updatedItemsDict setObject:[NSNumber numberWithBool:roomNotifSwitch.on] forKey:kRoomSettingsMuteNotifKey]; - } - } - else if (theSwitch == directoryVisibilitySwitch) - { - MXRoomDirectoryVisibility visibility = directoryVisibilitySwitch.on ? kMXRoomDirectoryVisibilityPublic : kMXRoomDirectoryVisibilityPrivate; - - // Check whether the actual settings has been retrieved - if (actualDirectoryVisibility) - { - if ([visibility isEqualToString:actualDirectoryVisibility]) + // The user wants to select this room tag + // Check the actual tag on mxRoom + if (mxRoom.accountData.tags[tappedRoomTag]) { - [updatedItemsDict removeObjectForKey:kRoomSettingsDirectoryKey]; + [updatedItemsDict removeObjectForKey:kRoomSettingsTagKey]; } else { - [updatedItemsDict setObject:visibility forKey:kRoomSettingsDirectoryKey]; + [updatedItemsDict setObject:tappedRoomTag forKey:kRoomSettingsTagKey]; } + + // Select the tapped tag + [roomTagCell setCheckBoxValue:YES atIndex:index]; } - else - { - [updatedItemsDict setObject:visibility forKey:kRoomSettingsDirectoryKey]; - } + + [self getNavigationItem].rightBarButtonItem.enabled = (updatedItemsDict.count != 0); } - - - [self getNavigationItem].rightBarButtonItem.enabled = (updatedItemsDict.count != 0); } @end diff --git a/Vector/Views/TableViewCell/TableViewCellWithCheckBoxes.h b/Vector/Views/TableViewCell/TableViewCellWithCheckBoxes.h new file mode 100644 index 0000000000..9049d44066 --- /dev/null +++ b/Vector/Views/TableViewCell/TableViewCellWithCheckBoxes.h @@ -0,0 +1,91 @@ +/* + Copyright 2016 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 "MXKTableViewCell.h" + +@class TableViewCellWithCheckBoxes; + +/** + `TableViewCellWithCheckBoxes` delegate. + */ +@protocol TableViewCellWithCheckBoxesDelegate + +/** + Tells the delegate that the user taps on a check box. + + @param tableViewCellWithCheckBoxes the `TableViewCellWithCheckBoxes` instance. + @param index the index of the concerned check box. + */ +- (void)tableViewCellWithCheckBoxes:(TableViewCellWithCheckBoxes *)tableViewCellWithCheckBoxes didTapOnCheckBoxAtIndex:(NSUInteger)index; + +@end + +/** + 'TableViewCellWithCheckBoxes' inherits 'MXKTableViewCell' class. + It displays several options in a UITableViewCell. Each option has its own check box and its label. + All option have the same width and they are horizontally aligned inside the main container. + They are vertically centered. + */ +@interface TableViewCellWithCheckBoxes : MXKTableViewCell + +@property (weak, nonatomic) IBOutlet UIView *mainContainer; + +/** + The number of boxes + */ +@property (nonatomic) NSUInteger checkboxesNumber; + +/** + The current array of checkboxes + */ +@property (nonatomic, readonly) NSArray *checkboxes; + +/** + The current array of labels + */ +@property (nonatomic, readonly) NSArray *labels; + +/** + Leading/Trailing constraints define here spacing to nearest neighbor (no relative to margin) + */ +@property (weak, nonatomic) IBOutlet NSLayoutConstraint *mainContainerLeadingConstraint; +@property (weak, nonatomic) IBOutlet NSLayoutConstraint *mainContainerTrailingConstraint; + +/** + The delegate for the cell. + */ +@property (nonatomic, weak) id delegate; + +/** + Default is NO. Controls whether multiple check boxes can be selected simultaneously + */ +@property (nonatomic) BOOL allowsMultipleSelection; + +/** + Select or unselect a check box. + If multiple selection is not allowed, this method unselect the current selected box in case of a new selection. + + @param isSelected the new value of the check box. + @param index the index of the check box. + */ +- (void)setCheckBoxValue:(BOOL)isSelected atIndex:(NSUInteger)index; + +/** + Get the current state of a check box + */ +- (BOOL)checkBoxValueAtIndex:(NSUInteger)index; + +@end \ No newline at end of file diff --git a/Vector/Views/TableViewCell/TableViewCellWithSwitches.m b/Vector/Views/TableViewCell/TableViewCellWithCheckBoxes.m similarity index 53% rename from Vector/Views/TableViewCell/TableViewCellWithSwitches.m rename to Vector/Views/TableViewCell/TableViewCellWithCheckBoxes.m index 63ad150dce..1a1ac3d9f1 100644 --- a/Vector/Views/TableViewCell/TableViewCellWithSwitches.m +++ b/Vector/Views/TableViewCell/TableViewCellWithCheckBoxes.m @@ -14,23 +14,23 @@ limitations under the License. */ -#import "TableViewCellWithSwitches.h" +#import "TableViewCellWithCheckBoxes.h" -// The space between 2 switches -#define TABLEVIEWCELLWITHSWITCHES_MARGIN 8 +// The space between 2 check boxes +#define TABLEVIEWCELLWITHCHECKBOXES_MARGIN 8 -@interface TableViewCellWithSwitches () +@interface TableViewCellWithCheckBoxes () { - NSMutableArray *switchArray; + NSMutableArray *checkboxesArray; NSMutableArray *labelArray; } @end -@implementation TableViewCellWithSwitches +@implementation TableViewCellWithCheckBoxes -- (void)setSwitchesNumber:(NSUInteger)switchesNumber +- (void)setCheckboxesNumber:(NSUInteger)checkboxesNumber { - if (_switchesNumber == switchesNumber) + if (_checkboxesNumber == checkboxesNumber) { return; } @@ -42,58 +42,58 @@ - (void)setSwitchesNumber:(NSUInteger)switchesNumber [view removeFromSuperview]; } - _switchesNumber = switchesNumber; + _checkboxesNumber = checkboxesNumber; - if (!switchesNumber) + if (!_checkboxesNumber) { // Nothing to do return; } - switchArray = [NSMutableArray arrayWithCapacity:switchesNumber]; - labelArray = [NSMutableArray arrayWithCapacity:switchesNumber]; + checkboxesArray = [NSMutableArray arrayWithCapacity:checkboxesNumber]; + labelArray = [NSMutableArray arrayWithCapacity:checkboxesNumber]; - CGFloat containerWidth = (self.mainContainer.frame.size.width - ((switchesNumber - 1.0) * TABLEVIEWCELLWITHSWITCHES_MARGIN)) / switchesNumber; + CGFloat containerWidth = (self.mainContainer.frame.size.width - ((checkboxesNumber - 1.0) * TABLEVIEWCELLWITHCHECKBOXES_MARGIN)) / checkboxesNumber; UIView *previousContainer = nil; NSLayoutConstraint *topConstraint, *leftConstraint, *bottomConstraint; - NSLayoutConstraint *widthConstraint, *centerYConstraint; + NSLayoutConstraint *widthConstraint, *heightConstraint, *centerYConstraint, *centerXConstraint; - for (NSInteger index = 0; index < switchesNumber; index++) + for (NSInteger index = 0; index < checkboxesNumber; index++) { - UIView *switchContainer = [[UIView alloc] initWithFrame:CGRectMake(index * (containerWidth + TABLEVIEWCELLWITHSWITCHES_MARGIN), 0, containerWidth, self.mainContainer.frame.size.height)]; - switchContainer.backgroundColor = [UIColor clearColor]; - [self.mainContainer addSubview:switchContainer]; + UIView *checkboxContainer = [[UIView alloc] initWithFrame:CGRectMake(index * (containerWidth + TABLEVIEWCELLWITHCHECKBOXES_MARGIN), 0, containerWidth, self.mainContainer.frame.size.height)]; + checkboxContainer.backgroundColor = [UIColor clearColor]; + [self.mainContainer addSubview:checkboxContainer]; // Add container constraints - switchContainer.translatesAutoresizingMaskIntoConstraints = NO; + checkboxContainer.translatesAutoresizingMaskIntoConstraints = NO; if (!previousContainer) { - leftConstraint = [NSLayoutConstraint constraintWithItem:switchContainer + leftConstraint = [NSLayoutConstraint constraintWithItem:checkboxContainer attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self.mainContainer attribute:NSLayoutAttributeLeading multiplier:1 constant:0]; - widthConstraint = [NSLayoutConstraint constraintWithItem:switchContainer + widthConstraint = [NSLayoutConstraint constraintWithItem:checkboxContainer attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:self.mainContainer attribute:NSLayoutAttributeWidth - multiplier:(1.0 / switchesNumber) - constant:(- ((switchesNumber - 1.0) * TABLEVIEWCELLWITHSWITCHES_MARGIN) / switchesNumber)]; + multiplier:(1.0 / checkboxesNumber) + constant:(- ((checkboxesNumber - 1.0) * TABLEVIEWCELLWITHCHECKBOXES_MARGIN) / checkboxesNumber)]; } else { - leftConstraint = [NSLayoutConstraint constraintWithItem:switchContainer + leftConstraint = [NSLayoutConstraint constraintWithItem:checkboxContainer attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:previousContainer attribute:NSLayoutAttributeTrailing multiplier:1 - constant:TABLEVIEWCELLWITHSWITCHES_MARGIN]; - widthConstraint = [NSLayoutConstraint constraintWithItem:switchContainer + constant:TABLEVIEWCELLWITHCHECKBOXES_MARGIN]; + widthConstraint = [NSLayoutConstraint constraintWithItem:checkboxContainer attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:previousContainer @@ -102,7 +102,7 @@ - (void)setSwitchesNumber:(NSUInteger)switchesNumber constant:0]; } - topConstraint = [NSLayoutConstraint constraintWithItem:switchContainer + topConstraint = [NSLayoutConstraint constraintWithItem:checkboxContainer attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.mainContainer @@ -110,7 +110,7 @@ - (void)setSwitchesNumber:(NSUInteger)switchesNumber multiplier:1 constant:0]; - bottomConstraint = [NSLayoutConstraint constraintWithItem:switchContainer + bottomConstraint = [NSLayoutConstraint constraintWithItem:checkboxContainer attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.mainContainer @@ -120,40 +120,56 @@ - (void)setSwitchesNumber:(NSUInteger)switchesNumber [NSLayoutConstraint activateConstraints:@[leftConstraint, widthConstraint, topConstraint, bottomConstraint]]; - previousContainer = switchContainer; + previousContainer = checkboxContainer; - // Add Switch and Label - UISwitch *theSwitch = [[UISwitch alloc] initWithFrame:CGRectMake(0, 0, 51, 31)]; - theSwitch.translatesAutoresizingMaskIntoConstraints = NO; - [switchContainer addSubview:theSwitch]; - [switchArray addObject:theSwitch]; + // Add Checkbox and Label + UIImageView *checkbox = [[UIImageView alloc] initWithFrame:CGRectMake(14, 11, 22, 22)]; + checkbox.translatesAutoresizingMaskIntoConstraints = NO; + [checkboxContainer addSubview:checkbox]; + + // Store the new check box unselected by default + checkbox.image = [UIImage imageNamed:@"selection_untick"]; + checkbox.tag = 0; + [checkboxesArray addObject:checkbox]; UILabel *theLabel = [[UILabel alloc] initWithFrame:CGRectMake(60, 0, containerWidth - 60, 31)]; theLabel.translatesAutoresizingMaskIntoConstraints = NO; - [switchContainer addSubview:theLabel]; + [checkboxContainer addSubview:theLabel]; [labelArray addObject:theLabel]; + UIView *checkboxMask = [[UIView alloc] initWithFrame:CGRectMake(7, 4, 36, 36)]; + checkboxMask.translatesAutoresizingMaskIntoConstraints = NO; + [checkboxContainer addSubview:checkboxMask]; + // Listen to check box tap + checkboxMask.tag = index; + checkboxMask.userInteractionEnabled = YES; + UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onCheckBoxTap:)]; + [tapGesture setNumberOfTouchesRequired:1]; + [tapGesture setNumberOfTapsRequired:1]; + [tapGesture setDelegate:self]; + [checkboxMask addGestureRecognizer:tapGesture]; + // Add switch constraints - leftConstraint = [NSLayoutConstraint constraintWithItem:theSwitch + leftConstraint = [NSLayoutConstraint constraintWithItem:checkbox attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual - toItem:switchContainer + toItem:checkboxContainer attribute:NSLayoutAttributeLeading multiplier:1 - constant:0]; + constant:14]; - widthConstraint = [NSLayoutConstraint constraintWithItem:theSwitch + widthConstraint = [NSLayoutConstraint constraintWithItem:checkbox attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 - constant:51]; + constant:22]; - centerYConstraint = [NSLayoutConstraint constraintWithItem:theSwitch + centerYConstraint = [NSLayoutConstraint constraintWithItem:checkbox attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual - toItem:switchContainer + toItem:checkboxContainer attribute:NSLayoutAttributeCenterY multiplier:1 constant:0.0f]; @@ -165,7 +181,7 @@ - (void)setSwitchesNumber:(NSUInteger)switchesNumber topConstraint = [NSLayoutConstraint constraintWithItem:theLabel attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual - toItem:switchContainer + toItem:checkboxContainer attribute:NSLayoutAttributeTop multiplier:1 constant:0]; @@ -173,7 +189,7 @@ - (void)setSwitchesNumber:(NSUInteger)switchesNumber leftConstraint = [NSLayoutConstraint constraintWithItem:theLabel attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual - toItem:theSwitch + toItem:checkbox attribute:NSLayoutAttributeTrailing multiplier:1 constant:9]; @@ -181,18 +197,53 @@ - (void)setSwitchesNumber:(NSUInteger)switchesNumber centerYConstraint = [NSLayoutConstraint constraintWithItem:theLabel attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual - toItem:switchContainer + toItem:checkboxContainer attribute:NSLayoutAttributeCenterY multiplier:1 constant:0.0f]; [NSLayoutConstraint activateConstraints:@[topConstraint, leftConstraint, centerYConstraint]]; + + // Add check box mask constraints + widthConstraint = [NSLayoutConstraint constraintWithItem:checkboxMask + attribute:NSLayoutAttributeWidth + relatedBy:NSLayoutRelationEqual + toItem:nil + attribute:NSLayoutAttributeNotAnAttribute + multiplier:1 + constant:36]; + + heightConstraint = [NSLayoutConstraint constraintWithItem:checkboxMask + attribute:NSLayoutAttributeHeight + relatedBy:NSLayoutRelationEqual + toItem:nil + attribute:NSLayoutAttributeNotAnAttribute + multiplier:1 + constant:36]; + + centerXConstraint = [NSLayoutConstraint constraintWithItem:checkboxMask + attribute:NSLayoutAttributeCenterX + relatedBy:NSLayoutRelationEqual + toItem:checkbox + attribute:NSLayoutAttributeCenterX + multiplier:1 + constant:0.0f]; + + centerYConstraint = [NSLayoutConstraint constraintWithItem:checkboxMask + attribute:NSLayoutAttributeCenterY + relatedBy:NSLayoutRelationEqual + toItem:checkbox + attribute:NSLayoutAttributeCenterY + multiplier:1 + constant:0.0f]; + + [NSLayoutConstraint activateConstraints:@[widthConstraint, heightConstraint, centerXConstraint, centerYConstraint]]; } } -- (NSArray*)switches +- (NSArray*)checkboxes { - return [NSArray arrayWithArray:switchArray]; + return [NSArray arrayWithArray:checkboxesArray]; } - (NSArray*)labels @@ -200,5 +251,62 @@ - (NSArray*)labels return [NSArray arrayWithArray:labelArray]; } +- (void)setCheckBoxValue:(BOOL)isSelected atIndex:(NSUInteger)index +{ + if (index < checkboxesArray.count) + { + UIImageView *checkBox = checkboxesArray[index]; + + if (isSelected && !checkBox.tag) + { + checkBox.image = [UIImage imageNamed:@"selection_tick"]; + checkBox.tag = 1; + + if (!self.allowsMultipleSelection) + { + // Unselect others check boxes + for (NSUInteger k = 0; k < checkboxesArray.count; k++) + { + if (k != index) + { + checkBox = checkboxesArray[k]; + if (checkBox.tag) + { + checkBox.image = [UIImage imageNamed:@"selection_untick"]; + checkBox.tag = 0; + } + } + } + } + } + else if (checkBox.tag) + { + checkBox.image = [UIImage imageNamed:@"selection_untick"]; + checkBox.tag = 0; + } + } +} + +- (BOOL)checkBoxValueAtIndex:(NSUInteger)index +{ + if (index < checkboxesArray.count) + { + UIImageView *checkBox = checkboxesArray[index]; + + return ((BOOL)checkBox.tag); + } + + return NO; +} + +#pragma mark - Action + +- (IBAction)onCheckBoxTap:(UITapGestureRecognizer*)sender +{ + if (_delegate) + { + [_delegate tableViewCellWithCheckBoxes:self didTapOnCheckBoxAtIndex:sender.view.tag]; + } +} @end diff --git a/Vector/Views/TableViewCell/TableViewCellWithSwitches.xib b/Vector/Views/TableViewCell/TableViewCellWithCheckBoxes.xib similarity index 99% rename from Vector/Views/TableViewCell/TableViewCellWithSwitches.xib rename to Vector/Views/TableViewCell/TableViewCellWithCheckBoxes.xib index 29b6440762..c5bb3c9693 100644 --- a/Vector/Views/TableViewCell/TableViewCellWithSwitches.xib +++ b/Vector/Views/TableViewCell/TableViewCellWithCheckBoxes.xib @@ -7,7 +7,7 @@ - + diff --git a/Vector/Views/TableViewCell/TableViewCellWithSwitches.h b/Vector/Views/TableViewCell/TableViewCellWithSwitches.h deleted file mode 100644 index 672a5a41b2..0000000000 --- a/Vector/Views/TableViewCell/TableViewCellWithSwitches.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - Copyright 2016 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 "MXKTableViewCell.h" - -/** - 'TableViewCellWithSwitches' inherits 'MXKTableViewCell' class. - It displays several switches in a UITableViewCell. Each switch has its own label. - All switches have the same width and they are horizontally aligned inside the main container. - They are vertically centered. - */ -@interface TableViewCellWithSwitches : MXKTableViewCell - -@property (weak, nonatomic) IBOutlet UIView *mainContainer; - -/** - The number of switches - */ -@property (nonatomic) NSUInteger switchesNumber; - -/** - The current array of switches - */ -@property (nonatomic, readonly) NSArray *switches; - -/** - The current array of labels - */ -@property (nonatomic, readonly) NSArray *labels; - -/** - Leading/Trailing constraints define here spacing to nearest neighbor (no relative to margin) - */ -@property (weak, nonatomic) IBOutlet NSLayoutConstraint *mainContainerLeadingConstraint; -@property (weak, nonatomic) IBOutlet NSLayoutConstraint *mainContainerTrailingConstraint; - -@end \ No newline at end of file From d7cc4f29a04205f13e04607c9ee96ec1a4c246d4 Mon Sep 17 00:00:00 2001 From: giomfo Date: Tue, 5 Jul 2016 17:26:55 +0200 Subject: [PATCH 04/18] Rename TableViewCellWithTickAndLabel with TableViewCellWithCheckBoxAndLabel --- Vector.xcodeproj/project.pbxproj | 20 +++++----- .../RoomSettingsViewController.m | 22 +++++----- ....h => TableViewCellWithCheckBoxAndLabel.h} | 4 +- ....m => TableViewCellWithCheckBoxAndLabel.m} | 8 ++-- ... => TableViewCellWithCheckBoxAndLabel.xib} | 4 +- .../TableViewCellWithCheckBoxes.h | 6 +-- .../TableViewCellWithCheckBoxes.m | 40 +++++++++---------- 7 files changed, 52 insertions(+), 52 deletions(-) rename Vector/Views/TableViewCell/{TableViewCellWithTickAndLabel.h => TableViewCellWithCheckBoxAndLabel.h} (85%) rename Vector/Views/TableViewCell/{TableViewCellWithTickAndLabel.m => TableViewCellWithCheckBoxAndLabel.m} (75%) rename Vector/Views/TableViewCell/{TableViewCellWithTickAndLabel.xib => TableViewCellWithCheckBoxAndLabel.xib} (96%) diff --git a/Vector.xcodeproj/project.pbxproj b/Vector.xcodeproj/project.pbxproj index fab4b06e0b..2c772f8045 100644 --- a/Vector.xcodeproj/project.pbxproj +++ b/Vector.xcodeproj/project.pbxproj @@ -200,8 +200,8 @@ F0A2413A1CB7E28F00E150C3 /* RoomParticipantsViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = F0A241391CB7E28F00E150C3 /* RoomParticipantsViewController.xib */; }; F0AF11F51D1029CF00FEE52F /* RoomIdOrAliasTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = F0AF11F31D1029CF00FEE52F /* RoomIdOrAliasTableViewCell.m */; }; F0AF11F61D1029CF00FEE52F /* RoomIdOrAliasTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = F0AF11F41D1029CF00FEE52F /* RoomIdOrAliasTableViewCell.xib */; }; - F0B7037E1D22D4AD00B63766 /* TableViewCellWithTickAndLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = F0B7037C1D22D4AD00B63766 /* TableViewCellWithTickAndLabel.m */; }; - F0B7037F1D22D4AD00B63766 /* TableViewCellWithTickAndLabel.xib in Resources */ = {isa = PBXBuildFile; fileRef = F0B7037D1D22D4AD00B63766 /* TableViewCellWithTickAndLabel.xib */; }; + F0B7037E1D22D4AD00B63766 /* TableViewCellWithCheckBoxAndLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = F0B7037C1D22D4AD00B63766 /* TableViewCellWithCheckBoxAndLabel.m */; }; + F0B7037F1D22D4AD00B63766 /* TableViewCellWithCheckBoxAndLabel.xib in Resources */ = {isa = PBXBuildFile; fileRef = F0B7037D1D22D4AD00B63766 /* TableViewCellWithCheckBoxAndLabel.xib */; }; F0BE3DF01C6CE17200AC3111 /* RoomMemberDetailsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F0BE3DEF1C6CE17200AC3111 /* RoomMemberDetailsViewController.m */; }; F0BE3DF21C6CE28300AC3111 /* RoomMemberDetailsViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = F0BE3DF11C6CE28300AC3111 /* RoomMemberDetailsViewController.xib */; }; F0C34B611C15C28300C36F09 /* RoomOutgoingAttachmentBubbleCell.m in Sources */ = {isa = PBXBuildFile; fileRef = F0C34B561C15C28300C36F09 /* RoomOutgoingAttachmentBubbleCell.m */; }; @@ -523,9 +523,9 @@ F0AF11F21D1029CF00FEE52F /* RoomIdOrAliasTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RoomIdOrAliasTableViewCell.h; sourceTree = ""; }; F0AF11F31D1029CF00FEE52F /* RoomIdOrAliasTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RoomIdOrAliasTableViewCell.m; sourceTree = ""; }; F0AF11F41D1029CF00FEE52F /* RoomIdOrAliasTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = RoomIdOrAliasTableViewCell.xib; sourceTree = ""; }; - F0B7037B1D22D4AD00B63766 /* TableViewCellWithTickAndLabel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TableViewCellWithTickAndLabel.h; path = TableViewCell/TableViewCellWithTickAndLabel.h; sourceTree = ""; }; - F0B7037C1D22D4AD00B63766 /* TableViewCellWithTickAndLabel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TableViewCellWithTickAndLabel.m; path = TableViewCell/TableViewCellWithTickAndLabel.m; sourceTree = ""; }; - F0B7037D1D22D4AD00B63766 /* TableViewCellWithTickAndLabel.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = TableViewCellWithTickAndLabel.xib; path = TableViewCell/TableViewCellWithTickAndLabel.xib; sourceTree = ""; }; + F0B7037B1D22D4AD00B63766 /* TableViewCellWithCheckBoxAndLabel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TableViewCellWithCheckBoxAndLabel.h; path = TableViewCell/TableViewCellWithCheckBoxAndLabel.h; sourceTree = ""; }; + F0B7037C1D22D4AD00B63766 /* TableViewCellWithCheckBoxAndLabel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TableViewCellWithCheckBoxAndLabel.m; path = TableViewCell/TableViewCellWithCheckBoxAndLabel.m; sourceTree = ""; }; + F0B7037D1D22D4AD00B63766 /* TableViewCellWithCheckBoxAndLabel.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = TableViewCellWithCheckBoxAndLabel.xib; path = TableViewCell/TableViewCellWithCheckBoxAndLabel.xib; sourceTree = ""; }; F0BE3DEE1C6CE17200AC3111 /* RoomMemberDetailsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RoomMemberDetailsViewController.h; sourceTree = ""; }; F0BE3DEF1C6CE17200AC3111 /* RoomMemberDetailsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RoomMemberDetailsViewController.m; sourceTree = ""; }; F0BE3DF11C6CE28300AC3111 /* RoomMemberDetailsViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = RoomMemberDetailsViewController.xib; sourceTree = ""; }; @@ -663,9 +663,9 @@ F07ECA4A1D2BB0A60060C09F /* TableViewCellWithCheckBoxes.h */, F07ECA4B1D2BB0A60060C09F /* TableViewCellWithCheckBoxes.m */, F07ECA4C1D2BB0A60060C09F /* TableViewCellWithCheckBoxes.xib */, - F0B7037B1D22D4AD00B63766 /* TableViewCellWithTickAndLabel.h */, - F0B7037C1D22D4AD00B63766 /* TableViewCellWithTickAndLabel.m */, - F0B7037D1D22D4AD00B63766 /* TableViewCellWithTickAndLabel.xib */, + F0B7037B1D22D4AD00B63766 /* TableViewCellWithCheckBoxAndLabel.h */, + F0B7037C1D22D4AD00B63766 /* TableViewCellWithCheckBoxAndLabel.m */, + F0B7037D1D22D4AD00B63766 /* TableViewCellWithCheckBoxAndLabel.xib */, F05641781C7C9FD7002276ED /* TableViewCellWithButton.h */, F05641791C7C9FD7002276ED /* TableViewCellWithButton.m */, F056417A1C7C9FD7002276ED /* TableViewCellWithButton.xib */, @@ -1282,7 +1282,7 @@ F008D6FC1D0180FB0049444D /* GoogleService-Info.plist in Resources */, F02528E01C11B6FC00E1FE1B /* create_room.png in Resources */, F02528DF1C11B6FC00E1FE1B /* camera_video.png in Resources */, - F0B7037F1D22D4AD00B63766 /* TableViewCellWithTickAndLabel.xib in Resources */, + F0B7037F1D22D4AD00B63766 /* TableViewCellWithCheckBoxAndLabel.xib in Resources */, F02BB04C1CBE2EE70022A025 /* PreviewRoomTitleView.xib in Resources */, F056418C1C7CBEBD002276ED /* group.png in Resources */, F0C34B681C15C28300C36F09 /* RoomOutgoingTextMsgWithoutSenderInfoBubbleCell.xib in Resources */, @@ -1541,7 +1541,7 @@ F094A9A81B78D8F000B1FBBF /* main.m in Sources */, F00C47861BFF77C800DBABC9 /* RecentTableViewCell.m in Sources */, F0CC4DCA1C4E594C003BBE45 /* MediaAlbumContentViewController.m in Sources */, - F0B7037E1D22D4AD00B63766 /* TableViewCellWithTickAndLabel.m in Sources */, + F0B7037E1D22D4AD00B63766 /* TableViewCellWithCheckBoxAndLabel.m in Sources */, 32AAC3E61C3525DE007A3B5B /* RoomSearchViewController.m in Sources */, 32F2E61B1C230D4D003BDEA5 /* PublicRoomsDirectoryDataSource.m in Sources */, 3235CD851C341FAA0084EA40 /* HomeSearchViewController.m in Sources */, diff --git a/Vector/ViewController/RoomSettingsViewController.m b/Vector/ViewController/RoomSettingsViewController.m index 06efc5bcf5..28f8ca74ab 100644 --- a/Vector/ViewController/RoomSettingsViewController.m +++ b/Vector/ViewController/RoomSettingsViewController.m @@ -17,7 +17,7 @@ #import "RoomSettingsViewController.h" #import "TableViewCellWithLabelAndLargeTextView.h" -#import "TableViewCellWithTickAndLabel.h" +#import "TableViewCellWithCheckBoxAndLabel.h" #import "SegmentedViewController.h" @@ -81,14 +81,14 @@ @interface RoomSettingsViewController () TableViewCellWithCheckBoxes *roomTagCell; // Room Access items - TableViewCellWithTickAndLabel *accessInvitedOnlyTickCell; - TableViewCellWithTickAndLabel *accessAnyoneApartGuestTickCell; - TableViewCellWithTickAndLabel *accessAnyoneTickCell; + TableViewCellWithCheckBoxAndLabel *accessInvitedOnlyTickCell; + TableViewCellWithCheckBoxAndLabel *accessAnyoneApartGuestTickCell; + TableViewCellWithCheckBoxAndLabel *accessAnyoneTickCell; UISwitch *directoryVisibilitySwitch; MXRoomDirectoryVisibility actualDirectoryVisibility; // History Visibility items - NSMutableDictionary *historyVisibilityTickCells; + NSMutableDictionary *historyVisibilityTickCells; // The potential image loader MXKMediaLoader *uploader; @@ -149,7 +149,7 @@ - (void)viewDidLoad [self.tableView registerClass:TableViewCellWithLabelAndLargeTextView.class forCellReuseIdentifier:[TableViewCellWithLabelAndLargeTextView defaultReuseIdentifier]]; [self.tableView registerClass:MXKTableViewCellWithLabelAndTextField.class forCellReuseIdentifier:[MXKTableViewCellWithLabelAndTextField defaultReuseIdentifier]]; [self.tableView registerClass:TableViewCellWithCheckBoxes.class forCellReuseIdentifier:[TableViewCellWithCheckBoxes defaultReuseIdentifier]]; - [self.tableView registerClass:TableViewCellWithTickAndLabel.class forCellReuseIdentifier:[TableViewCellWithTickAndLabel defaultReuseIdentifier]]; + [self.tableView registerClass:TableViewCellWithCheckBoxAndLabel.class forCellReuseIdentifier:[TableViewCellWithCheckBoxAndLabel defaultReuseIdentifier]]; [self setNavBarButtons]; } @@ -1078,7 +1078,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N { roomTagCell = [tableView dequeueReusableCellWithIdentifier:[TableViewCellWithCheckBoxes defaultReuseIdentifier] forIndexPath:indexPath]; - roomTagCell.checkboxesNumber = 2; + roomTagCell.checkBoxesNumber = 2; roomTagCell.allowsMultipleSelection = NO; roomTagCell.delegate = self; @@ -1195,7 +1195,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N } else { - TableViewCellWithTickAndLabel *roomAccessCell = [tableView dequeueReusableCellWithIdentifier:[TableViewCellWithTickAndLabel defaultReuseIdentifier] forIndexPath:indexPath]; + TableViewCellWithCheckBoxAndLabel *roomAccessCell = [tableView dequeueReusableCellWithIdentifier:[TableViewCellWithCheckBoxAndLabel defaultReuseIdentifier] forIndexPath:indexPath]; if (indexPath.row == ROOM_SETTINGS_ROOM_ACCESS_SECTION_ROW_INVITED_ONLY) { @@ -1277,7 +1277,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N } else if (indexPath.section == ROOM_SETTINGS_HISTORY_VISIBILITY_SECTION_INDEX) { - TableViewCellWithTickAndLabel *historyVisibilityCell = [tableView dequeueReusableCellWithIdentifier:[TableViewCellWithTickAndLabel defaultReuseIdentifier] forIndexPath:indexPath]; + TableViewCellWithCheckBoxAndLabel *historyVisibilityCell = [tableView dequeueReusableCellWithIdentifier:[TableViewCellWithCheckBoxAndLabel defaultReuseIdentifier] forIndexPath:indexPath]; if (indexPath.row == ROOM_SETTINGS_HISTORY_VISIBILITY_SECTION_ROW_ANYONE) { @@ -1521,7 +1521,7 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath else if (indexPath.section == ROOM_SETTINGS_HISTORY_VISIBILITY_SECTION_INDEX) { // Ignore the selection if the option is already enabled - TableViewCellWithTickAndLabel *selectedCell = [self.tableView cellForRowAtIndexPath:indexPath]; + TableViewCellWithCheckBoxAndLabel *selectedCell = [self.tableView cellForRowAtIndexPath:indexPath]; if (! selectedCell.isEnabled) { MXRoomHistoryVisibility historyVisibility; @@ -1595,7 +1595,7 @@ - (void)changeHistoryVisibility:(MXRoomHistoryVisibility)historyVisibility { // Disable all history visibility options NSArray *tickCells = historyVisibilityTickCells.allValues; - for (TableViewCellWithTickAndLabel *historyVisibilityTickCell in tickCells) + for (TableViewCellWithCheckBoxAndLabel *historyVisibilityTickCell in tickCells) { historyVisibilityTickCell.enabled = NO; } diff --git a/Vector/Views/TableViewCell/TableViewCellWithTickAndLabel.h b/Vector/Views/TableViewCell/TableViewCellWithCheckBoxAndLabel.h similarity index 85% rename from Vector/Views/TableViewCell/TableViewCellWithTickAndLabel.h rename to Vector/Views/TableViewCell/TableViewCellWithCheckBoxAndLabel.h index 03e294c6b5..e3338008a0 100644 --- a/Vector/Views/TableViewCell/TableViewCellWithTickAndLabel.h +++ b/Vector/Views/TableViewCell/TableViewCellWithCheckBoxAndLabel.h @@ -16,9 +16,9 @@ #import "MXKTableViewCell.h" -@interface TableViewCellWithTickAndLabel : MXKTableViewCell +@interface TableViewCellWithCheckBoxAndLabel : MXKTableViewCell -@property (strong, nonatomic) IBOutlet UIImageView *tick; +@property (strong, nonatomic) IBOutlet UIImageView *checkBox; @property (strong, nonatomic) IBOutlet UILabel *label; @property (nonatomic, getter=isEnabled) BOOL enabled; diff --git a/Vector/Views/TableViewCell/TableViewCellWithTickAndLabel.m b/Vector/Views/TableViewCell/TableViewCellWithCheckBoxAndLabel.m similarity index 75% rename from Vector/Views/TableViewCell/TableViewCellWithTickAndLabel.m rename to Vector/Views/TableViewCell/TableViewCellWithCheckBoxAndLabel.m index 2386b4cbfb..7387fe4cc4 100644 --- a/Vector/Views/TableViewCell/TableViewCellWithTickAndLabel.m +++ b/Vector/Views/TableViewCell/TableViewCellWithCheckBoxAndLabel.m @@ -14,19 +14,19 @@ limitations under the License. */ -#import "TableViewCellWithTickAndLabel.h" +#import "TableViewCellWithCheckBoxAndLabel.h" -@implementation TableViewCellWithTickAndLabel +@implementation TableViewCellWithCheckBoxAndLabel - (void)setEnabled:(BOOL)enabled { if (enabled) { - _tick.image = [UIImage imageNamed:@"selection_tick"]; + _checkBox.image = [UIImage imageNamed:@"selection_tick"]; } else { - _tick.image = [UIImage imageNamed:@"selection_untick"]; + _checkBox.image = [UIImage imageNamed:@"selection_untick"]; } _enabled = enabled; diff --git a/Vector/Views/TableViewCell/TableViewCellWithTickAndLabel.xib b/Vector/Views/TableViewCell/TableViewCellWithCheckBoxAndLabel.xib similarity index 96% rename from Vector/Views/TableViewCell/TableViewCellWithTickAndLabel.xib rename to Vector/Views/TableViewCell/TableViewCellWithCheckBoxAndLabel.xib index 2bf709e1fc..5cf36be251 100644 --- a/Vector/Views/TableViewCell/TableViewCellWithTickAndLabel.xib +++ b/Vector/Views/TableViewCell/TableViewCellWithCheckBoxAndLabel.xib @@ -7,7 +7,7 @@ - + @@ -37,8 +37,8 @@ + - diff --git a/Vector/Views/TableViewCell/TableViewCellWithCheckBoxes.h b/Vector/Views/TableViewCell/TableViewCellWithCheckBoxes.h index 9049d44066..598f622edb 100644 --- a/Vector/Views/TableViewCell/TableViewCellWithCheckBoxes.h +++ b/Vector/Views/TableViewCell/TableViewCellWithCheckBoxes.h @@ -46,12 +46,12 @@ /** The number of boxes */ -@property (nonatomic) NSUInteger checkboxesNumber; +@property (nonatomic) NSUInteger checkBoxesNumber; /** - The current array of checkboxes + The current array of checkBoxes */ -@property (nonatomic, readonly) NSArray *checkboxes; +@property (nonatomic, readonly) NSArray *checkBoxes; /** The current array of labels diff --git a/Vector/Views/TableViewCell/TableViewCellWithCheckBoxes.m b/Vector/Views/TableViewCell/TableViewCellWithCheckBoxes.m index 1a1ac3d9f1..e030932962 100644 --- a/Vector/Views/TableViewCell/TableViewCellWithCheckBoxes.m +++ b/Vector/Views/TableViewCell/TableViewCellWithCheckBoxes.m @@ -21,16 +21,16 @@ @interface TableViewCellWithCheckBoxes () { - NSMutableArray *checkboxesArray; + NSMutableArray *checkBoxesArray; NSMutableArray *labelArray; } @end @implementation TableViewCellWithCheckBoxes -- (void)setCheckboxesNumber:(NSUInteger)checkboxesNumber +- (void)setCheckBoxesNumber:(NSUInteger)checkBoxesNumber { - if (_checkboxesNumber == checkboxesNumber) + if (_checkBoxesNumber == checkBoxesNumber) { return; } @@ -42,24 +42,24 @@ - (void)setCheckboxesNumber:(NSUInteger)checkboxesNumber [view removeFromSuperview]; } - _checkboxesNumber = checkboxesNumber; + _checkBoxesNumber = checkBoxesNumber; - if (!_checkboxesNumber) + if (!_checkBoxesNumber) { // Nothing to do return; } - checkboxesArray = [NSMutableArray arrayWithCapacity:checkboxesNumber]; - labelArray = [NSMutableArray arrayWithCapacity:checkboxesNumber]; + checkBoxesArray = [NSMutableArray arrayWithCapacity:checkBoxesNumber]; + labelArray = [NSMutableArray arrayWithCapacity:checkBoxesNumber]; - CGFloat containerWidth = (self.mainContainer.frame.size.width - ((checkboxesNumber - 1.0) * TABLEVIEWCELLWITHCHECKBOXES_MARGIN)) / checkboxesNumber; + CGFloat containerWidth = (self.mainContainer.frame.size.width - ((checkBoxesNumber - 1.0) * TABLEVIEWCELLWITHCHECKBOXES_MARGIN)) / checkBoxesNumber; UIView *previousContainer = nil; NSLayoutConstraint *topConstraint, *leftConstraint, *bottomConstraint; NSLayoutConstraint *widthConstraint, *heightConstraint, *centerYConstraint, *centerXConstraint; - for (NSInteger index = 0; index < checkboxesNumber; index++) + for (NSInteger index = 0; index < checkBoxesNumber; index++) { UIView *checkboxContainer = [[UIView alloc] initWithFrame:CGRectMake(index * (containerWidth + TABLEVIEWCELLWITHCHECKBOXES_MARGIN), 0, containerWidth, self.mainContainer.frame.size.height)]; checkboxContainer.backgroundColor = [UIColor clearColor]; @@ -81,8 +81,8 @@ - (void)setCheckboxesNumber:(NSUInteger)checkboxesNumber relatedBy:NSLayoutRelationEqual toItem:self.mainContainer attribute:NSLayoutAttributeWidth - multiplier:(1.0 / checkboxesNumber) - constant:(- ((checkboxesNumber - 1.0) * TABLEVIEWCELLWITHCHECKBOXES_MARGIN) / checkboxesNumber)]; + multiplier:(1.0 / checkBoxesNumber) + constant:(- ((checkBoxesNumber - 1.0) * TABLEVIEWCELLWITHCHECKBOXES_MARGIN) / checkBoxesNumber)]; } else { @@ -130,7 +130,7 @@ - (void)setCheckboxesNumber:(NSUInteger)checkboxesNumber // Store the new check box unselected by default checkbox.image = [UIImage imageNamed:@"selection_untick"]; checkbox.tag = 0; - [checkboxesArray addObject:checkbox]; + [checkBoxesArray addObject:checkbox]; UILabel *theLabel = [[UILabel alloc] initWithFrame:CGRectMake(60, 0, containerWidth - 60, 31)]; theLabel.translatesAutoresizingMaskIntoConstraints = NO; @@ -241,9 +241,9 @@ - (void)setCheckboxesNumber:(NSUInteger)checkboxesNumber } } -- (NSArray*)checkboxes +- (NSArray*)checkBoxes { - return [NSArray arrayWithArray:checkboxesArray]; + return [NSArray arrayWithArray:checkBoxesArray]; } - (NSArray*)labels @@ -253,9 +253,9 @@ - (NSArray*)labels - (void)setCheckBoxValue:(BOOL)isSelected atIndex:(NSUInteger)index { - if (index < checkboxesArray.count) + if (index < checkBoxesArray.count) { - UIImageView *checkBox = checkboxesArray[index]; + UIImageView *checkBox = checkBoxesArray[index]; if (isSelected && !checkBox.tag) { @@ -265,11 +265,11 @@ - (void)setCheckBoxValue:(BOOL)isSelected atIndex:(NSUInteger)index if (!self.allowsMultipleSelection) { // Unselect others check boxes - for (NSUInteger k = 0; k < checkboxesArray.count; k++) + for (NSUInteger k = 0; k < checkBoxesArray.count; k++) { if (k != index) { - checkBox = checkboxesArray[k]; + checkBox = checkBoxesArray[k]; if (checkBox.tag) { checkBox.image = [UIImage imageNamed:@"selection_untick"]; @@ -289,9 +289,9 @@ - (void)setCheckBoxValue:(BOOL)isSelected atIndex:(NSUInteger)index - (BOOL)checkBoxValueAtIndex:(NSUInteger)index { - if (index < checkboxesArray.count) + if (index < checkBoxesArray.count) { - UIImageView *checkBox = checkboxesArray[index]; + UIImageView *checkBox = checkBoxesArray[index]; return ((BOOL)checkBox.tag); } From 0027c2829986af9a2a5caa0706ca305929acbf5d Mon Sep 17 00:00:00 2001 From: giomfo Date: Tue, 5 Jul 2016 17:57:33 +0200 Subject: [PATCH 05/18] Enhancement: Add 'leave' button to room settings https://github.com/vector-im/vector-ios/issues/417 --- Vector/Assets/en.lproj/Vector.strings | 4 +- .../RoomSettingsViewController.m | 74 ++++++++++++++++++- 2 files changed, 74 insertions(+), 4 deletions(-) diff --git a/Vector/Assets/en.lproj/Vector.strings b/Vector/Assets/en.lproj/Vector.strings index a631eb1482..18e80ff9e4 100644 --- a/Vector/Assets/en.lproj/Vector.strings +++ b/Vector/Assets/en.lproj/Vector.strings @@ -116,8 +116,8 @@ "room_participants_add_participant" = "Add participant"; "room_participants_one_participant" = "1 participant"; "room_participants_multi_participants" = "%d participants"; -"room_participants_leave_prompt_title" = "Leave?"; -"room_participants_leave_prompt_msg" = "Are you sure you want to leave this chat?"; +"room_participants_leave_prompt_title" = "Leave room"; +"room_participants_leave_prompt_msg" = "Are you sure you want to leave the room?"; "room_participants_remove_prompt_title" = "Remove?"; "room_participants_remove_prompt_msg" = "Are you sure you want to remove %@ from this chat?"; "room_participants_invite_prompt_title" = "Invite?"; diff --git a/Vector/ViewController/RoomSettingsViewController.m b/Vector/ViewController/RoomSettingsViewController.m index 28f8ca74ab..b90d0f1503 100644 --- a/Vector/ViewController/RoomSettingsViewController.m +++ b/Vector/ViewController/RoomSettingsViewController.m @@ -41,7 +41,8 @@ #define ROOM_SETTINGS_MAIN_SECTION_ROW_TOPIC 2 #define ROOM_SETTINGS_MAIN_SECTION_ROW_TAG 3 #define ROOM_SETTINGS_MAIN_SECTION_ROW_MUTE_NOTIFICATIONS 4 -#define ROOM_SETTINGS_MAIN_SECTION_ROW_COUNT 5 +#define ROOM_SETTINGS_MAIN_SECTION_ROW_LEAVE 5 +#define ROOM_SETTINGS_MAIN_SECTION_ROW_COUNT 6 #define ROOM_SETTINGS_ROOM_ACCESS_SECTION_ROW_INVITED_ONLY 0 #define ROOM_SETTINGS_ROOM_ACCESS_SECTION_ROW_ANYONE_APART_FROM_GUEST 1 @@ -148,6 +149,7 @@ - (void)viewDidLoad [self.tableView registerClass:MXKTableViewCellWithLabelAndMXKImageView.class forCellReuseIdentifier:[MXKTableViewCellWithLabelAndMXKImageView defaultReuseIdentifier]]; [self.tableView registerClass:TableViewCellWithLabelAndLargeTextView.class forCellReuseIdentifier:[TableViewCellWithLabelAndLargeTextView defaultReuseIdentifier]]; [self.tableView registerClass:MXKTableViewCellWithLabelAndTextField.class forCellReuseIdentifier:[MXKTableViewCellWithLabelAndTextField defaultReuseIdentifier]]; + [self.tableView registerClass:MXKTableViewCellWithButton.class forCellReuseIdentifier:[MXKTableViewCellWithButton defaultReuseIdentifier]]; [self.tableView registerClass:TableViewCellWithCheckBoxes.class forCellReuseIdentifier:[TableViewCellWithCheckBoxes defaultReuseIdentifier]]; [self.tableView registerClass:TableViewCellWithCheckBoxAndLabel.class forCellReuseIdentifier:[TableViewCellWithCheckBoxAndLabel defaultReuseIdentifier]]; @@ -970,7 +972,6 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N roomNotifSwitch.on = mxRoom.isMute; } - [roomNotifCell layoutIfNeeded]; cell = roomNotifCell; } else if (row == ROOM_SETTINGS_MAIN_SECTION_ROW_PHOTO) @@ -1116,6 +1117,22 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N cell = roomTagCell; } + else if (row == ROOM_SETTINGS_MAIN_SECTION_ROW_LEAVE) + { + MXKTableViewCellWithButton *leaveCell = [tableView dequeueReusableCellWithIdentifier:[MXKTableViewCellWithButton defaultReuseIdentifier] forIndexPath:indexPath]; + + NSString* title = NSLocalizedStringFromTable(@"leave", @"Vector", nil); + + [leaveCell.mxkButton setTitle:title forState:UIControlStateNormal]; + [leaveCell.mxkButton setTitle:title forState:UIControlStateHighlighted]; + [leaveCell.mxkButton setTintColor:kVectorColorGreen]; + leaveCell.mxkButton.titleLabel.font = [UIFont boldSystemFontOfSize:16]; + + [leaveCell.mxkButton removeTarget:self action:nil forControlEvents:UIControlEventTouchUpInside]; + [leaveCell.mxkButton addTarget:self action:@selector(onLeave:) forControlEvents:UIControlEventTouchUpInside]; + + cell = leaveCell; + } } else if (indexPath.section == ROOM_SETTINGS_ROOM_ACCESS_SECTION_INDEX) { @@ -1651,6 +1668,59 @@ - (void)mediaPickerController:(MediaPickerViewController *)mediaPickerController #pragma mark - actions +- (void)onLeave:(id)sender +{ + // Prompt user before leaving the room + __weak typeof(self) weakSelf = self; + + [currentAlert dismiss:NO]; + + + currentAlert = [[MXKAlert alloc] initWithTitle:NSLocalizedStringFromTable(@"room_participants_leave_prompt_title", @"Vector", nil) + message:NSLocalizedStringFromTable(@"room_participants_leave_prompt_msg", @"Vector", nil) + style:MXKAlertStyleAlert]; + + currentAlert.cancelButtonIndex = [currentAlert addActionWithTitle:[NSBundle mxk_localizedStringForKey:@"cancel"] + style:MXKAlertActionStyleCancel + handler:^(MXKAlert *alert) { + + if (weakSelf) + { + __strong __typeof(weakSelf)strongSelf = weakSelf; + strongSelf->currentAlert = nil; + } + }]; + + [currentAlert addActionWithTitle:NSLocalizedStringFromTable(@"leave", @"Vector", nil) + style:MXKAlertActionStyleDefault + handler:^(MXKAlert *alert) { + + if (weakSelf) + { + __strong __typeof(weakSelf)strongSelf = weakSelf; + strongSelf->currentAlert = nil; + + [strongSelf startActivityIndicator]; + [strongSelf->mxRoom leave:^{ + + [strongSelf withdrawViewControllerAnimated:YES completion:nil]; + + } failure:^(NSError *error) { + + [strongSelf stopActivityIndicator]; + + NSLog(@"[RoomSettingsViewController] Leave room failed"); + // Alert user + [[AppDelegate theDelegate] showErrorAsAlert:error]; + + }]; + } + + }]; + + [currentAlert showInViewController:self]; +} + - (void)onRoomAvatarTap:(UITapGestureRecognizer *)recognizer { mediaPicker = [MediaPickerViewController mediaPickerViewController]; From 85c10ffebcc74d82b217b89d9ecfac36c272757c Mon Sep 17 00:00:00 2001 From: giomfo Date: Wed, 6 Jul 2016 09:38:38 +0200 Subject: [PATCH 06/18] BugFix - Room Settings: check room permissions and grey out those boxes (disable) if you can't change them https://github.com/vector-im/vector-ios/issues/430 --- Vector/ViewController/RoomSettingsViewController.m | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/Vector/ViewController/RoomSettingsViewController.m b/Vector/ViewController/RoomSettingsViewController.m index b90d0f1503..1fa081f021 100644 --- a/Vector/ViewController/RoomSettingsViewController.m +++ b/Vector/ViewController/RoomSettingsViewController.m @@ -1208,6 +1208,9 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N }]; } + // Check whether the user can change this option + directoryVisibilitySwitch.enabled = (oneSelfPowerLevel >= powerLevels.stateDefault); + cell = directoryToggleCell; } else @@ -1288,9 +1291,12 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N accessAnyoneTickCell = roomAccessCell; } + // Check whether the user can change this option + roomAccessCell.userInteractionEnabled = (oneSelfPowerLevel >= [powerLevels minimumPowerLevelForSendingEventAsStateEvent:kMXEventTypeStringRoomJoinRules]); + roomAccessCell.checkBox.alpha = roomAccessCell.userInteractionEnabled ? 1.0f : 0.5f; + cell = roomAccessCell; } - } else if (indexPath.section == ROOM_SETTINGS_HISTORY_VISIBILITY_SECTION_INDEX) { @@ -1389,6 +1395,10 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N [historyVisibilityTickCells setObject:historyVisibilityCell forKey:kMXRoomHistoryVisibilityJoined]; } + // Check whether the user can change this option + historyVisibilityCell.userInteractionEnabled = (oneSelfPowerLevel >= [powerLevels minimumPowerLevelForSendingEventAsStateEvent:kMXEventTypeStringRoomHistoryVisibility]); + historyVisibilityCell.checkBox.alpha = historyVisibilityCell.userInteractionEnabled ? 1.0f : 0.5f; + cell = historyVisibilityCell; } From c400452abc6340b75a698a84555ee47063a54f36 Mon Sep 17 00:00:00 2001 From: giomfo Date: Fri, 8 Jul 2016 14:51:50 +0200 Subject: [PATCH 07/18] Bug Fix - Room Participants: The swipe to Leave/Kick is broken. --- .../RoomParticipantsViewController.m | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/Vector/ViewController/RoomParticipantsViewController.m b/Vector/ViewController/RoomParticipantsViewController.m index a8604da221..bbc4c59903 100644 --- a/Vector/ViewController/RoomParticipantsViewController.m +++ b/Vector/ViewController/RoomParticipantsViewController.m @@ -974,6 +974,15 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N return participantCell; } +- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath +{ + if (indexPath.section == participantsSection || indexPath.section == invitedSection) + { + return YES; + } + return NO; +} + - (void)tableView:(UITableView*)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath*)indexPath { // iOS8 requires this method to enable editing (see editActionsForRowAtIndexPath). @@ -1114,20 +1123,21 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath - (NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath { - NSMutableArray* actions = [[NSMutableArray alloc] init]; + NSMutableArray* actions; // add the swipe to delete only on participants sections if (indexPath.section == participantsSection || indexPath.section == invitedSection) { - NSString* title = @" "; + actions = [[NSMutableArray alloc] init]; - UITableViewRowAction *leaveAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDestructive title:title handler:^(UITableViewRowAction *action, NSIndexPath *indexPath){ + // Patch: Force the width of the button by adding whitespace characters into the title string. + UITableViewRowAction *leaveAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDestructive title:@" " handler:^(UITableViewRowAction *action, NSIndexPath *indexPath){ [self onDeleteAt:indexPath]; }]; - leaveAction.backgroundColor = [MXKTools convertImageToPatternColor:@"remove_icon" backgroundColor:kVectorColorLightGrey patternSize:CGSizeMake(74, 74) resourceSize:CGSizeMake(30, 30)]; + leaveAction.backgroundColor = [MXKTools convertImageToPatternColor:@"remove_icon" backgroundColor:kVectorColorLightGrey patternSize:CGSizeMake(74, 74) resourceSize:CGSizeMake(25, 24)]; [actions insertObject:leaveAction atIndex:0]; } From 894d753e744005e503049efde6aeb33d6a714565 Mon Sep 17 00:00:00 2001 From: giomfo Date: Fri, 8 Jul 2016 15:02:09 +0200 Subject: [PATCH 08/18] Settings: Set the right label text color (Vector TextColor Black) --- Vector/ViewController/SettingsViewController.m | 12 ++++++++++++ .../TableViewCellWithCheckBoxAndLabel.m | 9 +++++++++ .../TableViewCell/TableViewCellWithCheckBoxes.m | 3 +++ .../TableViewCellWithLabelAndLargeTextView.m | 4 ++++ 4 files changed, 28 insertions(+) diff --git a/Vector/ViewController/SettingsViewController.m b/Vector/ViewController/SettingsViewController.m index e89f006845..88fd0a3ab3 100644 --- a/Vector/ViewController/SettingsViewController.m +++ b/Vector/ViewController/SettingsViewController.m @@ -573,6 +573,8 @@ - (MXKTableViewCellWithLabelAndTextField*)getLabelAndTextFieldCell:(UITableView* cell.mxkTextFieldTrailingConstraint.constant = 15; } + cell.mxkLabel.textColor = kVectorTextColorBlack; + cell.mxkTextField.userInteractionEnabled = YES; cell.mxkTextField.borderStyle = UITextBorderStyleNone; cell.mxkTextField.textAlignment = NSTextAlignmentRight; @@ -601,6 +603,8 @@ - (MXKTableViewCellWithLabelAndSwitch*)getLabelAndSwitchCell:(UITableView*)table cell.mxkSwitchTrailingConstraint.constant = 15; } + cell.mxkLabel.textColor = kVectorTextColorBlack; + return cell; } @@ -668,6 +672,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N } profileCell.mxkLabel.text = NSLocalizedStringFromTable(@"settings_profile_picture", @"Vector", nil); + profileCell.mxkLabel.textColor = kVectorTextColorBlack; // if the user defines a new avatar if (newAvatarImage) @@ -911,6 +916,8 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N configCell.textLabel.text =[NSString stringWithFormat:configFormat, account.mxCredentials.userId, account.mxCredentials.homeServer, account.identityServerURL]; configCell.textLabel.numberOfLines = 0; + configCell.textLabel.textColor = kVectorTextColorBlack; + cell = configCell; } else if (section == SETTINGS_SECTION_OTHER_INDEX) @@ -928,6 +935,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N NSString* build = [AppDelegate theDelegate].build; versionCell.textLabel.text = [NSString stringWithFormat:NSLocalizedStringFromTable(@"settings_version", @"Vector", nil), [NSString stringWithFormat:@"%@ %@", appVersion, build]]; + versionCell.textLabel.textColor = kVectorTextColorBlack; cell = versionCell; } @@ -941,6 +949,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N } termAndConditionCell.textLabel.text = NSLocalizedStringFromTable(@"settings_term_conditions", @"Vector", nil); + termAndConditionCell.textLabel.textColor = kVectorTextColorBlack; cell = termAndConditionCell; } @@ -954,6 +963,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N } privacyPolicyCell.textLabel.text = NSLocalizedStringFromTable(@"settings_privacy_policy", @"Vector", nil); + privacyPolicyCell.textLabel.textColor = kVectorTextColorBlack; cell = privacyPolicyCell; } @@ -967,6 +977,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N } thirdPartyCell.textLabel.text = NSLocalizedStringFromTable(@"settings_third_party_notices", @"Vector", nil); + thirdPartyCell.textLabel.textColor = kVectorTextColorBlack; cell = thirdPartyCell; } @@ -992,6 +1003,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N NSString *btnTitle = [NSString stringWithFormat:@"%@", NSLocalizedStringFromTable(@"settings_clear_cache", @"Vector", nil)]; [clearCacheBtnCell.mxkButton setTitle:btnTitle forState:UIControlStateNormal]; [clearCacheBtnCell.mxkButton setTitle:btnTitle forState:UIControlStateHighlighted]; + [clearCacheBtnCell.mxkButton setTintColor:kVectorColorGreen]; [clearCacheBtnCell.mxkButton removeTarget:self action:nil forControlEvents:UIControlEventTouchUpInside]; [clearCacheBtnCell.mxkButton addTarget:self action:@selector(onClearCache:) forControlEvents:UIControlEventTouchUpInside]; diff --git a/Vector/Views/TableViewCell/TableViewCellWithCheckBoxAndLabel.m b/Vector/Views/TableViewCell/TableViewCellWithCheckBoxAndLabel.m index 7387fe4cc4..25bb01eeda 100644 --- a/Vector/Views/TableViewCell/TableViewCellWithCheckBoxAndLabel.m +++ b/Vector/Views/TableViewCell/TableViewCellWithCheckBoxAndLabel.m @@ -16,8 +16,17 @@ #import "TableViewCellWithCheckBoxAndLabel.h" +#import "VectorDesignValues.h" + @implementation TableViewCellWithCheckBoxAndLabel +- (void)awakeFromNib +{ + [super awakeFromNib]; + + _label.textColor = kVectorTextColorBlack; +} + - (void)setEnabled:(BOOL)enabled { if (enabled) diff --git a/Vector/Views/TableViewCell/TableViewCellWithCheckBoxes.m b/Vector/Views/TableViewCell/TableViewCellWithCheckBoxes.m index e030932962..cf15248be6 100644 --- a/Vector/Views/TableViewCell/TableViewCellWithCheckBoxes.m +++ b/Vector/Views/TableViewCell/TableViewCellWithCheckBoxes.m @@ -16,6 +16,8 @@ #import "TableViewCellWithCheckBoxes.h" +#import "VectorDesignValues.h" + // The space between 2 check boxes #define TABLEVIEWCELLWITHCHECKBOXES_MARGIN 8 @@ -134,6 +136,7 @@ - (void)setCheckBoxesNumber:(NSUInteger)checkBoxesNumber UILabel *theLabel = [[UILabel alloc] initWithFrame:CGRectMake(60, 0, containerWidth - 60, 31)]; theLabel.translatesAutoresizingMaskIntoConstraints = NO; + theLabel.textColor = kVectorTextColorBlack; [checkboxContainer addSubview:theLabel]; [labelArray addObject:theLabel]; diff --git a/Vector/Views/TableViewCell/TableViewCellWithLabelAndLargeTextView.m b/Vector/Views/TableViewCell/TableViewCellWithLabelAndLargeTextView.m index 68fe4bb0a7..62a0164ccf 100644 --- a/Vector/Views/TableViewCell/TableViewCellWithLabelAndLargeTextView.m +++ b/Vector/Views/TableViewCell/TableViewCellWithLabelAndLargeTextView.m @@ -16,12 +16,16 @@ #import "TableViewCellWithLabelAndLargeTextView.h" +#import "VectorDesignValues.h" + @implementation TableViewCellWithLabelAndLargeTextView - (void)awakeFromNib { [super awakeFromNib]; + _label.textColor = kVectorTextColorBlack; + // Adjust text view // Remove the container inset: this operation impacts only the vertical margin. // Reset textContainer.lineFragmentPadding to remove horizontal margin. From c376656657e11eea77bcd6269921616948f26ae0 Mon Sep 17 00:00:00 2001 From: giomfo Date: Fri, 8 Jul 2016 15:07:05 +0200 Subject: [PATCH 09/18] Room Settings: Add "Addresses" section https://github.com/vector-im/vector-ios/issues/412 - List the existing addresses (room aliases), the local aliases first (remote aliases at the end). - Support address deletion (Swipe mode) - Support the change of the main address - Display Room id in advanced section TODO: - Support add new aliases - Support long tap to copy alias, copy links or remove alias - Support long tap on room id to copy it --- Vector.xcodeproj/project.pbxproj | 12 + Vector/Assets/Images/main_alias_icon.png | Bin 0 -> 693 bytes Vector/Assets/Images/main_alias_icon@2x.png | Bin 0 -> 1457 bytes Vector/Assets/Images/main_alias_icon@3x.png | Bin 0 -> 1792 bytes Vector/Assets/en.lproj/Vector.strings | 13 +- .../RoomSettingsViewController.m | 682 ++++++++++++++---- 6 files changed, 581 insertions(+), 126 deletions(-) create mode 100644 Vector/Assets/Images/main_alias_icon.png create mode 100644 Vector/Assets/Images/main_alias_icon@2x.png create mode 100644 Vector/Assets/Images/main_alias_icon@3x.png diff --git a/Vector.xcodeproj/project.pbxproj b/Vector.xcodeproj/project.pbxproj index 2c772f8045..0438b1161f 100644 --- a/Vector.xcodeproj/project.pbxproj +++ b/Vector.xcodeproj/project.pbxproj @@ -166,6 +166,9 @@ F067F2BC1CF6F0EA00F35EE8 /* third_party_licenses.html in Resources */ = {isa = PBXBuildFile; fileRef = F067F2BB1CF6F0EA00F35EE8 /* third_party_licenses.html */; }; F07ECA4D1D2BB0A60060C09F /* TableViewCellWithCheckBoxes.m in Sources */ = {isa = PBXBuildFile; fileRef = F07ECA4B1D2BB0A60060C09F /* TableViewCellWithCheckBoxes.m */; }; F07ECA4E1D2BB0A60060C09F /* TableViewCellWithCheckBoxes.xib in Resources */ = {isa = PBXBuildFile; fileRef = F07ECA4C1D2BB0A60060C09F /* TableViewCellWithCheckBoxes.xib */; }; + F07ECA521D2D730D0060C09F /* main_alias_icon.png in Resources */ = {isa = PBXBuildFile; fileRef = F07ECA4F1D2D730D0060C09F /* main_alias_icon.png */; }; + F07ECA531D2D730D0060C09F /* main_alias_icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = F07ECA501D2D730D0060C09F /* main_alias_icon@2x.png */; }; + F07ECA541D2D730D0060C09F /* main_alias_icon@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = F07ECA511D2D730D0060C09F /* main_alias_icon@3x.png */; }; F08BE09E1B87025B00C480FB /* EventFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = F08BE09D1B87025B00C480FB /* EventFormatter.m */; }; F08BE0A21B87064000C480FB /* RoomDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = F08BE0A11B87064000C480FB /* RoomDataSource.m */; }; F094A9A81B78D8F000B1FBBF /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = F094A9A71B78D8F000B1FBBF /* main.m */; }; @@ -469,6 +472,9 @@ F07ECA4A1D2BB0A60060C09F /* TableViewCellWithCheckBoxes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TableViewCellWithCheckBoxes.h; path = TableViewCell/TableViewCellWithCheckBoxes.h; sourceTree = ""; }; F07ECA4B1D2BB0A60060C09F /* TableViewCellWithCheckBoxes.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TableViewCellWithCheckBoxes.m; path = TableViewCell/TableViewCellWithCheckBoxes.m; sourceTree = ""; }; F07ECA4C1D2BB0A60060C09F /* TableViewCellWithCheckBoxes.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = TableViewCellWithCheckBoxes.xib; path = TableViewCell/TableViewCellWithCheckBoxes.xib; sourceTree = ""; }; + F07ECA4F1D2D730D0060C09F /* main_alias_icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = main_alias_icon.png; sourceTree = ""; }; + F07ECA501D2D730D0060C09F /* main_alias_icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "main_alias_icon@2x.png"; sourceTree = ""; }; + F07ECA511D2D730D0060C09F /* main_alias_icon@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "main_alias_icon@3x.png"; sourceTree = ""; }; F08BE09C1B87025B00C480FB /* EventFormatter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EventFormatter.h; sourceTree = ""; }; F08BE09D1B87025B00C480FB /* EventFormatter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EventFormatter.m; sourceTree = ""; }; F08BE0A01B87064000C480FB /* RoomDataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RoomDataSource.h; sourceTree = ""; }; @@ -1067,6 +1073,9 @@ F0DD7D1B1B7AA8C900C4BE02 /* Images */ = { isa = PBXGroup; children = ( + F07ECA4F1D2D730D0060C09F /* main_alias_icon.png */, + F07ECA501D2D730D0060C09F /* main_alias_icon@2x.png */, + F07ECA511D2D730D0060C09F /* main_alias_icon@3x.png */, F0CC255E1D099F30000819CA /* newmessages.png */, F0CC255F1D099F30000819CA /* newmessages@2x.png */, F0CC25601D099F30000819CA /* newmessages@3x.png */, @@ -1285,6 +1294,7 @@ F0B7037F1D22D4AD00B63766 /* TableViewCellWithCheckBoxAndLabel.xib in Resources */, F02BB04C1CBE2EE70022A025 /* PreviewRoomTitleView.xib in Resources */, F056418C1C7CBEBD002276ED /* group.png in Resources */, + F07ECA541D2D730D0060C09F /* main_alias_icon@3x.png in Resources */, F0C34B681C15C28300C36F09 /* RoomOutgoingTextMsgWithoutSenderInfoBubbleCell.xib in Resources */, F0CC256F1D099F30000819CA /* scrollup@3x.png in Resources */, F0026B631C916E68001D2C04 /* priorityLow@3x.png in Resources */, @@ -1309,6 +1319,7 @@ F02528FC1C11B6FC00E1FE1B /* selection_tick@3x.png in Resources */, F03FBCCD1CBBF521000A5770 /* mod_icon@3x.png in Resources */, F025290B1C11B6FC00E1FE1B /* upload_icon@3x.png in Resources */, + F07ECA531D2D730D0060C09F /* main_alias_icon@2x.png in Resources */, F0CC25691D099F30000819CA /* newmessages@3x.png in Resources */, F02529011C11B6FC00E1FE1B /* settings_icon@2x.png in Resources */, F0026B511C916E68001D2C04 /* favourite@3x.png in Resources */, @@ -1382,6 +1393,7 @@ 325F6A491C21D4C100C12F51 /* chevron@3x.png in Resources */, F001D76E1B83156000A162C3 /* MediaPickerViewController.xib in Resources */, F02529031C11B6FC00E1FE1B /* typing.png in Resources */, + F07ECA521D2D730D0060C09F /* main_alias_icon.png in Resources */, 32D200851C15C56A00A4E396 /* search_bg@3x.png in Resources */, F056418D1C7CBEBD002276ED /* group@2x.png in Resources */, F0026B501C916E68001D2C04 /* favourite@2x.png in Resources */, diff --git a/Vector/Assets/Images/main_alias_icon.png b/Vector/Assets/Images/main_alias_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..f2bbb9c082af5a51401a1111fd4007ead30e29a2 GIT binary patch literal 693 zcmV;m0!safP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01ejw01ejxLMWSf00007bV*G`2jB+= z4iXhoY>V6g00K2hL_t(I%e9rgPZU8Ez<)EhoOjC!1`YA<#DJg$(U_QPj4{!|%4ocJ z1)f&MLW?65#>&RRj>5=4U}2DiORg}{N+Yo$@vt-!T^m0R1(jT6U5?ER1q-(vv#5oy znwj_BZ{N)OSb;&@@%{u*0P;W%$N(Cs0ac&^l)In(9F$x={-=Ch!@_Z*9a1`K47fYB&RYw$YAwzc))(spk;>W=p(WRT5lYp#TyMrKZ79k{r08cUxf z)_Vbw>H!gJ1!jSQ6_f_ZHsZNEh}}n#JNH8@X$&KNJh+T%pnrWtEzZ(-bsHLWfV>Rq z4Act#yN8HmcO-0+$T*@si|y`Yv4gUZFZMm^&V{$aOO0kYY_kK1MrtxqHn_*7y{qJ|1cTWT(XPKM0ncVkLu^Y zkTJXH47X03kzf@4Gc54^&jU6r-qUjl?ambtA}@AyPx#24YJ`L;(K){{a7>y{D4^000SaNLh0L01ejw01ejxLMWSf00007bV*G`2jB+= z4iW;X*->^(@HJ06_8;XVvE?Aunc&WF z8Y7C6NJxl4S%8U&X*3#ROzg%e#I%7((y*w;g+Ymu7!Xp{pbKaZL}L9p1E?5V2DAW8E(!YXJu{f-3|A`FwmWu5!928*C0Ku-aszk=&>D!uE<0v0(HRZ^ zJAut^Ea{;pe9K-1U%-vpW?-kXX%A2_*8!{r{EpcxtwCS97E$#idgT*t0Q!}!4rSYx z!4{y=ZD8qDs}Ut3wER-^&nx zM2=lRCPuKX{f3+zPFJl1R`^s<&T_9WycSXYG&vVdp!qA%{1pgpJ|a1Bk(omqGP${4 zsDAEFF(yg=+JX`LLbZ2yPpm7)nd#bsoVb|j?^QxIo3lhtU&rYA2y^Jiy9QE@50E_Z z4s!I5xjqRA)d^=lVCDv?qiL5>eN%K~b^v6s{YsWWYu z17CXvXbU-_3a1Bh$FUXvWIM*e3n!s z@)4yqP674;QK97(537ma9-qG)^5^KvQsWpGIx(UjBNM|}8(fFd1q_SA7f+i&yAwBS zWwo9VB^V+s)jT&YF?HIMYV*$aakL9mwR^?MoIf2H~?aweQycCjHA+)p})~OEe8p zR*Re&#kzV7t#$1EsEPW?3(xE_Ut{{rj- z+U6QNHN6lyIYjE{8<&%KxZ>8{PX-BOF34z-T(-vj3M0~-R7Si;eEOMSS_%NoRk>;krB z0+)3^n8xNNwT`IIF|Zz>Ef9(Aw(AG&WDoEPu-8q^wn@T!)tP&2i-W6RInWrgM*Etz zyg-Arj5^GzAX3_!&QN6r=*jMwCt9JY!&o9#KzGg5Y00000 LNkvXXu0mjf;lrMC literal 0 HcmV?d00001 diff --git a/Vector/Assets/Images/main_alias_icon@3x.png b/Vector/Assets/Images/main_alias_icon@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..5619537b0308886d4efd4984c56cb2931f9c82a1 GIT binary patch literal 1792 zcmV+b2mknqP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01ejw01ejxLMWSf00007bV*G`2jB+= z4iOX%M(BwE00w|bL_t(&-rbv9Y!y`$hQGb1KzryZw1`RpTPPy77!rv-C=xG$8nBoc zN=Rb}DuN)&gBma~MqiAmF(D?JR5U&iQfW+t21HS;wOp)JZV@qfN{i6Qt(D&ATxNWj zsp;kPoHH|f1Ly_XfmWai zI0ZBU^?`~|haYwc#Uu-Wa-a;D?{T;~pa!T8RD@d6ig3^NqD8=J;BlWEW+zY?s0i)3 zu7qu(8x^SOMD@*Hhzk#{`!=wg>w_v_lN(nTF33IuY_S8+^+Y$YAy5(e#L17OL$V(N zTRoE%5|K0AE8(%gR@)}E3fn1W2T-a)8m-_lv}sQeu6Hxq!2+3Qul)As_qY@1yxyh9~f z5Q9i+`41xVW~(N>!xdpW7?i5CMw_w#IeylV1$aSq^e#;l$Yg@lvsQH#8_$Kc$qyrQ z?^I2Ct<51hVY{f#paS!;kW%LDiXP_HgzF#{2i*N9BXqK znXp|OD=!zd{D+WvcO`are^g#>a~e_Mjeg9UO8U{JmLkX9?#J{S;}W)4Liw&ooAf|x z1%_Ra_<;EXRUWADYG2fK;Huhfi&fOv@vwRjVLO^B-@MCP??+CY>!|D;Rr0(agdgvZ z*ctXe%Du@LKn4pC!D)zK0W!M~kuwe9;+@nA$`~_#7G`HNW>*VF=UL3o7VGccOJ1xj z2j1%^T$bFDG05x!i%50>B3OtF79xU$h^(6x)+f?RQSs7Lvr-l zq#fzl`F(_cTnjNhmB))E){Q`FgSYG=d|(3@(exnu=U&1GUIZhO>QAOitm_Yllf2+$ z5`W14yZDam$d_1mJ$|~8da~|cuUrXa`5Y*eA{zRfaKo!^V@a0uGP&_rJ^ByNLiE2O z9X+#+NW*Jj8t%(otSd|Rq%R&uuYC$4UH+0i{V93v&*(l|NIrV9#LY%Q@s2ZwXW-hGmz-lG% zsKQMD6b|GgMg_eNQx~WRb@Ue=HQrV5kFcTzt?4g35TkRdJq@L0BC@AC*{(Y-Nfo>@ z)&COCT6(kvt2M~|J0`RgE3<>>-z=qX=L1B4tAtozimAy{;M&>W05htM6%9N|MRq3bBxJDWKM8n-sYjZC5EV6`(ry>nnwq+^&~95y^z_G=VP86a0f9EP6cMfS&C|dr{oU^B>^rKt<@$L`OV{uncIp zfyg%4Hsgx0-MhHt1|i)5EJ@aHne@~$P!YNaEWm2uOj|bw7TC5X34acdrh#n40Od;I zA!@G!RyoPjKBC)BJ&rnI93RBnxvj)aMWzr{K#9|Cc*ib1+{I@s0`vd>k;hQDuTD2(dOnfv!Jpz~WVWMawu&)%O(Ju`DUo$c iqX *historyVisibilityTickCells; + // Room aliases + NSMutableArray *roomAddresses; + NSUInteger localAddressesCount; + // The potential image loader MXKMediaLoader *uploader; @@ -152,6 +161,7 @@ - (void)viewDidLoad [self.tableView registerClass:MXKTableViewCellWithButton.class forCellReuseIdentifier:[MXKTableViewCellWithButton defaultReuseIdentifier]]; [self.tableView registerClass:TableViewCellWithCheckBoxes.class forCellReuseIdentifier:[TableViewCellWithCheckBoxes defaultReuseIdentifier]]; [self.tableView registerClass:TableViewCellWithCheckBoxAndLabel.class forCellReuseIdentifier:[TableViewCellWithCheckBoxAndLabel defaultReuseIdentifier]]; + [self.tableView registerClass:MXKTableViewCell.class forCellReuseIdentifier:[MXKTableViewCell defaultReuseIdentifier]]; [self setNavBarButtons]; } @@ -242,6 +252,8 @@ - (void)destroy updatedItemsDict = nil; historyVisibilityTickCells = nil; + roomAddresses = nil; + [super destroy]; } @@ -567,7 +579,12 @@ - (IBAction)onSave:(id)sender dispatch_async(dispatch_get_main_queue(), ^{ - [strongSelf onSaveFailed:NSLocalizedStringFromTable(@"room_details_fail_to_update_avatar", @"Vector", nil) withKey:kRoomSettingsAvatarKey]; + NSString* message = error.localizedDescription; + if (!message.length) + { + message = NSLocalizedStringFromTable(@"room_details_fail_to_update_avatar", @"Vector", nil); + } + [strongSelf onSaveFailed:message withKey:kRoomSettingsAvatarKey]; }); } @@ -603,7 +620,12 @@ - (IBAction)onSave:(id)sender dispatch_async(dispatch_get_main_queue(), ^{ - [strongSelf onSaveFailed:NSLocalizedStringFromTable(@"room_details_fail_to_update_avatar", @"Vector", nil) withKey:kRoomSettingsAvatarURLKey]; + NSString* message = error.localizedDescription; + if (!message.length) + { + message = NSLocalizedStringFromTable(@"room_details_fail_to_update_avatar", @"Vector", nil); + } + [strongSelf onSaveFailed:message withKey:kRoomSettingsAvatarURLKey]; }); } @@ -640,7 +662,12 @@ - (IBAction)onSave:(id)sender dispatch_async(dispatch_get_main_queue(), ^{ - [strongSelf onSaveFailed:NSLocalizedStringFromTable(@"room_details_fail_to_update_room_name", @"Vector", nil) withKey:kRoomSettingsNameKey]; + NSString* message = error.localizedDescription; + if (!message.length) + { + message = NSLocalizedStringFromTable(@"room_details_fail_to_update_room_name", @"Vector", nil); + } + [strongSelf onSaveFailed:message withKey:kRoomSettingsNameKey]; }); } @@ -677,7 +704,12 @@ - (IBAction)onSave:(id)sender dispatch_async(dispatch_get_main_queue(), ^{ - [strongSelf onSaveFailed:NSLocalizedStringFromTable(@"room_details_fail_to_update_topic", @"Vector", nil) withKey:kRoomSettingsTopicKey]; + NSString* message = error.localizedDescription; + if (!message.length) + { + message = NSLocalizedStringFromTable(@"room_details_fail_to_update_topic", @"Vector", nil); + } + [strongSelf onSaveFailed:message withKey:kRoomSettingsTopicKey]; }); } @@ -714,7 +746,12 @@ - (IBAction)onSave:(id)sender dispatch_async(dispatch_get_main_queue(), ^{ - [strongSelf onSaveFailed:NSLocalizedStringFromTable(@"room_details_fail_to_update_room_guest_access", @"Vector", nil) withKey:kRoomSettingsGuestAccessKey]; + NSString* message = error.localizedDescription; + if (!message.length) + { + message = NSLocalizedStringFromTable(@"room_details_fail_to_update_room_guest_access", @"Vector", nil); + } + [strongSelf onSaveFailed:message withKey:kRoomSettingsGuestAccessKey]; }); } @@ -751,7 +788,12 @@ - (IBAction)onSave:(id)sender dispatch_async(dispatch_get_main_queue(), ^{ - [strongSelf onSaveFailed:NSLocalizedStringFromTable(@"room_details_fail_to_update_room_join_rule", @"Vector", nil) withKey:kRoomSettingsJoinRuleKey]; + NSString* message = error.localizedDescription; + if (!message.length) + { + message = NSLocalizedStringFromTable(@"room_details_fail_to_update_room_join_rule", @"Vector", nil); + } + [strongSelf onSaveFailed:message withKey:kRoomSettingsJoinRuleKey]; }); } @@ -788,7 +830,160 @@ - (IBAction)onSave:(id)sender dispatch_async(dispatch_get_main_queue(), ^{ - [strongSelf onSaveFailed:NSLocalizedStringFromTable(@"room_details_fail_to_update_history_visibility", @"Vector", nil) withKey:kRoomSettingsHistoryVisibilityKey]; + NSString* message = error.localizedDescription; + if (!message.length) + { + message = NSLocalizedStringFromTable(@"room_details_fail_to_update_history_visibility", @"Vector", nil); + } + [strongSelf onSaveFailed:message withKey:kRoomSettingsHistoryVisibilityKey]; + + }); + } + + }]; + + return; + } + + // Room addresses + NSMutableArray *aliases = [updatedItemsDict objectForKey:kRoomSettingsNewAliasesKey]; + if (aliases.count) + { + NSString *roomAlias = aliases.firstObject; + + pendingOperation = [mxRoom addAlias:roomAlias success:^{ + + if (weakSelf) + { + __strong __typeof(weakSelf)strongSelf = weakSelf; + + strongSelf->pendingOperation = nil; + + if (aliases.count > 1) + { + [aliases removeObjectAtIndex:0]; + [strongSelf->updatedItemsDict setObject:aliases forKey:kRoomSettingsNewAliasesKey]; + } + else + { + [strongSelf->updatedItemsDict removeObjectForKey:kRoomSettingsNewAliasesKey]; + } + + [strongSelf onSave:nil]; + } + + } failure:^(NSError *error) { + + NSLog(@"[RoomSettingsViewController] Add room aliases failed"); + + if (weakSelf) + { + __strong __typeof(weakSelf)strongSelf = weakSelf; + + strongSelf->pendingOperation = nil; + + dispatch_async(dispatch_get_main_queue(), ^{ + + NSString* message = error.localizedDescription; + if (!message.length) + { + message = NSLocalizedStringFromTable(@"room_details_fail_to_add_room_aliases", @"Vector", nil); + } + [strongSelf onSaveFailed:message withKey:kRoomSettingsNewAliasesKey]; + + }); + } + + }]; + + return; + } + + aliases = [updatedItemsDict objectForKey:kRoomSettingsRemovedAliasesKey]; + if (aliases.count) + { + NSString *roomAlias = aliases.firstObject; + + pendingOperation = [mxRoom removeAlias:roomAlias success:^{ + + if (weakSelf) + { + __strong __typeof(weakSelf)strongSelf = weakSelf; + + strongSelf->pendingOperation = nil; + + if (aliases.count > 1) + { + [aliases removeObjectAtIndex:0]; + [strongSelf->updatedItemsDict setObject:aliases forKey:kRoomSettingsRemovedAliasesKey]; + } + else + { + [strongSelf->updatedItemsDict removeObjectForKey:kRoomSettingsRemovedAliasesKey]; + } + + [strongSelf onSave:nil]; + } + + } failure:^(NSError *error) { + + NSLog(@"[RoomSettingsViewController] Remove room aliases failed"); + + if (weakSelf) + { + __strong __typeof(weakSelf)strongSelf = weakSelf; + + strongSelf->pendingOperation = nil; + + dispatch_async(dispatch_get_main_queue(), ^{ + + NSString* message = error.localizedDescription; + if (!message.length) + { + message = NSLocalizedStringFromTable(@"room_details_fail_to_remove_room_aliases", @"Vector", nil); + } + [strongSelf onSaveFailed:message withKey:kRoomSettingsRemovedAliasesKey]; + + }); + } + + }]; + + return; + } + + NSString* canonicalAlias = [updatedItemsDict objectForKey:kRoomSettingsCanonicalAliasKey]; + if (canonicalAlias) + { + pendingOperation = [mxRoom setCanonicalAlias:canonicalAlias success:^{ + + if (weakSelf) + { + __strong __typeof(weakSelf)strongSelf = weakSelf; + + strongSelf->pendingOperation = nil; + [strongSelf->updatedItemsDict removeObjectForKey:kRoomSettingsCanonicalAliasKey]; + [strongSelf onSave:nil]; + } + + } failure:^(NSError *error) { + + NSLog(@"[RoomSettingsViewController] Update canonical alias failed"); + + if (weakSelf) + { + __strong __typeof(weakSelf)strongSelf = weakSelf; + + strongSelf->pendingOperation = nil; + + dispatch_async(dispatch_get_main_queue(), ^{ + + NSString* message = error.localizedDescription; + if (!message.length) + { + message = NSLocalizedStringFromTable(@"room_details_fail_to_update_room_canonical_alias", @"Vector", nil); + } + [strongSelf onSaveFailed:message withKey:kRoomSettingsCanonicalAliasKey]; }); } @@ -866,7 +1061,12 @@ - (IBAction)onSave:(id)sender dispatch_async(dispatch_get_main_queue(), ^{ - [strongSelf onSaveFailed:NSLocalizedStringFromTable(@"room_details_fail_to_update_room_directory_visibility", @"Vector", nil) withKey:kRoomSettingsDirectoryKey]; + NSString* message = error.localizedDescription; + if (!message.length) + { + message = NSLocalizedStringFromTable(@"room_details_fail_to_update_room_directory_visibility", @"Vector", nil); + } + [strongSelf onSaveFailed:message withKey:kRoomSettingsDirectoryKey]; }); } @@ -905,6 +1105,51 @@ - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger { return ROOM_SETTINGS_HISTORY_VISIBILITY_SECTION_ROW_COUNT; } + else if (section == ROOM_SETTINGS_ROOM_ADDRESSES_SECTION_INDEX) + { + roomAddresses = nil; + localAddressesCount = 0; + + NSArray *removedAliases = [updatedItemsDict objectForKey:kRoomSettingsRemovedAliasesKey]; + + NSArray *aliases = mxRoomState.aliases; + if (aliases) + { + roomAddresses = [NSMutableArray arrayWithCapacity:aliases.count]; + + for (NSString *alias in aliases) + { + // Check whether the user did not remove it + if (!removedAliases || [removedAliases indexOfObject:alias] == NSNotFound) + { + // Add it + if ([alias hasSuffix:self.mainSession.matrixRestClient.homeserverSuffix]) + { + [roomAddresses insertObject:alias atIndex:localAddressesCount]; + localAddressesCount++; + } + else + { + [roomAddresses addObject:alias]; + } + } + } + } + + aliases = [updatedItemsDict objectForKey:kRoomSettingsNewAliasesKey]; + for (NSString *alias in aliases) + { + // Add this new alias to local addresses + [roomAddresses insertObject:alias atIndex:localAddressesCount]; + localAddressesCount++; + } + + return (localAddressesCount ? roomAddresses.count : roomAddresses.count + 1); + } + else if (section == ROOM_SETTINGS_ADVANCED_SECTION_INDEX) + { + return 1; + } return 0; } @@ -919,6 +1164,14 @@ - (nullable NSString *)tableView:(UITableView *)tableView titleForHeaderInSectio { return NSLocalizedStringFromTable(@"room_details_history_section", @"Vector", nil); } + else if (section == ROOM_SETTINGS_ROOM_ADDRESSES_SECTION_INDEX) + { + return NSLocalizedStringFromTable(@"room_details_addresses_section", @"Vector", nil); + } + else if (section == ROOM_SETTINGS_ADVANCED_SECTION_INDEX) + { + return NSLocalizedStringFromTable(@"room_details_advanced_section", @"Vector", nil); + } return nil; } @@ -961,6 +1214,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N roomNotifCell.mxkSwitch.onTintColor = kVectorColorGreen; roomNotifCell.mxkLabel.text = NSLocalizedStringFromTable(@"room_details_mute_notifs", @"Vector", nil); + roomNotifCell.mxkLabel.textColor = kVectorTextColorBlack; roomNotifSwitch = roomNotifCell.mxkSwitch; if ([updatedItemsDict objectForKey:kRoomSettingsMuteNotifKey]) @@ -995,6 +1249,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N roomPhotoCell.mxkImageView.backgroundColor = [UIColor clearColor]; roomPhotoCell.mxkLabel.text = NSLocalizedStringFromTable(@"room_details_photo", @"Vector", nil); + roomPhotoCell.mxkLabel.textColor = kVectorTextColorBlack; if ([updatedItemsDict objectForKey:kRoomSettingsAvatarKey]) { @@ -1048,6 +1303,8 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N roomNameCell.mxkTextFieldTrailingConstraint.constant = 15; roomNameCell.mxkLabel.text = NSLocalizedStringFromTable(@"room_details_room_name", @"Vector", nil); + roomNameCell.mxkLabel.textColor = kVectorTextColorBlack; + roomNameCell.accessoryType = UITableViewCellAccessoryNone; nameTextField = roomNameCell.mxkTextField; @@ -1146,6 +1403,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N directoryToggleCell.mxkSwitchTrailingConstraint.constant = 15; directoryToggleCell.mxkLabel.text = NSLocalizedStringFromTable(@"room_details_access_section_directory_toggle", @"Vector", nil); + directoryToggleCell.mxkLabel.textColor = kVectorTextColorBlack; directoryVisibilitySwitch = directoryToggleCell.mxkSwitch; @@ -1217,76 +1475,44 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N { TableViewCellWithCheckBoxAndLabel *roomAccessCell = [tableView dequeueReusableCellWithIdentifier:[TableViewCellWithCheckBoxAndLabel defaultReuseIdentifier] forIndexPath:indexPath]; + // Retrieve the potential updated values for joinRule and guestAccess + NSString *joinRule = [updatedItemsDict objectForKey:kRoomSettingsJoinRuleKey]; + NSString *guestAccess = [updatedItemsDict objectForKey:kRoomSettingsGuestAccessKey]; + + // Use the actual values if no change is pending + if (!joinRule) + { + joinRule = mxRoomState.joinRule; + } + if (!guestAccess) + { + guestAccess = mxRoomState.guestAccess; + } + if (indexPath.row == ROOM_SETTINGS_ROOM_ACCESS_SECTION_ROW_INVITED_ONLY) { + roomAccessCell.label.lineBreakMode = NSLineBreakByTruncatingMiddle; roomAccessCell.label.text = NSLocalizedStringFromTable(@"room_details_access_section_invited_only", @"Vector", nil); - if ([updatedItemsDict objectForKey:kRoomSettingsJoinRuleKey]) - { - NSString *joinRule = [updatedItemsDict objectForKey:kRoomSettingsJoinRuleKey]; - if ([joinRule isEqualToString:kMXRoomJoinRuleInvite]) - { - roomAccessCell.enabled = YES; - } - else - { - roomAccessCell.enabled = NO; - } - } - else - { - roomAccessCell.enabled = ([mxRoomState.joinRule isEqualToString:kMXRoomJoinRuleInvite]); - } + roomAccessCell.enabled = ([joinRule isEqualToString:kMXRoomJoinRuleInvite]); accessInvitedOnlyTickCell = roomAccessCell; } else if (indexPath.row == ROOM_SETTINGS_ROOM_ACCESS_SECTION_ROW_ANYONE_APART_FROM_GUEST) { + roomAccessCell.label.lineBreakMode = NSLineBreakByTruncatingMiddle; roomAccessCell.label.text = NSLocalizedStringFromTable(@"room_details_access_section_anyone_apart_from_guest", @"Vector", nil); - if ([updatedItemsDict objectForKey:kRoomSettingsJoinRuleKey] || [updatedItemsDict objectForKey:kRoomSettingsGuestAccessKey]) - { - NSString *joinRule = [updatedItemsDict objectForKey:kRoomSettingsJoinRuleKey]; - NSString *guestAccess = [updatedItemsDict objectForKey:kRoomSettingsGuestAccessKey]; - - if ([joinRule isEqualToString:kMXRoomJoinRulePublic] && [guestAccess isEqualToString:kMXRoomGuestAccessForbidden]) - { - roomAccessCell.enabled = YES; - } - else - { - roomAccessCell.enabled = NO; - } - } - else - { - roomAccessCell.enabled = ([mxRoomState.joinRule isEqualToString:kMXRoomJoinRulePublic] && [mxRoomState.guestAccess isEqualToString:kMXRoomGuestAccessForbidden]); - } + roomAccessCell.enabled = ([joinRule isEqualToString:kMXRoomJoinRulePublic] && [guestAccess isEqualToString:kMXRoomGuestAccessForbidden]); accessAnyoneApartGuestTickCell = roomAccessCell; } else if (indexPath.row == ROOM_SETTINGS_ROOM_ACCESS_SECTION_ROW_ANYONE) { + roomAccessCell.label.lineBreakMode = NSLineBreakByTruncatingMiddle; roomAccessCell.label.text = NSLocalizedStringFromTable(@"room_details_access_section_anyone", @"Vector", nil); - if ([updatedItemsDict objectForKey:kRoomSettingsJoinRuleKey] || [updatedItemsDict objectForKey:kRoomSettingsGuestAccessKey]) - { - NSString *joinRule = [updatedItemsDict objectForKey:kRoomSettingsJoinRuleKey]; - NSString *guestAccess = [updatedItemsDict objectForKey:kRoomSettingsGuestAccessKey]; - - if ([joinRule isEqualToString:kMXRoomJoinRulePublic] && [guestAccess isEqualToString:kMXRoomGuestAccessCanJoin]) - { - roomAccessCell.enabled = YES; - } - else - { - roomAccessCell.enabled = NO; - } - } - else - { - roomAccessCell.enabled = ([mxRoomState.joinRule isEqualToString:kMXRoomJoinRulePublic] && [mxRoomState.guestAccess isEqualToString:kMXRoomGuestAccessCanJoin]); - } + roomAccessCell.enabled = ([joinRule isEqualToString:kMXRoomJoinRulePublic] && [guestAccess isEqualToString:kMXRoomGuestAccessCanJoin]); accessAnyoneTickCell = roomAccessCell; } @@ -1302,104 +1528,117 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N { TableViewCellWithCheckBoxAndLabel *historyVisibilityCell = [tableView dequeueReusableCellWithIdentifier:[TableViewCellWithCheckBoxAndLabel defaultReuseIdentifier] forIndexPath:indexPath]; + // Retrieve first the potential updated value for history visibility + NSString *visibility = [updatedItemsDict objectForKey:kRoomSettingsHistoryVisibilityKey]; + + // Use the actual value if no change is pending + if (!visibility) + { + visibility = mxRoomState.historyVisibility; + } + if (indexPath.row == ROOM_SETTINGS_HISTORY_VISIBILITY_SECTION_ROW_ANYONE) { + historyVisibilityCell.label.lineBreakMode = NSLineBreakByTruncatingMiddle; historyVisibilityCell.label.text = NSLocalizedStringFromTable(@"room_details_history_section_anyone", @"Vector", nil); - if ([updatedItemsDict objectForKey:kRoomSettingsHistoryVisibilityKey]) - { - NSString *visibility = [updatedItemsDict objectForKey:kRoomSettingsHistoryVisibilityKey]; - if ([visibility isEqualToString:kMXRoomHistoryVisibilityWorldReadable]) - { - historyVisibilityCell.enabled = YES; - } - else - { - historyVisibilityCell.enabled = NO; - } - } - else - { - historyVisibilityCell.enabled = ([mxRoomState.historyVisibility isEqualToString:kMXRoomHistoryVisibilityWorldReadable]); - } + historyVisibilityCell.enabled = ([visibility isEqualToString:kMXRoomHistoryVisibilityWorldReadable]); [historyVisibilityTickCells setObject:historyVisibilityCell forKey:kMXRoomHistoryVisibilityWorldReadable]; } else if (indexPath.row == ROOM_SETTINGS_HISTORY_VISIBILITY_SECTION_ROW_MEMBERS_ONLY) { + historyVisibilityCell.label.lineBreakMode = NSLineBreakByTruncatingMiddle; historyVisibilityCell.label.text = NSLocalizedStringFromTable(@"room_details_history_section_members_only", @"Vector", nil); - if ([updatedItemsDict objectForKey:kRoomSettingsHistoryVisibilityKey]) - { - NSString *visibility = [updatedItemsDict objectForKey:kRoomSettingsHistoryVisibilityKey]; - if ([visibility isEqualToString:kMXRoomHistoryVisibilityShared]) - { - historyVisibilityCell.enabled = YES; - } - else - { - historyVisibilityCell.enabled = NO; - } - } - else - { - historyVisibilityCell.enabled = ([mxRoomState.historyVisibility isEqualToString:kMXRoomHistoryVisibilityShared]); - } + historyVisibilityCell.enabled = ([visibility isEqualToString:kMXRoomHistoryVisibilityShared]); [historyVisibilityTickCells setObject:historyVisibilityCell forKey:kMXRoomHistoryVisibilityShared]; } else if (indexPath.row == ROOM_SETTINGS_HISTORY_VISIBILITY_SECTION_ROW_MEMBERS_ONLY_SINCE_INVITED) { + historyVisibilityCell.label.lineBreakMode = NSLineBreakByTruncatingMiddle; historyVisibilityCell.label.text = NSLocalizedStringFromTable(@"room_details_history_section_members_only_since_invited", @"Vector", nil); - if ([updatedItemsDict objectForKey:kRoomSettingsHistoryVisibilityKey]) - { - NSString *visibility = [updatedItemsDict objectForKey:kRoomSettingsHistoryVisibilityKey]; - if ([visibility isEqualToString:kMXRoomHistoryVisibilityInvited]) - { - historyVisibilityCell.enabled = YES; - } - else - { - historyVisibilityCell.enabled = NO; - } - } - else - { - historyVisibilityCell.enabled = ([mxRoomState.historyVisibility isEqualToString:kMXRoomHistoryVisibilityInvited]); - } + historyVisibilityCell.enabled = ([visibility isEqualToString:kMXRoomHistoryVisibilityInvited]); [historyVisibilityTickCells setObject:historyVisibilityCell forKey:kMXRoomHistoryVisibilityInvited]; } else if (indexPath.row == ROOM_SETTINGS_HISTORY_VISIBILITY_SECTION_ROW_MEMBERS_ONLY_SINCE_JOINED) { + historyVisibilityCell.label.lineBreakMode = NSLineBreakByTruncatingMiddle; historyVisibilityCell.label.text = NSLocalizedStringFromTable(@"room_details_history_section_members_only_since_joined", @"Vector", nil); - if ([updatedItemsDict objectForKey:kRoomSettingsHistoryVisibilityKey]) + historyVisibilityCell.enabled = ([visibility isEqualToString:kMXRoomHistoryVisibilityJoined]); + + [historyVisibilityTickCells setObject:historyVisibilityCell forKey:kMXRoomHistoryVisibilityJoined]; + } + + // Check whether the user can change this option + historyVisibilityCell.userInteractionEnabled = (oneSelfPowerLevel >= [powerLevels minimumPowerLevelForSendingEventAsStateEvent:kMXEventTypeStringRoomHistoryVisibility]); + historyVisibilityCell.checkBox.alpha = historyVisibilityCell.userInteractionEnabled ? 1.0f : 0.5f; + + cell = historyVisibilityCell; + } + else if (indexPath.section == ROOM_SETTINGS_ROOM_ADDRESSES_SECTION_INDEX) + { + MXKTableViewCell *addressCell = [tableView dequeueReusableCellWithIdentifier:[MXKTableViewCell defaultReuseIdentifier] forIndexPath:indexPath]; + + addressCell.textLabel.font = [UIFont systemFontOfSize:16]; + addressCell.textLabel.textColor = kVectorTextColorBlack; + addressCell.textLabel.lineBreakMode = NSLineBreakByTruncatingMiddle; + addressCell.accessoryView = nil; + addressCell.accessoryType = UITableViewCellAccessoryNone; + addressCell.selectionStyle = UITableViewCellSelectionStyleNone; + + // Check whether there is no local addresses + if (localAddressesCount == 0 && indexPath.row == 0) + { + addressCell.textLabel.text = NSLocalizedStringFromTable(@"room_details_no_local_addresses", @"Vector", nil); + } + else + { + NSInteger row = (localAddressesCount ? indexPath.row : indexPath.row - 1); + + if (row < roomAddresses.count) { - NSString *visibility = [updatedItemsDict objectForKey:kRoomSettingsHistoryVisibilityKey]; - if ([visibility isEqualToString:kMXRoomHistoryVisibilityJoined]) + NSString *alias = roomAddresses[indexPath.row]; + NSString *canonicalAlias; + + if ([updatedItemsDict objectForKey:kRoomSettingsCanonicalAliasKey]) { - historyVisibilityCell.enabled = YES; + canonicalAlias = [updatedItemsDict objectForKey:kRoomSettingsCanonicalAliasKey]; } else { - historyVisibilityCell.enabled = NO; + canonicalAlias = mxRoomState.canonicalAlias; + } + + addressCell.textLabel.text = alias; + + // Check whether this alias is the main address + if (canonicalAlias) + { + if ([alias isEqualToString:canonicalAlias]) + { + addressCell.accessoryView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"main_alias_icon"]]; + } } } - else - { - historyVisibilityCell.enabled = ([mxRoomState.historyVisibility isEqualToString:kMXRoomHistoryVisibilityJoined]); - } - - [historyVisibilityTickCells setObject:historyVisibilityCell forKey:kMXRoomHistoryVisibilityJoined]; } - // Check whether the user can change this option - historyVisibilityCell.userInteractionEnabled = (oneSelfPowerLevel >= [powerLevels minimumPowerLevelForSendingEventAsStateEvent:kMXEventTypeStringRoomHistoryVisibility]); - historyVisibilityCell.checkBox.alpha = historyVisibilityCell.userInteractionEnabled ? 1.0f : 0.5f; + cell = addressCell; + } + else if (indexPath.section == ROOM_SETTINGS_ADVANCED_SECTION_INDEX) + { + MXKTableViewCell *roomIdCell = [tableView dequeueReusableCellWithIdentifier:[MXKTableViewCell defaultReuseIdentifier] forIndexPath:indexPath]; - cell = historyVisibilityCell; + roomIdCell.textLabel.font = [UIFont systemFontOfSize:16]; + roomIdCell.textLabel.text = [NSString stringWithFormat:NSLocalizedStringFromTable(@"room_details_advanced_room_id", @"Vector", nil), mxRoomState.roomId]; + roomIdCell.textLabel.textColor = kVectorTextColorBlack; + roomIdCell.selectionStyle = UITableViewCellSelectionStyleNone; + + cell = roomIdCell; } // Sanity check @@ -1412,6 +1651,25 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N return cell; } +- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath +{ + if (indexPath.section == ROOM_SETTINGS_ROOM_ADDRESSES_SECTION_INDEX) + { + if (localAddressesCount != 0 || indexPath.row != 0) + { + return YES; + } + } + return NO; +} + +- (void)tableView:(UITableView*)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath*)indexPath +{ + // iOS8 requires this method to enable editing (see editActionsForRowAtIndexPath). +} + +#pragma mark - UITableViewDelegate + - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { if (self.tableView == tableView) @@ -1577,7 +1835,84 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath } } } + else if (indexPath.section == ROOM_SETTINGS_ROOM_ADDRESSES_SECTION_INDEX && (localAddressesCount != 0 || indexPath.row != 0)) + { + NSInteger row = (localAddressesCount ? indexPath.row : indexPath.row - 1); + + if (row < roomAddresses.count) + { + NSString *alias = roomAddresses[row]; + NSString *currentCanonicalAlias = mxRoomState.canonicalAlias; + NSString *canonicalAlias; + + if ([updatedItemsDict objectForKey:kRoomSettingsCanonicalAliasKey]) + { + canonicalAlias = [updatedItemsDict objectForKey:kRoomSettingsCanonicalAliasKey]; + } + else + { + canonicalAlias = currentCanonicalAlias; + } + + if (canonicalAlias) + { + if ([alias isEqualToString:canonicalAlias]) + { + // Prompt user before removing the current main address + dispatch_async(dispatch_get_main_queue(), ^{ + [self shouldRemoveCanonicalAlias:nil]; + }); + + } + else + { + // Update the current canonical address + if ([alias isEqualToString:currentCanonicalAlias]) + { + [updatedItemsDict removeObjectForKey:kRoomSettingsCanonicalAliasKey]; + } + else + { + [updatedItemsDict setObject:alias forKey:kRoomSettingsCanonicalAliasKey]; + } + + NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(ROOM_SETTINGS_ROOM_ADDRESSES_SECTION_INDEX, 1)]; + [self.tableView reloadSections:indexSet withRowAnimation:UITableViewRowAnimationNone]; + + [self getNavigationItem].rightBarButtonItem.enabled = (updatedItemsDict.count != 0); + } + } + } + } + + [tableView deselectRowAtIndexPath:indexPath animated:YES]; + } +} + +- (NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath +{ + NSMutableArray* actions; + + // Add the swipe to delete only on addresses section + if (indexPath.section == ROOM_SETTINGS_ROOM_ADDRESSES_SECTION_INDEX) + { + if (localAddressesCount != 0 || indexPath.row != 0) + { + actions = [[NSMutableArray alloc] init]; + + // Patch: Force the width of the button by adding whitespace characters into the title string. + UITableViewRowAction *removeAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDestructive title:@" " handler:^(UITableViewRowAction *action, NSIndexPath *indexPath){ + + [self removeAddressAtIndexPath:indexPath]; + + }]; + + removeAction.backgroundColor = [MXKTools convertImageToPatternColor:@"remove_icon" backgroundColor:kVectorColorLightGrey patternSize:CGSizeMake(44, 44) resourceSize:CGSizeMake(25, 24)]; + [actions insertObject:removeAction atIndex:0]; + } } + + return actions; } #pragma mark - @@ -1645,6 +1980,51 @@ - (void)changeHistoryVisibility:(MXRoomHistoryVisibility)historyVisibility } } +- (void)shouldRemoveCanonicalAlias:(void (^)())didRemoveCanonicalAlias +{ + // Prompt the user before removing the current main address + [currentAlert dismiss:NO]; + + __weak typeof(self) weakSelf = self; + + currentAlert = [[MXKAlert alloc] initWithTitle:NSLocalizedStringFromTable(@"room_details_addresses_disable_main_address_prompt_title", @"Vector", nil) message:NSLocalizedStringFromTable(@"room_details_addresses_disable_main_address_prompt_msg", @"Vector", nil) style:MXKAlertStyleAlert]; + + currentAlert.cancelButtonIndex = [currentAlert addActionWithTitle:[NSBundle mxk_localizedStringForKey:@"cancel"] style:MXKAlertActionStyleCancel handler:^(MXKAlert *alert) { + + if (weakSelf) + { + __strong __typeof(weakSelf)strongSelf = weakSelf; + strongSelf->currentAlert = nil; + } + + }]; + + [currentAlert addActionWithTitle:[NSBundle mxk_localizedStringForKey:@"continue"] style:MXKAlertActionStyleDefault handler:^(MXKAlert *alert) { + + if (weakSelf) + { + __strong __typeof(weakSelf)strongSelf = weakSelf; + strongSelf->currentAlert = nil; + + // Remove the canonical address + [strongSelf->updatedItemsDict setObject:@"" forKey:kRoomSettingsCanonicalAliasKey]; + + NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(ROOM_SETTINGS_ROOM_ADDRESSES_SECTION_INDEX, 1)]; + [strongSelf.tableView reloadSections:indexSet withRowAnimation:UITableViewRowAnimationNone]; + + [strongSelf getNavigationItem].rightBarButtonItem.enabled = (strongSelf->updatedItemsDict.count != 0); + + if (didRemoveCanonicalAlias) + { + didRemoveCanonicalAlias(); + } + } + + }]; + + [currentAlert showInViewController:self]; +} + #pragma mark - MediaPickerViewController Delegate - (void)dismissMediaPicker @@ -1781,6 +2161,60 @@ - (void)onSwitchUpdate:(UISwitch*)theSwitch [self getNavigationItem].rightBarButtonItem.enabled = (updatedItemsDict.count != 0); } +- (void)removeAddressAtIndexPath:(NSIndexPath *)indexPath +{ + NSInteger row = (localAddressesCount ? indexPath.row : indexPath.row - 1); + + if (row < roomAddresses.count) + { + NSString *alias = roomAddresses[indexPath.row]; + [self removeRoomAlias:alias]; + } +} + +- (void)removeRoomAlias:(NSString*)roomAlias +{ + NSString *canonicalAlias; + + if ([updatedItemsDict objectForKey:kRoomSettingsCanonicalAliasKey]) + { + canonicalAlias = [updatedItemsDict objectForKey:kRoomSettingsCanonicalAliasKey]; + } + else + { + canonicalAlias = mxRoomState.canonicalAlias; + } + + // Check whether this alias is the main address + if (canonicalAlias && [roomAlias isEqualToString:canonicalAlias]) + { + // Prompt user before remove this alias which is the main address + [self shouldRemoveCanonicalAlias:^{ + + // The room alias can be removed now + [self removeRoomAlias:roomAlias]; + + }]; + } + else + { + NSMutableArray *removedAlias = [updatedItemsDict objectForKey:kRoomSettingsRemovedAliasesKey]; + if (!removedAlias) + { + removedAlias = [NSMutableArray array]; + } + + [removedAlias addObject:roomAlias]; + + [updatedItemsDict setObject:removedAlias forKey:kRoomSettingsRemovedAliasesKey]; + + NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(ROOM_SETTINGS_ROOM_ADDRESSES_SECTION_INDEX, 1)]; + [self.tableView reloadSections:indexSet withRowAnimation:UITableViewRowAnimationNone]; + + [self getNavigationItem].rightBarButtonItem.enabled = (updatedItemsDict.count != 0); + } +} + #pragma mark - TableViewCellWithCheckBoxesDelegate - (void)tableViewCellWithCheckBoxes:(TableViewCellWithCheckBoxes *)tableViewCellWithCheckBoxes didTapOnCheckBoxAtIndex:(NSUInteger)index From 93601f54a644b215facbde4f27f0dad0811e475f Mon Sep 17 00:00:00 2001 From: giomfo Date: Mon, 11 Jul 2016 17:53:47 +0200 Subject: [PATCH 10/18] Room Settings: Add "Addresses" section #412 - Support add new aliases TODO - Support long tap to copy alias, copy links or remove alias - Support long tap on room id to copy it --- Vector/Assets/en.lproj/Vector.strings | 4 + .../RoomParticipantsViewController.m | 6 + .../RoomSettingsViewController.h | 2 +- .../RoomSettingsViewController.m | 558 ++++++++++++++---- 4 files changed, 446 insertions(+), 124 deletions(-) diff --git a/Vector/Assets/en.lproj/Vector.strings b/Vector/Assets/en.lproj/Vector.strings index 348e647206..14dc47959a 100644 --- a/Vector/Assets/en.lproj/Vector.strings +++ b/Vector/Assets/en.lproj/Vector.strings @@ -263,6 +263,10 @@ "room_details_history_section_prompt_msg" = "Changes to who can read history will only apply to future messages in this room. The visibility of existing history will be unchanged."; "room_details_addresses_section"="Addresses"; "room_details_no_local_addresses" = "This room has no local addresses"; +"room_details_new_address" = "Add new address"; +"room_details_new_address_placeholder" = "Add new address (e.g. #foo:example.org)"; +"room_details_addresses_invalid_address_prompt_title" = "Invalid alias format"; +"room_details_addresses_invalid_address_prompt_msg" = "%@ is not a valid format for an alias"; "room_details_addresses_disable_main_address_prompt_title" = "Main address warning"; "room_details_addresses_disable_main_address_prompt_msg"="You will have no main address specified. The default main address for this room will be picked randomly"; "room_details_advanced_section"="Advanced"; diff --git a/Vector/ViewController/RoomParticipantsViewController.m b/Vector/ViewController/RoomParticipantsViewController.m index bbc4c59903..ff030ac74a 100644 --- a/Vector/ViewController/RoomParticipantsViewController.m +++ b/Vector/ViewController/RoomParticipantsViewController.m @@ -384,6 +384,9 @@ - (void)startActivityIndicator if (self.parentViewController && [self.parentViewController isKindOfClass:SegmentedViewController.class]) { [((SegmentedViewController*)self.parentViewController) startActivityIndicator]; + + // Force stop the activity view of the view controller + [self.activityIndicator stopAnimating]; } else { @@ -397,6 +400,9 @@ - (void)stopActivityIndicator if (self.parentViewController && [self.parentViewController isKindOfClass:SegmentedViewController.class]) { [((SegmentedViewController*)self.parentViewController) stopActivityIndicator]; + + // Force stop the activity view of the view controller + [self.activityIndicator stopAnimating]; } else { diff --git a/Vector/ViewController/RoomSettingsViewController.h b/Vector/ViewController/RoomSettingsViewController.h index 981517bc1a..3e20bcad29 100644 --- a/Vector/ViewController/RoomSettingsViewController.h +++ b/Vector/ViewController/RoomSettingsViewController.h @@ -19,7 +19,7 @@ #import "MediaPickerViewController.h" #import "TableViewCellWithCheckBoxes.h" -@interface RoomSettingsViewController : MXKRoomSettingsViewController +@interface RoomSettingsViewController : MXKRoomSettingsViewController @end diff --git a/Vector/ViewController/RoomSettingsViewController.m b/Vector/ViewController/RoomSettingsViewController.m index 9f11a8ced8..ee6107a4c0 100644 --- a/Vector/ViewController/RoomSettingsViewController.m +++ b/Vector/ViewController/RoomSettingsViewController.m @@ -74,6 +74,10 @@ NSString *const kRoomSettingsRemovedAliasesKey = @"kRoomSettingsRemovedAliasesKey"; NSString *const kRoomSettingsCanonicalAliasKey = @"kRoomSettingsCanonicalAliasKey"; +NSString *const kRoomSettingsNameCellViewIdentifier = @"kRoomSettingsNameCellViewIdentifier"; +NSString *const kRoomSettingsTopicCellViewIdentifier = @"kRoomSettingsTopicCellViewIdentifier"; +NSString *const kRoomSettingsAddressCellViewIdentifier = @"kRoomSettingsAddressCellViewIdentifier"; + @interface RoomSettingsViewController () { // The updated user data @@ -92,6 +96,7 @@ @interface RoomSettingsViewController () TableViewCellWithCheckBoxAndLabel *accessAnyoneTickCell; UISwitch *directoryVisibilitySwitch; MXRoomDirectoryVisibility actualDirectoryVisibility; + MXHTTPOperation* actualDirectoryVisibilityRequest; // History Visibility items NSMutableDictionary *historyVisibilityTickCells; @@ -99,6 +104,8 @@ @interface RoomSettingsViewController () // Room aliases NSMutableArray *roomAddresses; NSUInteger localAddressesCount; + NSInteger roomAddressNewAliasIndex; + UITextField* addAddressTextField; // The potential image loader MXKMediaLoader *uploader; @@ -156,8 +163,13 @@ - (void)viewDidLoad [self.tableView registerClass:MXKTableViewCellWithLabelAndSwitch.class forCellReuseIdentifier:[MXKTableViewCellWithLabelAndSwitch defaultReuseIdentifier]]; [self.tableView registerClass:MXKTableViewCellWithLabelAndMXKImageView.class forCellReuseIdentifier:[MXKTableViewCellWithLabelAndMXKImageView defaultReuseIdentifier]]; - [self.tableView registerClass:TableViewCellWithLabelAndLargeTextView.class forCellReuseIdentifier:[TableViewCellWithLabelAndLargeTextView defaultReuseIdentifier]]; - [self.tableView registerClass:MXKTableViewCellWithLabelAndTextField.class forCellReuseIdentifier:[MXKTableViewCellWithLabelAndTextField defaultReuseIdentifier]]; + + // Use a specific cell identifier for the room name, the topic and the address in order to be able to keep reference + // on the text input field without being disturbed by the cell dequeuing process. + [self.tableView registerClass:MXKTableViewCellWithLabelAndTextField.class forCellReuseIdentifier:kRoomSettingsNameCellViewIdentifier]; + [self.tableView registerClass:TableViewCellWithLabelAndLargeTextView.class forCellReuseIdentifier:kRoomSettingsTopicCellViewIdentifier]; + [self.tableView registerClass:MXKTableViewCellWithLabelAndTextField.class forCellReuseIdentifier:kRoomSettingsAddressCellViewIdentifier]; + [self.tableView registerClass:MXKTableViewCellWithButton.class forCellReuseIdentifier:[MXKTableViewCellWithButton defaultReuseIdentifier]]; [self.tableView registerClass:TableViewCellWithCheckBoxes.class forCellReuseIdentifier:[TableViewCellWithCheckBoxes defaultReuseIdentifier]]; [self.tableView registerClass:TableViewCellWithCheckBoxAndLabel.class forCellReuseIdentifier:[TableViewCellWithCheckBoxAndLabel defaultReuseIdentifier]]; @@ -243,6 +255,12 @@ - (void)destroy pendingOperation = nil; } + if (actualDirectoryVisibilityRequest) + { + [actualDirectoryVisibilityRequest cancel]; + actualDirectoryVisibilityRequest = nil; + } + if (appDelegateDidTapStatusBarNotificationObserver) { [[NSNotificationCenter defaultCenter] removeObserver:appDelegateDidTapStatusBarNotificationObserver]; @@ -272,9 +290,12 @@ - (void)withdrawViewControllerAnimated:(BOOL)animated completion:(void (^)(void) - (void)refreshRoomSettings { + [self retrieveActualDirectoryVisibility]; + // Check whether a text input is currently edited BOOL isNameEdited = nameTextField ? nameTextField.isFirstResponder : NO; BOOL isTopicEdited = topicTextView ? topicTextView.isFirstResponder : NO; + BOOL isAddressEdited = addAddressTextField ? addAddressTextField.isFirstResponder : NO; // Trigger a full table reloadData [super refreshRoomSettings]; @@ -288,6 +309,10 @@ - (void)refreshRoomSettings { [self editRoomTopic]; } + else if (isAddressEdited) + { + [self editAddRoomAddress]; + } } #pragma mark - private @@ -318,6 +343,19 @@ - (void)editRoomTopic } } +- (void)editAddRoomAddress +{ + if (![addAddressTextField becomeFirstResponder]) + { + // Retry asynchronously + dispatch_async(dispatch_get_main_queue(), ^{ + + [self editAddRoomAddress]; + + }); + } +} + - (void)dismissFirstResponder { if ([topicTextView isFirstResponder]) @@ -329,6 +367,11 @@ - (void)dismissFirstResponder { [nameTextField resignFirstResponder]; } + + if ([addAddressTextField isFirstResponder]) + { + [addAddressTextField resignFirstResponder]; + } } - (void)startActivityIndicator @@ -340,6 +383,9 @@ - (void)startActivityIndicator if (self.parentViewController && [self.parentViewController isKindOfClass:SegmentedViewController.class]) { [((SegmentedViewController*)self.parentViewController) startActivityIndicator]; + + // Force stop the activity view of the view controller + [self.activityIndicator stopAnimating]; } else { @@ -359,6 +405,9 @@ - (void)stopActivityIndicator if (self.parentViewController && [self.parentViewController isKindOfClass:SegmentedViewController.class]) { [((SegmentedViewController*)self.parentViewController) stopActivityIndicator]; + + // Force stop the activity view of the view controller + [self.activityIndicator stopAnimating]; } else { @@ -405,6 +454,57 @@ - (void)promptUserToSaveChanges [currentAlert showInViewController:self]; } +- (void)retrieveActualDirectoryVisibility +{ + if (!mxRoom || actualDirectoryVisibilityRequest) + { + return; + } + + // Trigger a new request to check the actual directory visibility + __weak typeof(self) weakSelf = self; + + actualDirectoryVisibilityRequest = [mxRoom directoryVisibility:^(MXRoomDirectoryVisibility directoryVisibility) { + + if (weakSelf) + { + __strong __typeof(weakSelf)strongSelf = weakSelf; + strongSelf->actualDirectoryVisibilityRequest = nil; + + strongSelf->actualDirectoryVisibility = directoryVisibility; + + // Update the value of the displayed toggle button (if any) + if (directoryVisibilitySwitch) + { + // Check a potential user's change before the end of the request + MXRoomDirectoryVisibility modifiedDirectoryVisibility = [updatedItemsDict objectForKey:kRoomSettingsDirectoryKey]; + if (modifiedDirectoryVisibility) + { + if ([modifiedDirectoryVisibility isEqualToString:directoryVisibility]) + { + // The requested change corresponds to the actual settings + [updatedItemsDict removeObjectForKey:kRoomSettingsDirectoryKey]; + + [self getNavigationItem].rightBarButtonItem.enabled = (updatedItemsDict.count != 0); + } + } + + directoryVisibilitySwitch.on = ([directoryVisibility isEqualToString:kMXRoomDirectoryVisibilityPublic]); + } + } + + } failure:^(NSError *error) { + + NSLog(@"[RoomSettingsViewController] request to get directory visibility failed"); + + if (weakSelf) + { + __strong __typeof(weakSelf)strongSelf = weakSelf; + strongSelf->actualDirectoryVisibilityRequest = nil; + } + }]; +} + #pragma mark - UITextViewDelegate - (void)textViewDidBeginEditing:(UITextView *)textView; @@ -453,11 +553,112 @@ - (void)textViewDidChange:(UITextView *)textView } } +#pragma mark - UITextFieldDelegate + +- (void)textFieldDidBeginEditing:(UITextField *)textField +{ + if (textField == addAddressTextField) + { + if (textField.text.length == 0) + { + textField.text = @"#"; + } + } +} +- (void)textFieldDidEndEditing:(UITextField *)textField +{ + if (textField == addAddressTextField) + { + if (textField.text.length < 2) + { + // reset text field + textField.text = nil; + } + else + { + // Check whether homeserver suffix should be added + NSRange range = [textField.text rangeOfString:@":"]; + if (range.location == NSNotFound) + { + textField.text = [textField.text stringByAppendingString:self.mainSession.matrixRestClient.homeserverSuffix]; + } + } + } +} + +- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string +{ + // Auto complete room alias + if (textField == addAddressTextField) + { + // Add # if none + if (!textField.text.length || textField.text.length == range.length) + { + if ([string hasPrefix:@"#"] == NO) + { + if ([string isEqualToString:@":"]) + { + textField.text = [NSString stringWithFormat:@"#%@",self.mainSession.matrixRestClient.homeserverSuffix]; + } + else + { + textField.text = [NSString stringWithFormat:@"#%@",string]; + } + return NO; + } + } + else + { + // Remove default '#' if the string start with '#' + if ([string hasPrefix:@"#"] && [textField.text isEqualToString:@"#"]) + { + textField.text = string; + return NO; + } + // Add homeserver automatically when user adds ':' at the end + else if (range.location == textField.text.length && [string isEqualToString:@":"]) + { + textField.text = [textField.text stringByAppendingString:self.mainSession.matrixRestClient.homeserverSuffix]; + return NO; + } + } + } + return YES; +} + +- (BOOL)textFieldShouldClear:(UITextField *)textField +{ + if (textField == addAddressTextField) + { + textField.text = @"#"; + return NO; + } + return YES; +} + +- (BOOL)textFieldShouldReturn:(UITextField *)textField +{ + if (textField == addAddressTextField) + { + // Dismiss the keyboard + [addAddressTextField resignFirstResponder]; + + NSString *roomAlias = addAddressTextField.text; + if (!roomAlias.length || [self addRoomAlias:roomAlias]) + { + // Reset the input field + addAddressTextField.text = nil; + } + } + + return YES; +} + #pragma mark - actions - (IBAction)onTextFieldUpdate:(UITextField*)textField { - if (nameTextField == textField) + if (textField == nameTextField) { NSString* currentName = mxRoomState.name; @@ -1109,6 +1310,7 @@ - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger { roomAddresses = nil; localAddressesCount = 0; + roomAddressNewAliasIndex = -1; NSArray *removedAliases = [updatedItemsDict objectForKey:kRoomSettingsRemovedAliasesKey]; @@ -1144,7 +1346,21 @@ - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger localAddressesCount++; } - return (localAddressesCount ? roomAddresses.count : roomAddresses.count + 1); + NSInteger count = (localAddressesCount ? roomAddresses.count : roomAddresses.count + 1); + + if (self.mainSession) + { + // Check user's power level to know whether the user is allowed to add room alias + MXRoomPowerLevels *powerLevels = [mxRoom.state powerLevels]; + NSInteger oneSelfPowerLevel = [powerLevels powerLevelOfUserWithUserID:self.mainSession.myUser.userId]; + + if (oneSelfPowerLevel >= [powerLevels minimumPowerLevelForSendingEventAsStateEvent:kMXEventTypeStringRoomAliases]) + { + roomAddressNewAliasIndex = count++; + } + } + + return count; } else if (section == ROOM_SETTINGS_ADVANCED_SECTION_INDEX) { @@ -1267,7 +1483,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N } else if (row == ROOM_SETTINGS_MAIN_SECTION_ROW_TOPIC) { - TableViewCellWithLabelAndLargeTextView *roomTopicCell = [tableView dequeueReusableCellWithIdentifier:[TableViewCellWithLabelAndLargeTextView defaultReuseIdentifier] forIndexPath:indexPath]; + TableViewCellWithLabelAndLargeTextView *roomTopicCell = [tableView dequeueReusableCellWithIdentifier:kRoomSettingsTopicCellViewIdentifier forIndexPath:indexPath]; roomTopicCell.label.text = NSLocalizedStringFromTable(@"room_details_topic", @"Vector", nil); @@ -1295,7 +1511,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N } else if (row == ROOM_SETTINGS_MAIN_SECTION_ROW_NAME) { - MXKTableViewCellWithLabelAndTextField *roomNameCell = [tableView dequeueReusableCellWithIdentifier:[MXKTableViewCellWithLabelAndTextField defaultReuseIdentifier] forIndexPath:indexPath]; + MXKTableViewCellWithLabelAndTextField *roomNameCell = [tableView dequeueReusableCellWithIdentifier:kRoomSettingsNameCellViewIdentifier forIndexPath:indexPath]; UIEdgeInsets separatorInset = roomNameCell.separatorInset; @@ -1306,6 +1522,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N roomNameCell.mxkLabel.textColor = kVectorTextColorBlack; roomNameCell.accessoryType = UITableViewCellAccessoryNone; + roomNameCell.accessoryView = nil; nameTextField = roomNameCell.mxkTextField; @@ -1418,52 +1635,6 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N { // Use the last retrieved value if any directoryVisibilitySwitch.on = actualDirectoryVisibility ? [actualDirectoryVisibility isEqualToString:kMXRoomDirectoryVisibilityPublic] : NO; - - // Trigger a request to check the actual directory visibility - [self startActivityIndicator]; - - __weak typeof(self) weakSelf = self; - - pendingOperation = [mxRoom directoryVisibility:^(MXRoomDirectoryVisibility directoryVisibility) { - - if (weakSelf) - { - __strong __typeof(weakSelf)strongSelf = weakSelf; - strongSelf->pendingOperation = nil; - - strongSelf->actualDirectoryVisibility = directoryVisibility; - - // Check a potential change before update - if ([updatedItemsDict objectForKey:kRoomSettingsDirectoryKey]) - { - if (directoryVisibilitySwitch.on == ([directoryVisibility isEqualToString:kMXRoomDirectoryVisibilityPublic])) - { - // The requested change corresponds to the actual settings - [updatedItemsDict removeObjectForKey:kRoomSettingsDirectoryKey]; - - [self getNavigationItem].rightBarButtonItem.enabled = (updatedItemsDict.count != 0); - } - } - else - { - directoryVisibilitySwitch.on = ([directoryVisibility isEqualToString:kMXRoomDirectoryVisibilityPublic]); - } - - [strongSelf stopActivityIndicator]; - } - - } failure:^(NSError *error) { - - NSLog(@"[RoomSettingsViewController] request to get directory visibility failed"); - - if (weakSelf) - { - __strong __typeof(weakSelf)strongSelf = weakSelf; - strongSelf->pendingOperation = nil; - - [strongSelf stopActivityIndicator]; - } - }]; } // Check whether the user can change this option @@ -1582,52 +1753,90 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N } else if (indexPath.section == ROOM_SETTINGS_ROOM_ADDRESSES_SECTION_INDEX) { - MXKTableViewCell *addressCell = [tableView dequeueReusableCellWithIdentifier:[MXKTableViewCell defaultReuseIdentifier] forIndexPath:indexPath]; - - addressCell.textLabel.font = [UIFont systemFontOfSize:16]; - addressCell.textLabel.textColor = kVectorTextColorBlack; - addressCell.textLabel.lineBreakMode = NSLineBreakByTruncatingMiddle; - addressCell.accessoryView = nil; - addressCell.accessoryType = UITableViewCellAccessoryNone; - addressCell.selectionStyle = UITableViewCellSelectionStyleNone; - - // Check whether there is no local addresses - if (localAddressesCount == 0 && indexPath.row == 0) + if (indexPath.row == roomAddressNewAliasIndex) { - addressCell.textLabel.text = NSLocalizedStringFromTable(@"room_details_no_local_addresses", @"Vector", nil); + MXKTableViewCellWithLabelAndTextField *addAddressCell = [tableView dequeueReusableCellWithIdentifier:kRoomSettingsAddressCellViewIdentifier forIndexPath:indexPath]; + + // Retrieve the current edited value if any + NSString *currentValue = (addAddressTextField ? addAddressTextField.text : nil); + + UIEdgeInsets separatorInset = addAddressCell.separatorInset; + + addAddressCell.mxkLabelLeadingConstraint.constant = 0; + addAddressCell.mxkTextFieldLeadingConstraint.constant = separatorInset.left; + addAddressCell.mxkTextFieldTrailingConstraint.constant = 15; + + addAddressCell.mxkLabel.text = nil; + + addAddressCell.accessoryType = UITableViewCellAccessoryNone; + addAddressCell.accessoryView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"plus_icon"]]; + + addAddressTextField = addAddressCell.mxkTextField; + addAddressTextField.placeholder = NSLocalizedStringFromTable(@"room_details_new_address_placeholder", @"Vector", nil); + addAddressTextField.userInteractionEnabled = YES; + addAddressTextField.text = currentValue; + addAddressTextField.textColor = kVectorTextColorGray; + + addAddressTextField.tintColor = kVectorColorGreen; + addAddressTextField.font = [UIFont systemFontOfSize:17]; + addAddressTextField.borderStyle = UITextBorderStyleNone; + addAddressTextField.textAlignment = NSTextAlignmentLeft; + + addAddressTextField.autocorrectionType = UITextAutocorrectionTypeNo; + addAddressTextField.spellCheckingType = UITextSpellCheckingTypeNo; + addAddressTextField.delegate = self; + + cell = addAddressCell; } else { - NSInteger row = (localAddressesCount ? indexPath.row : indexPath.row - 1); + MXKTableViewCell *addressCell = [tableView dequeueReusableCellWithIdentifier:[MXKTableViewCell defaultReuseIdentifier] forIndexPath:indexPath]; - if (row < roomAddresses.count) + addressCell.textLabel.font = [UIFont systemFontOfSize:16]; + addressCell.textLabel.textColor = kVectorTextColorBlack; + addressCell.textLabel.lineBreakMode = NSLineBreakByTruncatingMiddle; + addressCell.accessoryView = nil; + addressCell.accessoryType = UITableViewCellAccessoryNone; + addressCell.selectionStyle = UITableViewCellSelectionStyleNone; + + // Check whether there is no local addresses + if (localAddressesCount == 0 && indexPath.row == 0) { - NSString *alias = roomAddresses[indexPath.row]; - NSString *canonicalAlias; - - if ([updatedItemsDict objectForKey:kRoomSettingsCanonicalAliasKey]) - { - canonicalAlias = [updatedItemsDict objectForKey:kRoomSettingsCanonicalAliasKey]; - } - else - { - canonicalAlias = mxRoomState.canonicalAlias; - } - - addressCell.textLabel.text = alias; + addressCell.textLabel.text = NSLocalizedStringFromTable(@"room_details_no_local_addresses", @"Vector", nil); + } + else + { + NSInteger row = (localAddressesCount ? indexPath.row : indexPath.row - 1); - // Check whether this alias is the main address - if (canonicalAlias) + if (row < roomAddresses.count) { - if ([alias isEqualToString:canonicalAlias]) + NSString *alias = roomAddresses[indexPath.row]; + NSString *canonicalAlias; + + if ([updatedItemsDict objectForKey:kRoomSettingsCanonicalAliasKey]) + { + canonicalAlias = [updatedItemsDict objectForKey:kRoomSettingsCanonicalAliasKey]; + } + else { - addressCell.accessoryView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"main_alias_icon"]]; + canonicalAlias = mxRoomState.canonicalAlias; + } + + addressCell.textLabel.text = alias; + + // Check whether this alias is the main address + if (canonicalAlias) + { + if ([alias isEqualToString:canonicalAlias]) + { + addressCell.accessoryView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"main_alias_icon"]]; + } } } } + + cell = addressCell; } - - cell = addressCell; } else if (indexPath.section == ROOM_SETTINGS_ADVANCED_SECTION_INDEX) { @@ -1653,11 +1862,18 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath { - if (indexPath.section == ROOM_SETTINGS_ROOM_ADDRESSES_SECTION_INDEX) + if (indexPath.section == ROOM_SETTINGS_ROOM_ADDRESSES_SECTION_INDEX && indexPath.row != roomAddressNewAliasIndex) { if (localAddressesCount != 0 || indexPath.row != 0) { - return YES; + // Check user's power level to know whether the user is allowed to remove room alias + MXRoomPowerLevels *powerLevels = [mxRoom.state powerLevels]; + NSInteger oneSelfPowerLevel = [powerLevels powerLevelOfUserWithUserID:self.mainSession.myUser.userId]; + + if (oneSelfPowerLevel >= [powerLevels minimumPowerLevelForSendingEventAsStateEvent:kMXEventTypeStringRoomAliases]) + { + return YES; + } } } return NO; @@ -1682,6 +1898,13 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath { [self onRoomAvatarTap:nil]; } + else if (indexPath.row == ROOM_SETTINGS_MAIN_SECTION_ROW_TOPIC) + { + if (topicTextView.editable) + { + [self editRoomTopic]; + } + } } else if (indexPath.section == ROOM_SETTINGS_ROOM_ACCESS_SECTION_INDEX) { @@ -1835,51 +2058,63 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath } } } - else if (indexPath.section == ROOM_SETTINGS_ROOM_ADDRESSES_SECTION_INDEX && (localAddressesCount != 0 || indexPath.row != 0)) + else if (indexPath.section == ROOM_SETTINGS_ROOM_ADDRESSES_SECTION_INDEX) { - NSInteger row = (localAddressesCount ? indexPath.row : indexPath.row - 1); - - if (row < roomAddresses.count) + if (indexPath.row == roomAddressNewAliasIndex) { - NSString *alias = roomAddresses[row]; - NSString *currentCanonicalAlias = mxRoomState.canonicalAlias; - NSString *canonicalAlias; - - if ([updatedItemsDict objectForKey:kRoomSettingsCanonicalAliasKey]) - { - canonicalAlias = [updatedItemsDict objectForKey:kRoomSettingsCanonicalAliasKey]; - } - else + NSString *roomAlias = addAddressTextField.text; + if (!roomAlias.length || [self addRoomAlias:roomAlias]) { - canonicalAlias = currentCanonicalAlias; + // Reset the input field + addAddressTextField.text = nil; } + } + else if (localAddressesCount != 0 || indexPath.row != 0) + { + NSInteger row = (localAddressesCount ? indexPath.row : indexPath.row - 1); - if (canonicalAlias) + if (row < roomAddresses.count) { - if ([alias isEqualToString:canonicalAlias]) + NSString *alias = roomAddresses[row]; + NSString *currentCanonicalAlias = mxRoomState.canonicalAlias; + NSString *canonicalAlias; + + if ([updatedItemsDict objectForKey:kRoomSettingsCanonicalAliasKey]) { - // Prompt user before removing the current main address - dispatch_async(dispatch_get_main_queue(), ^{ - [self shouldRemoveCanonicalAlias:nil]; - }); - + canonicalAlias = [updatedItemsDict objectForKey:kRoomSettingsCanonicalAliasKey]; } else { - // Update the current canonical address - if ([alias isEqualToString:currentCanonicalAlias]) + canonicalAlias = currentCanonicalAlias; + } + + if (canonicalAlias) + { + if ([alias isEqualToString:canonicalAlias]) { - [updatedItemsDict removeObjectForKey:kRoomSettingsCanonicalAliasKey]; + // Prompt user before removing the current main address + dispatch_async(dispatch_get_main_queue(), ^{ + [self shouldRemoveCanonicalAlias:nil]; + }); + } else { - [updatedItemsDict setObject:alias forKey:kRoomSettingsCanonicalAliasKey]; + // Update the current canonical address + if ([alias isEqualToString:currentCanonicalAlias]) + { + [updatedItemsDict removeObjectForKey:kRoomSettingsCanonicalAliasKey]; + } + else + { + [updatedItemsDict setObject:alias forKey:kRoomSettingsCanonicalAliasKey]; + } + + NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(ROOM_SETTINGS_ROOM_ADDRESSES_SECTION_INDEX, 1)]; + [self.tableView reloadSections:indexSet withRowAnimation:UITableViewRowAnimationNone]; + + [self getNavigationItem].rightBarButtonItem.enabled = (updatedItemsDict.count != 0); } - - NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(ROOM_SETTINGS_ROOM_ADDRESSES_SECTION_INDEX, 1)]; - [self.tableView reloadSections:indexSet withRowAnimation:UITableViewRowAnimationNone]; - - [self getNavigationItem].rightBarButtonItem.enabled = (updatedItemsDict.count != 0); } } } @@ -1894,7 +2129,7 @@ - (NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NS NSMutableArray* actions; // Add the swipe to delete only on addresses section - if (indexPath.section == ROOM_SETTINGS_ROOM_ADDRESSES_SECTION_INDEX) + if (indexPath.section == ROOM_SETTINGS_ROOM_ADDRESSES_SECTION_INDEX && indexPath.row != roomAddressNewAliasIndex) { if (localAddressesCount != 0 || indexPath.row != 0) { @@ -2198,21 +2433,98 @@ - (void)removeRoomAlias:(NSString*)roomAlias } else { - NSMutableArray *removedAlias = [updatedItemsDict objectForKey:kRoomSettingsRemovedAliasesKey]; - if (!removedAlias) + // Check whether the alias has just been added + NSMutableArray *addedAlias = [updatedItemsDict objectForKey:kRoomSettingsNewAliasesKey]; + if (addedAlias && [addedAlias indexOfObject:roomAlias] != NSNotFound) { - removedAlias = [NSMutableArray array]; + [addedAlias removeObject:roomAlias]; + + if (!addedAlias.count) + { + [updatedItemsDict removeObjectForKey:kRoomSettingsNewAliasesKey]; + } + } + else + { + NSMutableArray *removedAlias = [updatedItemsDict objectForKey:kRoomSettingsRemovedAliasesKey]; + if (!removedAlias) + { + removedAlias = [NSMutableArray array]; + [updatedItemsDict setObject:removedAlias forKey:kRoomSettingsRemovedAliasesKey]; + } + + [removedAlias addObject:roomAlias]; } - [removedAlias addObject:roomAlias]; + NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(ROOM_SETTINGS_ROOM_ADDRESSES_SECTION_INDEX, 1)]; + [self.tableView reloadSections:indexSet withRowAnimation:UITableViewRowAnimationNone]; - [updatedItemsDict setObject:removedAlias forKey:kRoomSettingsRemovedAliasesKey]; + [self getNavigationItem].rightBarButtonItem.enabled = (updatedItemsDict.count != 0); + } +} + +- (BOOL)addRoomAlias:(NSString*)roomAlias +{ + // Check whether the provided alias is valid + if ([MXTools isMatrixRoomAlias:roomAlias]) + { + // Check whether this alias has just been deleted + NSMutableArray *removedAlias = [updatedItemsDict objectForKey:kRoomSettingsRemovedAliasesKey]; + if (removedAlias && [removedAlias indexOfObject:roomAlias] != NSNotFound) + { + [removedAlias removeObject:roomAlias]; + + if (!removedAlias.count) + { + [updatedItemsDict removeObjectForKey:kRoomSettingsRemovedAliasesKey]; + } + } + // Check whether this alias is not already defined for this room + else if (roomAddresses && [roomAddresses indexOfObject:roomAlias] == NSNotFound) + { + NSMutableArray *addedAlias = [updatedItemsDict objectForKey:kRoomSettingsNewAliasesKey]; + if (!addedAlias) + { + addedAlias = [NSMutableArray array]; + [updatedItemsDict setObject:addedAlias forKey:kRoomSettingsNewAliasesKey]; + } + + [addedAlias addObject:roomAlias]; + } NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(ROOM_SETTINGS_ROOM_ADDRESSES_SECTION_INDEX, 1)]; [self.tableView reloadSections:indexSet withRowAnimation:UITableViewRowAnimationNone]; [self getNavigationItem].rightBarButtonItem.enabled = (updatedItemsDict.count != 0); + + return YES; } + + // Prompt here user for invalid alias + __weak typeof(self) weakSelf = self; + + [currentAlert dismiss:NO]; + + NSString *alertMsg = [NSString stringWithFormat:NSLocalizedStringFromTable(@"room_details_addresses_invalid_address_prompt_msg", @"Vector", nil), roomAlias]; + + currentAlert = [[MXKAlert alloc] initWithTitle:NSLocalizedStringFromTable(@"room_details_addresses_invalid_address_prompt_title", @"Vector", nil) + message:alertMsg + style:MXKAlertStyleAlert]; + + currentAlert.cancelButtonIndex = [currentAlert addActionWithTitle:[NSBundle mxk_localizedStringForKey:@"ok"] + style:MXKAlertActionStyleDefault + handler:^(MXKAlert *alert) { + + if (weakSelf) + { + __strong __typeof(weakSelf)strongSelf = weakSelf; + strongSelf->currentAlert = nil; + } + }]; + + [currentAlert showInViewController:self]; + + return NO; } #pragma mark - TableViewCellWithCheckBoxesDelegate From d478d5a8d3ec6b3047f4c90f6112f8920cb77e29 Mon Sep 17 00:00:00 2001 From: giomfo Date: Tue, 12 Jul 2016 00:13:05 +0200 Subject: [PATCH 11/18] Room Settings: Add "Addresses" section #412 - Support tap on room id to copy it - Align the leading constraint of the content with the separatorInset.left of the cell. TODO - Support long tap to copy alias, copy links or remove alias --- Vector/Assets/en.lproj/Vector.strings | 5 +- .../RoomSettingsViewController.m | 100 +++++++++++--- .../ViewController/SettingsViewController.m | 130 ++++-------------- .../TableViewCellWithCheckBoxAndLabel.h | 2 + .../TableViewCellWithCheckBoxAndLabel.xib | 1 + .../TableViewCellWithLabelAndLargeTextView.h | 1 + .../TableViewCellWithLabelAndLargeTextView.m | 2 +- ...TableViewCellWithLabelAndLargeTextView.xib | 1 + 8 files changed, 119 insertions(+), 123 deletions(-) diff --git a/Vector/Assets/en.lproj/Vector.strings b/Vector/Assets/en.lproj/Vector.strings index 14dc47959a..cbaec311fa 100644 --- a/Vector/Assets/en.lproj/Vector.strings +++ b/Vector/Assets/en.lproj/Vector.strings @@ -270,7 +270,7 @@ "room_details_addresses_disable_main_address_prompt_title" = "Main address warning"; "room_details_addresses_disable_main_address_prompt_msg"="You will have no main address specified. The default main address for this room will be picked randomly"; "room_details_advanced_section"="Advanced"; -"room_details_advanced_room_id"="This room's internal ID is %@"; +"room_details_advanced_room_id"="Room ID:"; "room_details_fail_to_update_avatar" = "Fail to update the room photo"; "room_details_fail_to_update_room_name" = "Fail to update the room name"; "room_details_fail_to_update_topic" = "Fail to update the topic"; @@ -281,7 +281,8 @@ "room_details_fail_to_add_room_aliases" = "Fail to add the new room addresses"; "room_details_fail_to_remove_room_aliases" = "Fail to remove the room addresses"; "room_details_fail_to_update_room_canonical_alias" = "Fail to update the main address"; -"room_details_with_updates" = "Do you want to save changes?"; +"room_details_save_changes_prompt" = "Do you want to save changes?"; +"room_details_copy_room_id" = "Copy Room ID"; // Media picker "media_picker_library" = "Library"; diff --git a/Vector/ViewController/RoomSettingsViewController.m b/Vector/ViewController/RoomSettingsViewController.m index ee6107a4c0..939e7d402e 100644 --- a/Vector/ViewController/RoomSettingsViewController.m +++ b/Vector/ViewController/RoomSettingsViewController.m @@ -77,6 +77,7 @@ NSString *const kRoomSettingsNameCellViewIdentifier = @"kRoomSettingsNameCellViewIdentifier"; NSString *const kRoomSettingsTopicCellViewIdentifier = @"kRoomSettingsTopicCellViewIdentifier"; NSString *const kRoomSettingsAddressCellViewIdentifier = @"kRoomSettingsAddressCellViewIdentifier"; +NSString *const kRoomSettingsAdvancedCellViewIdentifier = @"kRoomSettingsAdvancedCellViewIdentifier"; @interface RoomSettingsViewController () { @@ -243,6 +244,12 @@ - (void)destroy { self.navigationItem.rightBarButtonItem.enabled = NO; + if (currentAlert) + { + [currentAlert dismiss:NO]; + currentAlert = nil; + } + if (uploader) { [uploader cancel]; @@ -423,7 +430,7 @@ - (void)promptUserToSaveChanges __weak typeof(self) weakSelf = self; - currentAlert = [[MXKAlert alloc] initWithTitle:nil message:NSLocalizedStringFromTable(@"room_details_with_updates", @"Vector", nil) style:MXKAlertStyleAlert]; + currentAlert = [[MXKAlert alloc] initWithTitle:nil message:NSLocalizedStringFromTable(@"room_details_save_changes_prompt", @"Vector", nil) style:MXKAlertStyleAlert]; currentAlert.cancelButtonIndex = [currentAlert addActionWithTitle:[NSBundle mxk_localizedStringForKey:@"no"] style:MXKAlertActionStyleCancel handler:^(MXKAlert *alert) { @@ -454,6 +461,43 @@ - (void)promptUserToSaveChanges [currentAlert showInViewController:self]; } +- (void)promptUserToCopyRoomId:(UILabel*)roomIdLabel +{ + if (roomIdLabel) + { + [currentAlert dismiss:NO]; + + __weak typeof(self) weakSelf = self; + + currentAlert = [[MXKAlert alloc] initWithTitle:nil message:nil style:MXKAlertStyleActionSheet]; + + [currentAlert addActionWithTitle:NSLocalizedStringFromTable(@"room_details_copy_room_id", @"Vector", nil) style:MXKAlertActionStyleDefault handler:^(MXKAlert *alert) { + + if (weakSelf) + { + __strong __typeof(weakSelf)strongSelf = weakSelf; + strongSelf->currentAlert = nil; + + [[UIPasteboard generalPasteboard] setString:roomIdLabel.text]; + } + + }]; + + currentAlert.cancelButtonIndex = [currentAlert addActionWithTitle:[NSBundle mxk_localizedStringForKey:@"cancel"] style:MXKAlertActionStyleDefault handler:^(MXKAlert *alert) { + + if (weakSelf) + { + __strong __typeof(weakSelf)strongSelf = weakSelf; + strongSelf->currentAlert = nil; + } + + }]; + + currentAlert.sourceView = roomIdLabel; + [currentAlert showInViewController:self]; + } +} + - (void)retrieveActualDirectoryVisibility { if (!mxRoom || actualDirectoryVisibilityRequest) @@ -1421,9 +1465,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N { MXKTableViewCellWithLabelAndSwitch *roomNotifCell = [tableView dequeueReusableCellWithIdentifier:[MXKTableViewCellWithLabelAndSwitch defaultReuseIdentifier] forIndexPath:indexPath]; - UIEdgeInsets separatorInset = roomNotifCell.separatorInset; - - roomNotifCell.mxkLabelLeadingConstraint.constant = separatorInset.left; + roomNotifCell.mxkLabelLeadingConstraint.constant = roomNotifCell.separatorInset.left; roomNotifCell.mxkSwitchTrailingConstraint.constant = 15; [roomNotifCell.mxkSwitch addTarget:self action:@selector(onSwitchUpdate:) forControlEvents:UIControlEventValueChanged]; @@ -1448,7 +1490,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N { MXKTableViewCellWithLabelAndMXKImageView *roomPhotoCell = [tableView dequeueReusableCellWithIdentifier:[MXKTableViewCellWithLabelAndMXKImageView defaultReuseIdentifier] forIndexPath:indexPath]; - roomPhotoCell.mxkLabelLeadingConstraint.constant = 15; + roomPhotoCell.mxkLabelLeadingConstraint.constant = roomPhotoCell.separatorInset.left; roomPhotoCell.mxkImageViewTrailingConstraint.constant = 10; roomPhotoCell.mxkImageViewWidthConstraint.constant = roomPhotoCell.mxkImageViewHeightConstraint.constant = 30; @@ -1485,6 +1527,8 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N { TableViewCellWithLabelAndLargeTextView *roomTopicCell = [tableView dequeueReusableCellWithIdentifier:kRoomSettingsTopicCellViewIdentifier forIndexPath:indexPath]; + roomTopicCell.labelLeadingConstraint.constant = roomTopicCell.separatorInset.left; + roomTopicCell.label.text = NSLocalizedStringFromTable(@"room_details_topic", @"Vector", nil); topicTextView = roomTopicCell.textView; @@ -1513,9 +1557,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N { MXKTableViewCellWithLabelAndTextField *roomNameCell = [tableView dequeueReusableCellWithIdentifier:kRoomSettingsNameCellViewIdentifier forIndexPath:indexPath]; - UIEdgeInsets separatorInset = roomNameCell.separatorInset; - - roomNameCell.mxkLabelLeadingConstraint.constant = separatorInset.left; + roomNameCell.mxkLabelLeadingConstraint.constant = roomNameCell.separatorInset.left; roomNameCell.mxkTextFieldTrailingConstraint.constant = 15; roomNameCell.mxkLabel.text = NSLocalizedStringFromTable(@"room_details_room_name", @"Vector", nil); @@ -1553,6 +1595,8 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N { roomTagCell = [tableView dequeueReusableCellWithIdentifier:[TableViewCellWithCheckBoxes defaultReuseIdentifier] forIndexPath:indexPath]; + roomTagCell.mainContainerLeadingConstraint.constant = roomTagCell.separatorInset.left; + roomTagCell.checkBoxesNumber = 2; roomTagCell.allowsMultipleSelection = NO; @@ -1614,9 +1658,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N { MXKTableViewCellWithLabelAndSwitch *directoryToggleCell = [tableView dequeueReusableCellWithIdentifier:[MXKTableViewCellWithLabelAndSwitch defaultReuseIdentifier] forIndexPath:indexPath]; - UIEdgeInsets separatorInset = directoryToggleCell.separatorInset; - - directoryToggleCell.mxkLabelLeadingConstraint.constant = separatorInset.left; + directoryToggleCell.mxkLabelLeadingConstraint.constant = directoryToggleCell.separatorInset.left; directoryToggleCell.mxkSwitchTrailingConstraint.constant = 15; directoryToggleCell.mxkLabel.text = NSLocalizedStringFromTable(@"room_details_access_section_directory_toggle", @"Vector", nil); @@ -1646,6 +1688,8 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N { TableViewCellWithCheckBoxAndLabel *roomAccessCell = [tableView dequeueReusableCellWithIdentifier:[TableViewCellWithCheckBoxAndLabel defaultReuseIdentifier] forIndexPath:indexPath]; + roomAccessCell.checkBoxLeadingConstraint.constant = roomAccessCell.separatorInset.left; + // Retrieve the potential updated values for joinRule and guestAccess NSString *joinRule = [updatedItemsDict objectForKey:kRoomSettingsJoinRuleKey]; NSString *guestAccess = [updatedItemsDict objectForKey:kRoomSettingsGuestAccessKey]; @@ -1699,6 +1743,8 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N { TableViewCellWithCheckBoxAndLabel *historyVisibilityCell = [tableView dequeueReusableCellWithIdentifier:[TableViewCellWithCheckBoxAndLabel defaultReuseIdentifier] forIndexPath:indexPath]; + historyVisibilityCell.checkBoxLeadingConstraint.constant = historyVisibilityCell.separatorInset.left; + // Retrieve first the potential updated value for history visibility NSString *visibility = [updatedItemsDict objectForKey:kRoomSettingsHistoryVisibilityKey]; @@ -1760,10 +1806,8 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N // Retrieve the current edited value if any NSString *currentValue = (addAddressTextField ? addAddressTextField.text : nil); - UIEdgeInsets separatorInset = addAddressCell.separatorInset; - addAddressCell.mxkLabelLeadingConstraint.constant = 0; - addAddressCell.mxkTextFieldLeadingConstraint.constant = separatorInset.left; + addAddressCell.mxkTextFieldLeadingConstraint.constant = addAddressCell.separatorInset.left; addAddressCell.mxkTextFieldTrailingConstraint.constant = 15; addAddressCell.mxkLabel.text = nil; @@ -1840,14 +1884,22 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N } else if (indexPath.section == ROOM_SETTINGS_ADVANCED_SECTION_INDEX) { - MXKTableViewCell *roomIdCell = [tableView dequeueReusableCellWithIdentifier:[MXKTableViewCell defaultReuseIdentifier] forIndexPath:indexPath]; + cell = [tableView dequeueReusableCellWithIdentifier:kRoomSettingsAdvancedCellViewIdentifier]; + if (!cell) + { + cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:kRoomSettingsAdvancedCellViewIdentifier]; + } - roomIdCell.textLabel.font = [UIFont systemFontOfSize:16]; - roomIdCell.textLabel.text = [NSString stringWithFormat:NSLocalizedStringFromTable(@"room_details_advanced_room_id", @"Vector", nil), mxRoomState.roomId]; - roomIdCell.textLabel.textColor = kVectorTextColorBlack; - roomIdCell.selectionStyle = UITableViewCellSelectionStyleNone; + cell.textLabel.font = [UIFont systemFontOfSize:17]; + cell.textLabel.text = NSLocalizedStringFromTable(@"room_details_advanced_room_id", @"Vector", nil); + cell.textLabel.textColor = kVectorTextColorBlack; - cell = roomIdCell; + cell.detailTextLabel.font = [UIFont systemFontOfSize:15]; + cell.detailTextLabel.text = mxRoomState.roomId; + cell.detailTextLabel.textColor = kVectorTextColorGray; + cell.detailTextLabel.lineBreakMode = NSLineBreakByTruncatingMiddle; + + cell.selectionStyle = UITableViewCellSelectionStyleNone; } // Sanity check @@ -2119,6 +2171,14 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath } } } + else if (indexPath.section == ROOM_SETTINGS_ADVANCED_SECTION_INDEX) + { + UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; + if (cell) + { + [self promptUserToCopyRoomId:cell.detailTextLabel]; + } + } [tableView deselectRowAtIndexPath:indexPath animated:YES]; } diff --git a/Vector/ViewController/SettingsViewController.m b/Vector/ViewController/SettingsViewController.m index 88fd0a3ab3..edc2c8ba52 100644 --- a/Vector/ViewController/SettingsViewController.m +++ b/Vector/ViewController/SettingsViewController.m @@ -136,6 +136,10 @@ - (void)viewDidLoad self.tableView.backgroundColor = kVectorColorLightGrey; + [self.tableView registerClass:MXKTableViewCellWithLabelAndTextField.class forCellReuseIdentifier:[MXKTableViewCellWithLabelAndTextField defaultReuseIdentifier]]; + [self.tableView registerClass:MXKTableViewCellWithLabelAndSwitch.class forCellReuseIdentifier:[MXKTableViewCellWithLabelAndSwitch defaultReuseIdentifier]]; + [self.tableView registerClass:MXKTableViewCellWithLabelAndMXKImageView.class forCellReuseIdentifier:[MXKTableViewCellWithLabelAndMXKImageView defaultReuseIdentifier]]; + // Add observer to handle removed accounts removedAccountObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMXKAccountManagerDidRemoveAccountNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) { @@ -559,19 +563,12 @@ - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger return count; } -- (MXKTableViewCellWithLabelAndTextField*)getLabelAndTextFieldCell:(UITableView*)tableview +- (MXKTableViewCellWithLabelAndTextField*)getLabelAndTextFieldCell:(UITableView*)tableview forIndexPath:(NSIndexPath *)indexPath { - MXKTableViewCellWithLabelAndTextField *cell = [tableview dequeueReusableCellWithIdentifier:[MXKTableViewCellWithLabelAndTextField defaultReuseIdentifier]]; + MXKTableViewCellWithLabelAndTextField *cell = [tableview dequeueReusableCellWithIdentifier:[MXKTableViewCellWithLabelAndTextField defaultReuseIdentifier] forIndexPath:indexPath]; - if (!cell) - { - cell = [[MXKTableViewCellWithLabelAndTextField alloc] init]; - - UIEdgeInsets separatorInset = cell.separatorInset; - - cell.mxkLabelLeadingConstraint.constant = separatorInset.left; - cell.mxkTextFieldTrailingConstraint.constant = 15; - } + cell.mxkLabelLeadingConstraint.constant = cell.separatorInset.left; + cell.mxkTextFieldTrailingConstraint.constant = 15; cell.mxkLabel.textColor = kVectorTextColorBlack; @@ -589,19 +586,12 @@ - (MXKTableViewCellWithLabelAndTextField*)getLabelAndTextFieldCell:(UITableView* return cell; } -- (MXKTableViewCellWithLabelAndSwitch*)getLabelAndSwitchCell:(UITableView*)tableview +- (MXKTableViewCellWithLabelAndSwitch*)getLabelAndSwitchCell:(UITableView*)tableview forIndexPath:(NSIndexPath *)indexPath { - MXKTableViewCellWithLabelAndSwitch *cell = [tableview dequeueReusableCellWithIdentifier:[MXKTableViewCellWithLabelAndSwitch defaultReuseIdentifier]]; + MXKTableViewCellWithLabelAndSwitch *cell = [tableview dequeueReusableCellWithIdentifier:[MXKTableViewCellWithLabelAndSwitch defaultReuseIdentifier] forIndexPath:indexPath]; - if (!cell) - { - cell = [[MXKTableViewCellWithLabelAndSwitch alloc] init]; - - UIEdgeInsets separatorInset = cell.separatorInset; - - cell.mxkLabelLeadingConstraint.constant = separatorInset.left; - cell.mxkSwitchTrailingConstraint.constant = 15; - } + cell.mxkLabelLeadingConstraint.constant = cell.separatorInset.left; + cell.mxkSwitchTrailingConstraint.constant = 15; cell.mxkLabel.textColor = kVectorTextColorBlack; @@ -653,19 +643,16 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N if (row == userSettingsProfilePictureIndex) { - MXKTableViewCellWithLabelAndMXKImageView *profileCell = [tableView dequeueReusableCellWithIdentifier:[MXKTableViewCellWithLabelAndMXKImageView defaultReuseIdentifier]]; + MXKTableViewCellWithLabelAndMXKImageView *profileCell = [tableView dequeueReusableCellWithIdentifier:[MXKTableViewCellWithLabelAndMXKImageView defaultReuseIdentifier] forIndexPath:indexPath]; + + profileCell.mxkLabelLeadingConstraint.constant = profileCell.separatorInset.left; + profileCell.mxkImageViewTrailingConstraint.constant = 10; - if (!profileCell) + profileCell.mxkImageViewWidthConstraint.constant = profileCell.mxkImageViewHeightConstraint.constant = 30; + profileCell.mxkImageViewDisplayBoxType = MXKTableViewCellDisplayBoxTypeCircle; + + if (!profileCell.mxkImageView.gestureRecognizers.count) { - profileCell = [[MXKTableViewCellWithLabelAndMXKImageView alloc] init]; - - profileCell.mxkLabelLeadingConstraint.constant = 15; - profileCell.mxkImageViewTrailingConstraint.constant = 10; - - profileCell.mxkImageViewWidthConstraint.constant = profileCell.mxkImageViewHeightConstraint.constant = 30; - - profileCell.mxkImageViewDisplayBoxType = MXKTableViewCellDisplayBoxTypeCircle; - // tap on avatar to update it UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onProfileAvatarTap:)]; [profileCell.mxkImageView addGestureRecognizer:tap]; @@ -699,7 +686,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N } else if (row == userSettingsDisplayNameIndex) { - MXKTableViewCellWithLabelAndTextField *displaynameCell = [self getLabelAndTextFieldCell:tableView]; + MXKTableViewCellWithLabelAndTextField *displaynameCell = [self getLabelAndTextFieldCell:tableView forIndexPath:indexPath]; displaynameCell.mxkLabel.text = NSLocalizedStringFromTable(@"settings_display_name", @"Vector", nil); displaynameCell.mxkTextField.text = myUser.displayname; @@ -712,7 +699,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N } else if (row == userSettingsFirstNameIndex) { - MXKTableViewCellWithLabelAndTextField *firstCell = [self getLabelAndTextFieldCell:tableView]; + MXKTableViewCellWithLabelAndTextField *firstCell = [self getLabelAndTextFieldCell:tableView forIndexPath:indexPath]; firstCell.mxkLabel.text = NSLocalizedStringFromTable(@"settings_first_name", @"Vector", nil); firstCell.mxkTextField.userInteractionEnabled = NO; @@ -721,7 +708,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N } else if (row == userSettingsSurnameIndex) { - MXKTableViewCellWithLabelAndTextField *surnameCell = [self getLabelAndTextFieldCell:tableView]; + MXKTableViewCellWithLabelAndTextField *surnameCell = [self getLabelAndTextFieldCell:tableView forIndexPath:indexPath]; surnameCell.mxkLabel.text = NSLocalizedStringFromTable(@"settings_surname", @"Vector", nil); surnameCell.mxkTextField.userInteractionEnabled = NO; @@ -730,7 +717,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N } else if (userSettingsEmailStartIndex <= row && row < userSettingsNewEmailIndex) { - MXKTableViewCellWithLabelAndTextField *emailCell = [self getLabelAndTextFieldCell:tableView]; + MXKTableViewCellWithLabelAndTextField *emailCell = [self getLabelAndTextFieldCell:tableView forIndexPath:indexPath]; emailCell.mxkLabel.text = NSLocalizedStringFromTable(@"settings_email_address", @"Vector", nil); emailCell.mxkTextField.text = account.linkedEmails[row - userSettingsEmailStartIndex]; @@ -740,7 +727,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N } else if (row == userSettingsNewEmailIndex) { - MXKTableViewCellWithLabelAndTextField *newEmailCell = [self getLabelAndTextFieldCell:tableView]; + MXKTableViewCellWithLabelAndTextField *newEmailCell = [self getLabelAndTextFieldCell:tableView forIndexPath:indexPath]; // Render the cell according to the `newEmailEditingEnabled` property if (!_newEmailEditingEnabled) @@ -782,7 +769,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N } else if (row == userSettingsChangePasswordIndex) { - MXKTableViewCellWithLabelAndTextField *passwordCell = [self getLabelAndTextFieldCell:tableView]; + MXKTableViewCellWithLabelAndTextField *passwordCell = [self getLabelAndTextFieldCell:tableView forIndexPath:indexPath]; passwordCell.mxkLabel.text = NSLocalizedStringFromTable(@"settings_change_password", @"Vector", nil); passwordCell.mxkTextField.text = @"*********"; @@ -792,7 +779,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N } else if (row == userSettingsPhoneNumberIndex) { - MXKTableViewCellWithLabelAndTextField *phonenumberCell = [self getLabelAndTextFieldCell:tableView]; + MXKTableViewCellWithLabelAndTextField *phonenumberCell = [self getLabelAndTextFieldCell:tableView forIndexPath:indexPath]; phonenumberCell.mxkLabel.text = NSLocalizedStringFromTable(@"settings_phone_number", @"Vector", nil); phonenumberCell.mxkTextField.userInteractionEnabled = NO; @@ -808,7 +795,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N } else if (row == userSettingsNightModeIndex) { - MXKTableViewCellWithLabelAndTextField *nightModeCell = [self getLabelAndTextFieldCell:tableView]; + MXKTableViewCellWithLabelAndTextField *nightModeCell = [self getLabelAndTextFieldCell:tableView forIndexPath:indexPath]; nightModeCell.mxkLabel.text = NSLocalizedStringFromTable(@"settings_night_mode", @"Vector", nil); nightModeCell.mxkTextField.userInteractionEnabled = NO; @@ -824,7 +811,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N if (row == NOTIFICATION_SETTINGS_ENABLE_PUSH_INDEX) { - MXKTableViewCellWithLabelAndSwitch* enableAllCell = [self getLabelAndSwitchCell:tableView]; + MXKTableViewCellWithLabelAndSwitch* enableAllCell = [self getLabelAndSwitchCell:tableView forIndexPath:indexPath]; enableAllCell.mxkLabel.text = NSLocalizedStringFromTable(@"settings_enable_push_notif", @"Vector", nil); enableAllCell.mxkSwitch.on = account.pushNotificationServiceIsActive; @@ -845,63 +832,6 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N globalInfoCell.textLabel.numberOfLines = 0; cell = globalInfoCell; } -// else if (row == NOTIFICATION_SETTINGS_CONTAINING_MY_USER_NAME_INDEX) -// { -// MXKTableViewCellWithLabelAndSwitch* myNameCell = [self getLabelAndSwitchCell:tableView]; -// -// myNameCell.mxkLabel.text = NSLocalizedStringFromTable(@"settings_messages_my_user_name", @"Vector", nil); -// rule = [session.notificationCenter ruleById:kMXNotificationCenterContainUserNameRuleID]; -// cell = myNameCell; -// } -// else if (row == NOTIFICATION_SETTINGS_CONTAINING_MY_DISPLAY_NAME_INDEX) -// { -// MXKTableViewCellWithLabelAndSwitch* myNameCell = [self getLabelAndSwitchCell:tableView]; -// -// myNameCell.mxkLabel.text = NSLocalizedStringFromTable(@"settings_messages_my_display_name", @"Vector", nil); -// rule = [session.notificationCenter ruleById:kMXNotificationCenterContainDisplayNameRuleID]; -// cell = myNameCell; -// } -// else if (row == NOTIFICATION_SETTINGS_SENT_TO_ME_INDEX) -// { -// MXKTableViewCellWithLabelAndSwitch* sentToMeCell = [self getLabelAndSwitchCell:tableView]; -// sentToMeCell.mxkLabel.text = NSLocalizedStringFromTable(@"settings_messages_sent_to_me", @"Vector", nil); -// rule = [session.notificationCenter ruleById:kMXNotificationCenterOneToOneRoomRuleID]; -// cell = sentToMeCell; -// } -// else if (row == NOTIFICATION_SETTINGS_INVITED_TO_ROOM_INDEX) -// { -// MXKTableViewCellWithLabelAndSwitch* invitedToARoom = [self getLabelAndSwitchCell:tableView]; -// invitedToARoom.mxkLabel.text = NSLocalizedStringFromTable(@"settings_invited_to_room", @"Vector", nil); -// rule = [session.notificationCenter ruleById:kMXNotificationCenterInviteMeRuleID]; -// cell = invitedToARoom; -// } -// else if (row == NOTIFICATION_SETTINGS_PEOPLE_LEAVE_JOIN_INDEX) -// { -// MXKTableViewCellWithLabelAndSwitch* peopleJoinLeaveCell = [self getLabelAndSwitchCell:tableView]; -// peopleJoinLeaveCell.mxkLabel.text = NSLocalizedStringFromTable(@"settings_join_leave_rooms", @"Vector", nil); -// rule = [session.notificationCenter ruleById:kMXNotificationCenterMemberEventRuleID]; -// cell = peopleJoinLeaveCell; -// } -// else if (row == NOTIFICATION_SETTINGS_CALL_INVITATION_INDEX) -// { -// MXKTableViewCellWithLabelAndSwitch* callInvitationCell = [self getLabelAndSwitchCell:tableView]; -// callInvitationCell.mxkLabel.text = NSLocalizedStringFromTable(@"settings_call_invitations", @"Vector", nil); -// rule = [session.notificationCenter ruleById:kMXNotificationCenterCallRuleID]; -// cell = callInvitationCell; -// } - -// // common management -// MXKTableViewCellWithLabelAndSwitch* switchCell = (MXKTableViewCellWithLabelAndSwitch*)cell; -// switchCell.mxkSwitch.tag = row; -// -// if (rule) -// { -// switchCell.mxkSwitch.on = rule.enabled; -// } -// -// [switchCell.mxkSwitch removeTarget:self action:nil forControlEvents:UIControlEventTouchUpInside]; -// [switchCell.mxkSwitch addTarget:self action:@selector(onRuleUpdate:) forControlEvents:UIControlEventTouchUpInside]; - } else if (section == SETTINGS_SECTION_ADVANCED_INDEX) { @@ -983,7 +913,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N } else if (row == OTHER_CRASH_REPORT_INDEX) { - MXKTableViewCellWithLabelAndSwitch* sendCrashReportCell = [self getLabelAndSwitchCell:tableView]; + MXKTableViewCellWithLabelAndSwitch* sendCrashReportCell = [self getLabelAndSwitchCell:tableView forIndexPath:indexPath]; sendCrashReportCell.mxkLabel.text = NSLocalizedStringFromTable(@"settings_send_crash_report", @"Vector", nil); sendCrashReportCell.mxkSwitch.on = [[NSUserDefaults standardUserDefaults] boolForKey:@"enableCrashReport"]; diff --git a/Vector/Views/TableViewCell/TableViewCellWithCheckBoxAndLabel.h b/Vector/Views/TableViewCell/TableViewCellWithCheckBoxAndLabel.h index e3338008a0..bf6a6f14b9 100644 --- a/Vector/Views/TableViewCell/TableViewCellWithCheckBoxAndLabel.h +++ b/Vector/Views/TableViewCell/TableViewCellWithCheckBoxAndLabel.h @@ -23,4 +23,6 @@ @property (nonatomic, getter=isEnabled) BOOL enabled; +@property (weak, nonatomic) IBOutlet NSLayoutConstraint *checkBoxLeadingConstraint; + @end diff --git a/Vector/Views/TableViewCell/TableViewCellWithCheckBoxAndLabel.xib b/Vector/Views/TableViewCell/TableViewCellWithCheckBoxAndLabel.xib index 5cf36be251..e93af9266c 100644 --- a/Vector/Views/TableViewCell/TableViewCellWithCheckBoxAndLabel.xib +++ b/Vector/Views/TableViewCell/TableViewCellWithCheckBoxAndLabel.xib @@ -38,6 +38,7 @@ + diff --git a/Vector/Views/TableViewCell/TableViewCellWithLabelAndLargeTextView.h b/Vector/Views/TableViewCell/TableViewCellWithLabelAndLargeTextView.h index bf879c2735..c810ffbb19 100644 --- a/Vector/Views/TableViewCell/TableViewCellWithLabelAndLargeTextView.h +++ b/Vector/Views/TableViewCell/TableViewCellWithLabelAndLargeTextView.h @@ -22,6 +22,7 @@ @property (strong, nonatomic) IBOutlet UITextView *textView; @property (weak, nonatomic) IBOutlet NSLayoutConstraint *labelTrailingMinConstraint; +@property (weak, nonatomic) IBOutlet NSLayoutConstraint *labelLeadingConstraint; @property (weak, nonatomic) IBOutlet NSLayoutConstraint *textViewWidthConstraint; @property (weak, nonatomic) IBOutlet NSLayoutConstraint *textViewTrailingConstraint; diff --git a/Vector/Views/TableViewCell/TableViewCellWithLabelAndLargeTextView.m b/Vector/Views/TableViewCell/TableViewCellWithLabelAndLargeTextView.m index 62a0164ccf..40183a14d2 100644 --- a/Vector/Views/TableViewCell/TableViewCellWithLabelAndLargeTextView.m +++ b/Vector/Views/TableViewCell/TableViewCellWithLabelAndLargeTextView.m @@ -44,7 +44,7 @@ - (void)layoutSubviews CGFloat maxTextViewWidth = cellWidth - minTextViewPosX - _textViewTrailingConstraint.constant; - if (_textView.isFirstResponder) + if (_textView.isEditable && _textView.isFirstResponder) { // Use the full available width when the field is edited _textViewWidthConstraint.constant = maxTextViewWidth; diff --git a/Vector/Views/TableViewCell/TableViewCellWithLabelAndLargeTextView.xib b/Vector/Views/TableViewCell/TableViewCellWithLabelAndLargeTextView.xib index 8b4c4224a3..35cf1afa61 100644 --- a/Vector/Views/TableViewCell/TableViewCellWithLabelAndLargeTextView.xib +++ b/Vector/Views/TableViewCell/TableViewCellWithLabelAndLargeTextView.xib @@ -46,6 +46,7 @@ + From ce7f5febacaddb1ac70cec8e0a3b3a6bd33f3013 Mon Sep 17 00:00:00 2001 From: giomfo Date: Tue, 12 Jul 2016 14:41:16 +0200 Subject: [PATCH 12/18] Room Settings: Add "Addresses" section #412 - Support long tap to copy room address, copy room url or remove alias TODO - Add a notice "To link to a room it must have an address." when the user let anyone who knows the room's link access the room, whereas no address is defined --- Vector/Assets/en.lproj/Vector.strings | 4 +- .../RoomSettingsViewController.m | 117 ++++++++++++++++-- 2 files changed, 112 insertions(+), 9 deletions(-) diff --git a/Vector/Assets/en.lproj/Vector.strings b/Vector/Assets/en.lproj/Vector.strings index cbaec311fa..51b5c79dc1 100644 --- a/Vector/Assets/en.lproj/Vector.strings +++ b/Vector/Assets/en.lproj/Vector.strings @@ -264,7 +264,7 @@ "room_details_addresses_section"="Addresses"; "room_details_no_local_addresses" = "This room has no local addresses"; "room_details_new_address" = "Add new address"; -"room_details_new_address_placeholder" = "Add new address (e.g. #foo:example.org)"; +"room_details_new_address_placeholder" = "Add new address (e.g. #foo%@)"; "room_details_addresses_invalid_address_prompt_title" = "Invalid alias format"; "room_details_addresses_invalid_address_prompt_msg" = "%@ is not a valid format for an alias"; "room_details_addresses_disable_main_address_prompt_title" = "Main address warning"; @@ -283,6 +283,8 @@ "room_details_fail_to_update_room_canonical_alias" = "Fail to update the main address"; "room_details_save_changes_prompt" = "Do you want to save changes?"; "room_details_copy_room_id" = "Copy Room ID"; +"room_details_copy_room_address" = "Copy Room Address"; +"room_details_copy_room_url" = "Copy Room URL"; // Media picker "media_picker_library" = "Library"; diff --git a/Vector/ViewController/RoomSettingsViewController.m b/Vector/ViewController/RoomSettingsViewController.m index 939e7d402e..091cf05c37 100644 --- a/Vector/ViewController/RoomSettingsViewController.m +++ b/Vector/ViewController/RoomSettingsViewController.m @@ -26,6 +26,7 @@ #import "VectorDesignValues.h" #import "AvatarGenerator.h" +#import "Tools.h" #import "MXRoom+Vector.h" @@ -76,6 +77,7 @@ NSString *const kRoomSettingsNameCellViewIdentifier = @"kRoomSettingsNameCellViewIdentifier"; NSString *const kRoomSettingsTopicCellViewIdentifier = @"kRoomSettingsTopicCellViewIdentifier"; +NSString *const kRoomSettingsNewAddressCellViewIdentifier = @"kRoomSettingsNewAddressCellViewIdentifier"; NSString *const kRoomSettingsAddressCellViewIdentifier = @"kRoomSettingsAddressCellViewIdentifier"; NSString *const kRoomSettingsAdvancedCellViewIdentifier = @"kRoomSettingsAdvancedCellViewIdentifier"; @@ -162,6 +164,8 @@ - (void)viewDidLoad updatedItemsDict = [[NSMutableDictionary alloc] init]; historyVisibilityTickCells = [[NSMutableDictionary alloc] initWithCapacity:4]; + roomAddresses = [NSMutableArray array]; + [self.tableView registerClass:MXKTableViewCellWithLabelAndSwitch.class forCellReuseIdentifier:[MXKTableViewCellWithLabelAndSwitch defaultReuseIdentifier]]; [self.tableView registerClass:MXKTableViewCellWithLabelAndMXKImageView.class forCellReuseIdentifier:[MXKTableViewCellWithLabelAndMXKImageView defaultReuseIdentifier]]; @@ -169,7 +173,8 @@ - (void)viewDidLoad // on the text input field without being disturbed by the cell dequeuing process. [self.tableView registerClass:MXKTableViewCellWithLabelAndTextField.class forCellReuseIdentifier:kRoomSettingsNameCellViewIdentifier]; [self.tableView registerClass:TableViewCellWithLabelAndLargeTextView.class forCellReuseIdentifier:kRoomSettingsTopicCellViewIdentifier]; - [self.tableView registerClass:MXKTableViewCellWithLabelAndTextField.class forCellReuseIdentifier:kRoomSettingsAddressCellViewIdentifier]; + [self.tableView registerClass:MXKTableViewCellWithLabelAndTextField.class forCellReuseIdentifier:kRoomSettingsNewAddressCellViewIdentifier]; + [self.tableView registerClass:UITableViewCell.class forCellReuseIdentifier:kRoomSettingsAddressCellViewIdentifier]; [self.tableView registerClass:MXKTableViewCellWithButton.class forCellReuseIdentifier:[MXKTableViewCellWithButton defaultReuseIdentifier]]; [self.tableView registerClass:TableViewCellWithCheckBoxes.class forCellReuseIdentifier:[TableViewCellWithCheckBoxes defaultReuseIdentifier]]; @@ -498,6 +503,72 @@ - (void)promptUserToCopyRoomId:(UILabel*)roomIdLabel } } +- (void)promptUserOnSelectedRoomAlias:(UILabel*)roomAliasLabel +{ + if (roomAliasLabel) + { + [currentAlert dismiss:NO]; + + __weak typeof(self) weakSelf = self; + + currentAlert = [[MXKAlert alloc] initWithTitle:nil message:nil style:MXKAlertStyleActionSheet]; + + [currentAlert addActionWithTitle:NSLocalizedStringFromTable(@"room_details_copy_room_address", @"Vector", nil) style:MXKAlertActionStyleDefault handler:^(MXKAlert *alert) { + + if (weakSelf) + { + __strong __typeof(weakSelf)strongSelf = weakSelf; + strongSelf->currentAlert = nil; + + [[UIPasteboard generalPasteboard] setString:roomAliasLabel.text]; + } + + }]; + + [currentAlert addActionWithTitle:NSLocalizedStringFromTable(@"room_details_copy_room_url", @"Vector", nil) style:MXKAlertActionStyleDefault handler:^(MXKAlert *alert) { + + if (weakSelf) + { + __strong __typeof(weakSelf)strongSelf = weakSelf; + strongSelf->currentAlert = nil; + + // Create a room url that is common to all Vector.im clients + NSString *roomURL = [NSString stringWithFormat:@"%@/#/room/%@", + [Tools webAppUrl], + roomAliasLabel.text]; + + [[UIPasteboard generalPasteboard] setString:roomURL]; + } + + }]; + + [currentAlert addActionWithTitle:[NSBundle mxk_localizedStringForKey:@"delete"] style:MXKAlertActionStyleDefault handler:^(MXKAlert *alert) { + + if (weakSelf) + { + __strong __typeof(weakSelf)strongSelf = weakSelf; + strongSelf->currentAlert = nil; + + [strongSelf removeRoomAlias:roomAliasLabel.text]; + } + + }]; + + currentAlert.cancelButtonIndex = [currentAlert addActionWithTitle:[NSBundle mxk_localizedStringForKey:@"cancel"] style:MXKAlertActionStyleDefault handler:^(MXKAlert *alert) { + + if (weakSelf) + { + __strong __typeof(weakSelf)strongSelf = weakSelf; + strongSelf->currentAlert = nil; + } + + }]; + + currentAlert.sourceView = roomAliasLabel; + [currentAlert showInViewController:self]; + } +} + - (void)retrieveActualDirectoryVisibility { if (!mxRoom || actualDirectoryVisibilityRequest) @@ -1352,7 +1423,7 @@ - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger } else if (section == ROOM_SETTINGS_ROOM_ADDRESSES_SECTION_INDEX) { - roomAddresses = nil; + [roomAddresses removeAllObjects]; localAddressesCount = 0; roomAddressNewAliasIndex = -1; @@ -1361,8 +1432,6 @@ - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger NSArray *aliases = mxRoomState.aliases; if (aliases) { - roomAddresses = [NSMutableArray arrayWithCapacity:aliases.count]; - for (NSString *alias in aliases) { // Check whether the user did not remove it @@ -1801,7 +1870,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N { if (indexPath.row == roomAddressNewAliasIndex) { - MXKTableViewCellWithLabelAndTextField *addAddressCell = [tableView dequeueReusableCellWithIdentifier:kRoomSettingsAddressCellViewIdentifier forIndexPath:indexPath]; + MXKTableViewCellWithLabelAndTextField *addAddressCell = [tableView dequeueReusableCellWithIdentifier:kRoomSettingsNewAddressCellViewIdentifier forIndexPath:indexPath]; // Retrieve the current edited value if any NSString *currentValue = (addAddressTextField ? addAddressTextField.text : nil); @@ -1816,7 +1885,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N addAddressCell.accessoryView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"plus_icon"]]; addAddressTextField = addAddressCell.mxkTextField; - addAddressTextField.placeholder = NSLocalizedStringFromTable(@"room_details_new_address_placeholder", @"Vector", nil); + addAddressTextField.placeholder = [NSString stringWithFormat:NSLocalizedStringFromTable(@"room_details_new_address_placeholder", @"Vector", nil), self.mainSession.matrixRestClient.homeserverSuffix]; addAddressTextField.userInteractionEnabled = YES; addAddressTextField.text = currentValue; addAddressTextField.textColor = kVectorTextColorGray; @@ -1834,7 +1903,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N } else { - MXKTableViewCell *addressCell = [tableView dequeueReusableCellWithIdentifier:[MXKTableViewCell defaultReuseIdentifier] forIndexPath:indexPath]; + UITableViewCell *addressCell = [tableView dequeueReusableCellWithIdentifier:kRoomSettingsAddressCellViewIdentifier forIndexPath:indexPath]; addressCell.textLabel.font = [UIFont systemFontOfSize:16]; addressCell.textLabel.textColor = kVectorTextColorBlack; @@ -1843,6 +1912,12 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N addressCell.accessoryType = UITableViewCellAccessoryNone; addressCell.selectionStyle = UITableViewCellSelectionStyleNone; + while (addressCell.textLabel.gestureRecognizers.count) + { + [addressCell.textLabel removeGestureRecognizer:addressCell.textLabel.gestureRecognizers[0]]; + } + addressCell.textLabel.userInteractionEnabled = NO; + // Check whether there is no local addresses if (localAddressesCount == 0 && indexPath.row == 0) { @@ -1876,6 +1951,11 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N addressCell.accessoryView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"main_alias_icon"]]; } } + + // Add a long gesture recognizer on alias label + UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(onLongPressGesture:)]; + [addressCell.textLabel addGestureRecognizer:longPress]; + addressCell.textLabel.userInteractionEnabled = YES; } } @@ -2456,6 +2536,21 @@ - (void)onSwitchUpdate:(UISwitch*)theSwitch [self getNavigationItem].rightBarButtonItem.enabled = (updatedItemsDict.count != 0); } +- (IBAction)onLongPressGesture:(UILongPressGestureRecognizer*)longPressGestureRecognizer +{ + if (longPressGestureRecognizer.state == UIGestureRecognizerStateBegan) + { + UIView* view = longPressGestureRecognizer.view; + + if ([view isKindOfClass:UILabel.class]) + { + UILabel *aliasLabel = (UILabel*)view; + + [self promptUserOnSelectedRoomAlias:aliasLabel]; + } + } +} + - (void)removeAddressAtIndexPath:(NSIndexPath *)indexPath { NSInteger row = (localAddressesCount ? indexPath.row : indexPath.row - 1); @@ -2540,7 +2635,7 @@ - (BOOL)addRoomAlias:(NSString*)roomAlias } } // Check whether this alias is not already defined for this room - else if (roomAddresses && [roomAddresses indexOfObject:roomAlias] == NSNotFound) + else if ([roomAddresses indexOfObject:roomAlias] == NSNotFound) { NSMutableArray *addedAlias = [updatedItemsDict objectForKey:kRoomSettingsNewAliasesKey]; if (!addedAlias) @@ -2550,6 +2645,12 @@ - (BOOL)addRoomAlias:(NSString*)roomAlias } [addedAlias addObject:roomAlias]; + + if (!roomAddresses.count) + { + // The first created alias is defined as the main address by default + [updatedItemsDict setObject:roomAlias forKey:kRoomSettingsCanonicalAliasKey]; + } } NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(ROOM_SETTINGS_ROOM_ADDRESSES_SECTION_INDEX, 1)]; From 280ee809f0c6dcb3dfd80a4e8dfbcc879464b688 Mon Sep 17 00:00:00 2001 From: giomfo Date: Tue, 12 Jul 2016 17:22:06 +0200 Subject: [PATCH 13/18] Room Settings: Add "Addresses" section #412 - Add a notice "To link to a room it must have an address." when the user let anyone who knows the room's link access the room, whereas no address is defined --- Vector/Assets/en.lproj/Vector.strings | 1 + .../RoomSettingsViewController.m | 205 +++++++++++++----- 2 files changed, 148 insertions(+), 58 deletions(-) diff --git a/Vector/Assets/en.lproj/Vector.strings b/Vector/Assets/en.lproj/Vector.strings index 51b5c79dc1..3a2c846ef1 100644 --- a/Vector/Assets/en.lproj/Vector.strings +++ b/Vector/Assets/en.lproj/Vector.strings @@ -253,6 +253,7 @@ "room_details_access_section_invited_only"="Only people who have been invited"; "room_details_access_section_anyone_apart_from_guest"="Anyone who knows the room's link, apart from guests"; "room_details_access_section_anyone"="Anyone who knows the room's link, including guests"; +"room_details_access_section_no_address_warning" = "To link to a room it must have an address"; "room_details_access_section_directory_toggle"="List this room in room directory"; "room_details_history_section"="Who can read history?"; "room_details_history_section_anyone"="Anyone"; diff --git a/Vector/ViewController/RoomSettingsViewController.m b/Vector/ViewController/RoomSettingsViewController.m index 091cf05c37..b31b9910ce 100644 --- a/Vector/ViewController/RoomSettingsViewController.m +++ b/Vector/ViewController/RoomSettingsViewController.m @@ -50,8 +50,7 @@ #define ROOM_SETTINGS_ROOM_ACCESS_SECTION_ROW_INVITED_ONLY 0 #define ROOM_SETTINGS_ROOM_ACCESS_SECTION_ROW_ANYONE_APART_FROM_GUEST 1 #define ROOM_SETTINGS_ROOM_ACCESS_SECTION_ROW_ANYONE 2 -#define ROOM_SETTINGS_ROOM_ACCESS_SECTION_ROW_DIRECTORY_TOGGLE 3 -#define ROOM_SETTINGS_ROOM_ACCESS_SECTION_ROW_COUNT 4 +#define ROOM_SETTINGS_ROOM_ACCESS_SECTION_ROW_SUB_COUNT 3 #define ROOM_SETTINGS_HISTORY_VISIBILITY_SECTION_ROW_ANYONE 0 #define ROOM_SETTINGS_HISTORY_VISIBILITY_SECTION_ROW_MEMBERS_ONLY 1 @@ -77,6 +76,7 @@ NSString *const kRoomSettingsNameCellViewIdentifier = @"kRoomSettingsNameCellViewIdentifier"; NSString *const kRoomSettingsTopicCellViewIdentifier = @"kRoomSettingsTopicCellViewIdentifier"; +NSString *const kRoomSettingsWarningCellViewIdentifier = @"kRoomSettingsWarningCellViewIdentifier"; NSString *const kRoomSettingsNewAddressCellViewIdentifier = @"kRoomSettingsNewAddressCellViewIdentifier"; NSString *const kRoomSettingsAddressCellViewIdentifier = @"kRoomSettingsAddressCellViewIdentifier"; NSString *const kRoomSettingsAdvancedCellViewIdentifier = @"kRoomSettingsAdvancedCellViewIdentifier"; @@ -94,6 +94,8 @@ @interface RoomSettingsViewController () TableViewCellWithCheckBoxes *roomTagCell; // Room Access items + NSInteger directoryVisibilityIndex; + NSInteger missingAddressWarningIndex; TableViewCellWithCheckBoxAndLabel *accessInvitedOnlyTickCell; TableViewCellWithCheckBoxAndLabel *accessAnyoneApartGuestTickCell; TableViewCellWithCheckBoxAndLabel *accessAnyoneTickCell; @@ -175,6 +177,7 @@ - (void)viewDidLoad [self.tableView registerClass:TableViewCellWithLabelAndLargeTextView.class forCellReuseIdentifier:kRoomSettingsTopicCellViewIdentifier]; [self.tableView registerClass:MXKTableViewCellWithLabelAndTextField.class forCellReuseIdentifier:kRoomSettingsNewAddressCellViewIdentifier]; [self.tableView registerClass:UITableViewCell.class forCellReuseIdentifier:kRoomSettingsAddressCellViewIdentifier]; + [self.tableView registerClass:UITableViewCell.class forCellReuseIdentifier:kRoomSettingsWarningCellViewIdentifier]; [self.tableView registerClass:MXKTableViewCellWithButton.class forCellReuseIdentifier:[MXKTableViewCellWithButton defaultReuseIdentifier]]; [self.tableView registerClass:TableViewCellWithCheckBoxes.class forCellReuseIdentifier:[TableViewCellWithCheckBoxes defaultReuseIdentifier]]; @@ -1404,62 +1407,86 @@ - (IBAction)onSave:(id)sender - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { + // Refresh here the room addresses list + [roomAddresses removeAllObjects]; + localAddressesCount = 0; + + NSArray *removedAliases = [updatedItemsDict objectForKey:kRoomSettingsRemovedAliasesKey]; + + NSArray *aliases = mxRoomState.aliases; + if (aliases) + { + for (NSString *alias in aliases) + { + // Check whether the user did not remove it + if (!removedAliases || [removedAliases indexOfObject:alias] == NSNotFound) + { + // Add it + if ([alias hasSuffix:self.mainSession.matrixRestClient.homeserverSuffix]) + { + [roomAddresses insertObject:alias atIndex:localAddressesCount]; + localAddressesCount++; + } + else + { + [roomAddresses addObject:alias]; + } + } + } + } + + aliases = [updatedItemsDict objectForKey:kRoomSettingsNewAliasesKey]; + for (NSString *alias in aliases) + { + // Add this new alias to local addresses + [roomAddresses insertObject:alias atIndex:localAddressesCount]; + localAddressesCount++; + } + + // Return the fixed number of sections return ROOM_SETTINGS_SECTION_COUNT; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + NSInteger count = 0; + if (section == ROOM_SETTINGS_MAIN_SECTION_INDEX) { - return ROOM_SETTINGS_MAIN_SECTION_ROW_COUNT; + count = ROOM_SETTINGS_MAIN_SECTION_ROW_COUNT; } else if (section == ROOM_SETTINGS_ROOM_ACCESS_SECTION_INDEX) { - return ROOM_SETTINGS_ROOM_ACCESS_SECTION_ROW_COUNT; - } - else if (section == ROOM_SETTINGS_HISTORY_VISIBILITY_SECTION_INDEX) - { - return ROOM_SETTINGS_HISTORY_VISIBILITY_SECTION_ROW_COUNT; - } - else if (section == ROOM_SETTINGS_ROOM_ADDRESSES_SECTION_INDEX) - { - [roomAddresses removeAllObjects]; - localAddressesCount = 0; - roomAddressNewAliasIndex = -1; + missingAddressWarningIndex = -1; + directoryVisibilityIndex = -1; - NSArray *removedAliases = [updatedItemsDict objectForKey:kRoomSettingsRemovedAliasesKey]; + count = ROOM_SETTINGS_ROOM_ACCESS_SECTION_ROW_SUB_COUNT; - NSArray *aliases = mxRoomState.aliases; - if (aliases) + // Check whether a room address is required for the current join rule + NSString *joinRule = [updatedItemsDict objectForKey:kRoomSettingsJoinRuleKey]; + if (!joinRule) { - for (NSString *alias in aliases) - { - // Check whether the user did not remove it - if (!removedAliases || [removedAliases indexOfObject:alias] == NSNotFound) - { - // Add it - if ([alias hasSuffix:self.mainSession.matrixRestClient.homeserverSuffix]) - { - [roomAddresses insertObject:alias atIndex:localAddressesCount]; - localAddressesCount++; - } - else - { - [roomAddresses addObject:alias]; - } - } - } + // Use the actual values if no change is pending. + joinRule = mxRoomState.joinRule; } - aliases = [updatedItemsDict objectForKey:kRoomSettingsNewAliasesKey]; - for (NSString *alias in aliases) + if ([joinRule isEqualToString:kMXRoomJoinRulePublic] && !roomAddresses.count) { - // Add this new alias to local addresses - [roomAddresses insertObject:alias atIndex:localAddressesCount]; - localAddressesCount++; + // Notify the user that a room address is required. + missingAddressWarningIndex = count++; } - NSInteger count = (localAddressesCount ? roomAddresses.count : roomAddresses.count + 1); + directoryVisibilityIndex = count++; + } + else if (section == ROOM_SETTINGS_HISTORY_VISIBILITY_SECTION_INDEX) + { + count = ROOM_SETTINGS_HISTORY_VISIBILITY_SECTION_ROW_COUNT; + } + else if (section == ROOM_SETTINGS_ROOM_ADDRESSES_SECTION_INDEX) + { + roomAddressNewAliasIndex = -1; + + count = (localAddressesCount ? roomAddresses.count : roomAddresses.count + 1); if (self.mainSession) { @@ -1472,15 +1499,13 @@ - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger roomAddressNewAliasIndex = count++; } } - - return count; } else if (section == ROOM_SETTINGS_ADVANCED_SECTION_INDEX) { - return 1; + count = 1; } - return 0; + return count; } - (nullable NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section @@ -1723,7 +1748,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N } else if (indexPath.section == ROOM_SETTINGS_ROOM_ACCESS_SECTION_INDEX) { - if (indexPath.row == ROOM_SETTINGS_ROOM_ACCESS_SECTION_ROW_DIRECTORY_TOGGLE) + if (indexPath.row == directoryVisibilityIndex) { MXKTableViewCellWithLabelAndSwitch *directoryToggleCell = [tableView dequeueReusableCellWithIdentifier:[MXKTableViewCellWithLabelAndSwitch defaultReuseIdentifier] forIndexPath:indexPath]; @@ -1753,6 +1778,18 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N cell = directoryToggleCell; } + else if (indexPath.row == missingAddressWarningIndex) + { + cell = [tableView dequeueReusableCellWithIdentifier:kRoomSettingsWarningCellViewIdentifier forIndexPath:indexPath]; + + cell.textLabel.font = [UIFont systemFontOfSize:17]; + cell.textLabel.textColor = kVectorColorPinkRed; + cell.textLabel.lineBreakMode = NSLineBreakByTruncatingMiddle; + cell.accessoryView = nil; + cell.accessoryType = UITableViewCellAccessoryNone; + cell.selectionStyle = UITableViewCellSelectionStyleNone; + cell.textLabel.text = NSLocalizedStringFromTable(@"room_details_access_section_no_address_warning", @"Vector", nil); + } else { TableViewCellWithCheckBoxAndLabel *roomAccessCell = [tableView dequeueReusableCellWithIdentifier:[TableViewCellWithCheckBoxAndLabel defaultReuseIdentifier] forIndexPath:indexPath]; @@ -2040,6 +2077,8 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath } else if (indexPath.section == ROOM_SETTINGS_ROOM_ACCESS_SECTION_INDEX) { + BOOL isUpdated = NO; + if (indexPath.row == ROOM_SETTINGS_ROOM_ACCESS_SECTION_ROW_INVITED_ONLY) { // Ignore the selection if the option is already enabled @@ -2073,6 +2112,8 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath [updatedItemsDict setObject:kMXRoomGuestAccessCanJoin forKey:kRoomSettingsGuestAccessKey]; } } + + isUpdated = YES; } } else if (indexPath.row == ROOM_SETTINGS_ROOM_ACCESS_SECTION_ROW_ANYONE_APART_FROM_GUEST) @@ -2113,6 +2154,8 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath [updatedItemsDict setObject:kMXRoomGuestAccessForbidden forKey:kRoomSettingsGuestAccessKey]; } } + + isUpdated = YES; } } else if (indexPath.row == ROOM_SETTINGS_ROOM_ACCESS_SECTION_ROW_ANYONE) @@ -2153,10 +2196,24 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath [updatedItemsDict setObject:kMXRoomGuestAccessCanJoin forKey:kRoomSettingsGuestAccessKey]; } } + + isUpdated = YES; } } + else if (indexPath.row == missingAddressWarningIndex) + { + // Scroll to room addresses section + NSIndexPath *addressIndexPath = [NSIndexPath indexPathForRow:0 inSection:ROOM_SETTINGS_ROOM_ADDRESSES_SECTION_INDEX]; + [tableView scrollToRowAtIndexPath:addressIndexPath atScrollPosition:UITableViewScrollPositionTop animated:YES]; + } - [self getNavigationItem].rightBarButtonItem.enabled = (updatedItemsDict.count != 0); + if (isUpdated) + { + NSIndexSet *indexSet = [NSIndexSet indexSetWithIndex:ROOM_SETTINGS_ROOM_ACCESS_SECTION_INDEX]; + [self.tableView reloadSections:indexSet withRowAnimation:UITableViewRowAnimationNone]; + + [self getNavigationItem].rightBarButtonItem.enabled = (updatedItemsDict.count != 0); + } } else if (indexPath.section == ROOM_SETTINGS_HISTORY_VISIBILITY_SECTION_INDEX) { @@ -2224,11 +2281,12 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath { if ([alias isEqualToString:canonicalAlias]) { - // Prompt user before removing the current main address + // Prompt user before removing the current main address (use dispatch_async here to not be stuck by the table refresh). dispatch_async(dispatch_get_main_queue(), ^{ + [self shouldRemoveCanonicalAlias:nil]; + }); - } else { @@ -2242,7 +2300,7 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath [updatedItemsDict setObject:alias forKey:kRoomSettingsCanonicalAliasKey]; } - NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(ROOM_SETTINGS_ROOM_ADDRESSES_SECTION_INDEX, 1)]; + NSIndexSet *indexSet = [NSIndexSet indexSetWithIndex:ROOM_SETTINGS_ROOM_ADDRESSES_SECTION_INDEX]; [self.tableView reloadSections:indexSet withRowAnimation:UITableViewRowAnimationNone]; [self getNavigationItem].rightBarButtonItem.enabled = (updatedItemsDict.count != 0); @@ -2256,7 +2314,12 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; if (cell) { - [self promptUserToCopyRoomId:cell.detailTextLabel]; + // Prompt user to copy the room id (use dispatch_async here to not be stuck by the table refresh). + dispatch_async(dispatch_get_main_queue(), ^{ + + [self promptUserToCopyRoomId:cell.detailTextLabel]; + + }); } } @@ -2384,7 +2447,7 @@ - (void)shouldRemoveCanonicalAlias:(void (^)())didRemoveCanonicalAlias // Remove the canonical address [strongSelf->updatedItemsDict setObject:@"" forKey:kRoomSettingsCanonicalAliasKey]; - NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(ROOM_SETTINGS_ROOM_ADDRESSES_SECTION_INDEX, 1)]; + NSIndexSet *indexSet = [NSIndexSet indexSetWithIndex:ROOM_SETTINGS_ROOM_ADDRESSES_SECTION_INDEX]; [strongSelf.tableView reloadSections:indexSet withRowAnimation:UITableViewRowAnimationNone]; [strongSelf getNavigationItem].rightBarButtonItem.enabled = (strongSelf->updatedItemsDict.count != 0); @@ -2611,8 +2674,16 @@ - (void)removeRoomAlias:(NSString*)roomAlias [removedAlias addObject:roomAlias]; } - NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(ROOM_SETTINGS_ROOM_ADDRESSES_SECTION_INDEX, 1)]; - [self.tableView reloadSections:indexSet withRowAnimation:UITableViewRowAnimationNone]; + NSMutableIndexSet *mutableIndexSet = [NSMutableIndexSet indexSet]; + + if (roomAddresses.count <= 1) + { + // The user remove here all the room addresses, reload the room access section to display potential warning message + [mutableIndexSet addIndex:ROOM_SETTINGS_ROOM_ACCESS_SECTION_INDEX]; + } + + [mutableIndexSet addIndex:ROOM_SETTINGS_ROOM_ADDRESSES_SECTION_INDEX]; + [self.tableView reloadSections:mutableIndexSet withRowAnimation:UITableViewRowAnimationAutomatic]; [self getNavigationItem].rightBarButtonItem.enabled = (updatedItemsDict.count != 0); } @@ -2645,16 +2716,34 @@ - (BOOL)addRoomAlias:(NSString*)roomAlias } [addedAlias addObject:roomAlias]; - - if (!roomAddresses.count) + } + + NSMutableIndexSet *mutableIndexSet = [NSMutableIndexSet indexSet]; + + if (!roomAddresses.count) + { + // The first added alias is defined as the main address by default. + // Update the current canonical address. + NSString *currentCanonicalAlias = mxRoomState.canonicalAlias; + if (currentCanonicalAlias && [roomAlias isEqualToString:currentCanonicalAlias]) + { + // The right canonical alias is already defined + [updatedItemsDict removeObjectForKey:kRoomSettingsCanonicalAliasKey]; + } + else { - // The first created alias is defined as the main address by default [updatedItemsDict setObject:roomAlias forKey:kRoomSettingsCanonicalAliasKey]; } + + if (missingAddressWarningIndex != -1) + { + // Reload room access section to remove warning message + [mutableIndexSet addIndex:ROOM_SETTINGS_ROOM_ACCESS_SECTION_INDEX]; + } } - NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(ROOM_SETTINGS_ROOM_ADDRESSES_SECTION_INDEX, 1)]; - [self.tableView reloadSections:indexSet withRowAnimation:UITableViewRowAnimationNone]; + [mutableIndexSet addIndex:ROOM_SETTINGS_ROOM_ADDRESSES_SECTION_INDEX]; + [self.tableView reloadSections:mutableIndexSet withRowAnimation:UITableViewRowAnimationAutomatic]; [self getNavigationItem].rightBarButtonItem.enabled = (updatedItemsDict.count != 0); From f1c905981204302d38b93accbcb0cd387ff64659 Mon Sep 17 00:00:00 2001 From: giomfo Date: Tue, 12 Jul 2016 22:40:35 +0200 Subject: [PATCH 14/18] Enhancement - Messages: switch decline and preview buttons on invites https://github.com/vector-im/vector-ios/issues/447 --- Vector/ViewController/RoomViewController.m | 6 ++++-- Vector/Views/RoomList/InviteRecentTableViewCell.m | 12 ++++++------ Vector/Views/RoomTitle/PreviewRoomTitleView.m | 8 ++++---- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/Vector/ViewController/RoomViewController.m b/Vector/ViewController/RoomViewController.m index 85e4e40628..6079225883 100644 --- a/Vector/ViewController/RoomViewController.m +++ b/Vector/ViewController/RoomViewController.m @@ -1982,8 +1982,9 @@ - (void)roomTitleView:(RoomTitleView*)titleView recognizeTapGesture:(UITapGestur selectedRoomDetailsIndex = 0; [self performSegueWithIdentifier:@"showRoomDetails" sender:self]; } - else if (view == previewHeader.leftButton) + else if (view == previewHeader.rightButton) { + // 'Join' button has been pressed if (roomPreviewData) { // Attempt to join the room (keep reference on the potential eventId, the preview data will be removed automatically in case of success). @@ -2045,8 +2046,9 @@ - (void)roomTitleView:(RoomTitleView*)titleView recognizeTapGesture:(UITapGestur }]; } } - else if (view == previewHeader.rightButton) + else if (view == previewHeader.leftButton) { + // 'Decline' button has been pressed if (roomPreviewData) { // Decline this invitation = leave this page diff --git a/Vector/Views/RoomList/InviteRecentTableViewCell.m b/Vector/Views/RoomList/InviteRecentTableViewCell.m index 342f2a8e02..5e7941b6dc 100644 --- a/Vector/Views/RoomList/InviteRecentTableViewCell.m +++ b/Vector/Views/RoomList/InviteRecentTableViewCell.m @@ -40,17 +40,17 @@ - (void)awakeFromNib [self.leftButton.layer setCornerRadius:5]; self.leftButton.clipsToBounds = YES; self.leftButton.backgroundColor = kVectorColorGreen; - [self.leftButton setTitle:NSLocalizedStringFromTable(@"preview", @"Vector", nil) forState:UIControlStateNormal]; - [self.leftButton setTitle:NSLocalizedStringFromTable(@"preview", @"Vector", nil) forState:UIControlStateHighlighted]; - [self.leftButton addTarget:self action:@selector(onPreviewPressed:) forControlEvents:UIControlEventTouchUpInside]; + [self.leftButton setTitle:NSLocalizedStringFromTable(@"decline", @"Vector", nil) forState:UIControlStateNormal]; + [self.leftButton setTitle:NSLocalizedStringFromTable(@"decline", @"Vector", nil) forState:UIControlStateHighlighted]; + [self.leftButton addTarget:self action:@selector(onDeclinePressed:) forControlEvents:UIControlEventTouchUpInside]; [self.rightButton.layer setCornerRadius:5]; self.rightButton.clipsToBounds = YES; self.rightButton.backgroundColor = kVectorColorGreen; - [self.rightButton setTitle:NSLocalizedStringFromTable(@"decline", @"Vector", nil) forState:UIControlStateNormal]; - [self.rightButton setTitle:NSLocalizedStringFromTable(@"decline", @"Vector", nil) forState:UIControlStateHighlighted]; - [self.rightButton addTarget:self action:@selector(onDeclinePressed:) forControlEvents:UIControlEventTouchUpInside]; + [self.rightButton setTitle:NSLocalizedStringFromTable(@"preview", @"Vector", nil) forState:UIControlStateNormal]; + [self.rightButton setTitle:NSLocalizedStringFromTable(@"preview", @"Vector", nil) forState:UIControlStateHighlighted]; + [self.rightButton addTarget:self action:@selector(onPreviewPressed:) forControlEvents:UIControlEventTouchUpInside]; self.noticeBadgeView.backgroundColor = kVectorColorPinkRed; [self.noticeBadgeView.layer setCornerRadius:10]; diff --git a/Vector/Views/RoomTitle/PreviewRoomTitleView.m b/Vector/Views/RoomTitle/PreviewRoomTitleView.m index aeb34b0a3a..c3190c8b3f 100644 --- a/Vector/Views/RoomTitle/PreviewRoomTitleView.m +++ b/Vector/Views/RoomTitle/PreviewRoomTitleView.m @@ -54,8 +54,8 @@ - (void)awakeFromNib [self.leftButton.layer setCornerRadius:5]; self.leftButton.clipsToBounds = YES; self.leftButton.backgroundColor = kVectorColorGreen; - [self.leftButton setTitle:NSLocalizedStringFromTable(@"join", @"Vector", nil) forState:UIControlStateNormal]; - [self.leftButton setTitle:NSLocalizedStringFromTable(@"join", @"Vector", nil) forState:UIControlStateHighlighted]; + [self.leftButton setTitle:NSLocalizedStringFromTable(@"decline", @"Vector", nil) forState:UIControlStateNormal]; + [self.leftButton setTitle:NSLocalizedStringFromTable(@"decline", @"Vector", nil) forState:UIControlStateHighlighted]; UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(reportTapGesture:)]; [tap setNumberOfTouchesRequired:1]; [tap setNumberOfTapsRequired:1]; @@ -66,8 +66,8 @@ - (void)awakeFromNib [self.rightButton.layer setCornerRadius:5]; self.rightButton.clipsToBounds = YES; self.rightButton.backgroundColor = kVectorColorGreen; - [self.rightButton setTitle:NSLocalizedStringFromTable(@"decline", @"Vector", nil) forState:UIControlStateNormal]; - [self.rightButton setTitle:NSLocalizedStringFromTable(@"decline", @"Vector", nil) forState:UIControlStateHighlighted]; + [self.rightButton setTitle:NSLocalizedStringFromTable(@"join", @"Vector", nil) forState:UIControlStateNormal]; + [self.rightButton setTitle:NSLocalizedStringFromTable(@"join", @"Vector", nil) forState:UIControlStateHighlighted]; tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(reportTapGesture:)]; [tap setNumberOfTouchesRequired:1]; [tap setNumberOfTapsRequired:1]; From 26773e52406411762e08db30a2b5621c41d773ae Mon Sep 17 00:00:00 2001 From: giomfo Date: Wed, 13 Jul 2016 18:17:08 +0200 Subject: [PATCH 15/18] Bug Fix - Reported crash: App crashes during [AppDelegate applicationDidEnterBackground:] https://github.com/vector-im/vector-ios/issues/452 --- Vector/AppDelegate.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Vector/AppDelegate.m b/Vector/AppDelegate.m index c48d64bd79..5f916ddf18 100644 --- a/Vector/AppDelegate.m +++ b/Vector/AppDelegate.m @@ -360,7 +360,7 @@ - (void)applicationDidEnterBackground:(UIApplication *)application } [[AFNetworkReachabilityManager sharedManager] setReachabilityStatusChangeBlock:nil]; [[AFNetworkReachabilityManager sharedManager] stopMonitoring]; - self.isOffline = NO; + _isOffline = NO; // check if some media must be released to reduce the cache size [MXKMediaManager reduceCacheSizeToInsert:0]; From 8558a7dc24cd3dd9442040a66bd3c25b6cd8c6e6 Mon Sep 17 00:00:00 2001 From: giomfo Date: Fri, 15 Jul 2016 15:10:59 +0200 Subject: [PATCH 16/18] Chat Screen: Set the right tint color of the "send" button. --- Vector/Views/RoomInputToolbar/RoomInputToolbarView.m | 4 ++++ Vector/Views/RoomInputToolbar/RoomInputToolbarView.xib | 5 +++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/Vector/Views/RoomInputToolbar/RoomInputToolbarView.m b/Vector/Views/RoomInputToolbar/RoomInputToolbarView.m index a1f1da0b3d..2b45a22889 100644 --- a/Vector/Views/RoomInputToolbar/RoomInputToolbarView.m +++ b/Vector/Views/RoomInputToolbar/RoomInputToolbarView.m @@ -63,6 +63,9 @@ - (void)awakeFromNib self.rightInputToolbarButton.hidden = YES; + [self.rightInputToolbarButton setTitleColor:kVectorColorGreen forState:UIControlStateNormal]; + [self.rightInputToolbarButton setTitleColor:kVectorColorGreen forState:UIControlStateHighlighted]; + self.separatorView.backgroundColor = kVectorColorSilver; // Custom the growingTextView display @@ -72,6 +75,7 @@ - (void)awakeFromNib growingTextView.font = [UIFont systemFontOfSize:15]; growingTextView.textColor = kVectorTextColorBlack; + growingTextView.tintColor = kVectorColorGreen; self.placeholder = NSLocalizedStringFromTable(@"room_message_placeholder", @"Vector", nil); } diff --git a/Vector/Views/RoomInputToolbar/RoomInputToolbarView.xib b/Vector/Views/RoomInputToolbar/RoomInputToolbarView.xib index 4add0b805d..a2c1e9d028 100644 --- a/Vector/Views/RoomInputToolbar/RoomInputToolbarView.xib +++ b/Vector/Views/RoomInputToolbar/RoomInputToolbarView.xib @@ -1,8 +1,8 @@ - + - + @@ -52,6 +52,7 @@ + From c232bf20a73305dd48bf5619b7a7a575b770a871 Mon Sep 17 00:00:00 2001 From: giomfo Date: Fri, 15 Jul 2016 15:31:34 +0200 Subject: [PATCH 17/18] Bug Fix - Room Participants: Admin badge is missing sometimes --- Vector/ViewController/RoomParticipantsViewController.m | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Vector/ViewController/RoomParticipantsViewController.m b/Vector/ViewController/RoomParticipantsViewController.m index ff030ac74a..1de1a81a6b 100644 --- a/Vector/ViewController/RoomParticipantsViewController.m +++ b/Vector/ViewController/RoomParticipantsViewController.m @@ -920,7 +920,9 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N if (disambiguatedDisplayName) { - contact = [[Contact alloc] initMatrixContactWithDisplayName:disambiguatedDisplayName andMatrixID:contact.mxMember.userId]; + MXRoomMember* mxMember = contact.mxMember; + contact = [[Contact alloc] initMatrixContactWithDisplayName:disambiguatedDisplayName andMatrixID:mxMember.userId]; + contact.mxMember = mxMember; } } From 5da1f1567f0380b800974add75ada7ad0122aa30 Mon Sep 17 00:00:00 2001 From: giomfo Date: Fri, 15 Jul 2016 15:46:07 +0200 Subject: [PATCH 18/18] Prepare vector-ios release v0.1.12 --- CHANGES.rst | 22 +++++++++++++++++ Podfile | 6 ++--- Podfile.lock | 63 +++++++++++++++-------------------------------- Vector/Info.plist | 2 +- 4 files changed, 46 insertions(+), 47 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 0e8f410e35..105b577eaa 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,3 +1,25 @@ +Changes in Vector iOS in 0.1.12 (2016-07-15) +=============================================== + +Improvements: + * Upgrade MatrixKit version (v0.3.11). + * Chat Screen: Set the right tint color of the "send" button. + * Messages: Add pink red badge on each invitation #426. + * Add 'leave' button to room settings #417. + * Settings: Set the right label text color. + * Room Settings: Add "Addresses" section #412. + * Messages: switch decline and preview buttons on invites #447. + +Bug fixes: + * App crashes when the user leaves Settings whereas an email binding is in progress. + * App crashes during [AppDelegate applicationDidEnterBackground:] #452. + * Room Participants: Admin badge is missing sometimes. + * Room Participants: The swipe to Leave/Kick is broken. + * Markdown swallows leading #'s even if there are less than 3 #423. + * HTML blockquote is badly rendered: some characters can miss #437. + * Room Settings: check room permissions and grey out those boxes (disable) if you can't change them #430. + * Room Settings: if there isn't a topic (new rooms) you can't actually change/set it. #441. + Changes in Vector iOS in 0.1.11 (2016-07-01) =============================================== diff --git a/Podfile b/Podfile index 9be6ca56e1..8944c49618 100644 --- a/Podfile +++ b/Podfile @@ -8,14 +8,14 @@ target "Vector" do # Different flavours of pods to MatrixKit # The tagged version on which this version of Console has been built -#pod 'MatrixKit', '~> 0.3.10' +pod 'MatrixKit', '~> 0.3.11' # The lastest release available on the CocoaPods repository #pod 'MatrixKit' # The develop branch version -pod 'MatrixSDK', :git => 'https://github.com/matrix-org/matrix-ios-sdk.git', :branch => 'develop' -pod 'MatrixKit', :git => 'https://github.com/matrix-org/matrix-ios-kit.git', :branch => 'develop' +#pod 'MatrixSDK', :git => 'https://github.com/matrix-org/matrix-ios-sdk.git', :branch => 'develop' +#pod 'MatrixKit', :git => 'https://github.com/matrix-org/matrix-ios-kit.git', :branch => 'develop' # The one used for developping both MatrixSDK and MatrixKit # Note that MatrixSDK must be cloned into a folder called matrix-ios-sdk next to the MatrixKit folder diff --git a/Podfile.lock b/Podfile.lock index b9a2670593..e5b1d2bac8 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -1,24 +1,18 @@ PODS: - - AFNetworking (2.6.3): - - AFNetworking/NSURLConnection (= 2.6.3) - - AFNetworking/NSURLSession (= 2.6.3) - - AFNetworking/Reachability (= 2.6.3) - - AFNetworking/Security (= 2.6.3) - - AFNetworking/Serialization (= 2.6.3) - - AFNetworking/UIKit (= 2.6.3) - - AFNetworking/NSURLConnection (2.6.3): + - AFNetworking (3.1.0): + - AFNetworking/NSURLSession (= 3.1.0) + - AFNetworking/Reachability (= 3.1.0) + - AFNetworking/Security (= 3.1.0) + - AFNetworking/Serialization (= 3.1.0) + - AFNetworking/UIKit (= 3.1.0) + - AFNetworking/NSURLSession (3.1.0): - AFNetworking/Reachability - AFNetworking/Security - AFNetworking/Serialization - - AFNetworking/NSURLSession (2.6.3): - - AFNetworking/Reachability - - AFNetworking/Security - - AFNetworking/Serialization - - AFNetworking/Reachability (2.6.3) - - AFNetworking/Security (2.6.3) - - AFNetworking/Serialization (2.6.3) - - AFNetworking/UIKit (2.6.3): - - AFNetworking/NSURLConnection + - AFNetworking/Reachability (3.1.0) + - AFNetworking/Security (3.1.0) + - AFNetworking/Serialization (3.1.0) + - AFNetworking/UIKit (3.1.0): - AFNetworking/NSURLSession - DTCoreText (1.6.17): - DTFoundation/Core (~> 1.7.5) @@ -38,39 +32,22 @@ PODS: - GoogleAnalytics (3.14.0) - HPGrowingTextView (1.1) - libPhoneNumber-iOS (0.8.14) - - MatrixKit (0.3.10): + - MatrixKit (0.3.11): - DTCoreText (~> 1.6.17) - GHMarkdownParser (~> 0.1.2) - HPGrowingTextView (~> 1.1) - libPhoneNumber-iOS (~> 0.8.14) - - MatrixSDK (~> 0.6.9) - - MatrixSDK (0.6.9): - - AFNetworking (~> 2.6.0) + - MatrixSDK (~> 0.6.10) + - MatrixSDK (0.6.10): + - AFNetworking (~> 3.1.0) DEPENDENCIES: - GBDeviceInfo (~> 4.1.0) - GoogleAnalytics - - MatrixKit (from `https://github.com/matrix-org/matrix-ios-kit.git`, branch `develop`) - - MatrixSDK (from `https://github.com/matrix-org/matrix-ios-sdk.git`, branch `develop`) - -EXTERNAL SOURCES: - MatrixKit: - :branch: develop - :git: https://github.com/matrix-org/matrix-ios-kit.git - MatrixSDK: - :branch: develop - :git: https://github.com/matrix-org/matrix-ios-sdk.git - -CHECKOUT OPTIONS: - MatrixKit: - :commit: b5764e0b6d460b3b9a3a824ee6a2ae02f268f389 - :git: https://github.com/matrix-org/matrix-ios-kit.git - MatrixSDK: - :commit: 34a74838efff4bb3344b4580503f22111be5a149 - :git: https://github.com/matrix-org/matrix-ios-sdk.git + - MatrixKit (~> 0.3.11) SPEC CHECKSUMS: - AFNetworking: cb8d14a848e831097108418f5d49217339d4eb60 + AFNetworking: 5e0e199f73d8626b11e79750991f5d173d1f8b67 DTCoreText: 3ea8bba23dd2141ba18adb227a7dd33a822df1c4 DTFoundation: 3b6b1b817d2a7fb02e7eaf2596c922a68145bd43 GBDeviceInfo: e50df975a95e21faec93e2bf98376846fe17d307 @@ -78,9 +55,9 @@ SPEC CHECKSUMS: GoogleAnalytics: 9be1afdb8deeac4bb5f13ca7f7d3b9db2a1f43dc HPGrowingTextView: 88a716d97fb853bcb08a4a08e4727da17efc9b19 libPhoneNumber-iOS: fb165271ebe7fb32e55da97b83219382f2f9d409 - MatrixKit: f777a251efb4c62d6b6414dab032998add4a415e - MatrixSDK: 46b12fd15ef0d50c6ac189989897855b47ce6ba2 + MatrixKit: 711c7b8c1a0751432de3b718f948d25b736925be + MatrixSDK: 39f5fd09a729e88ce7f159a66f2d2515c7252664 -PODFILE CHECKSUM: 69ead5355ed3feb10e54e4f3a9d295700c8e911a +PODFILE CHECKSUM: fd4aa6cba642bed3736613be8b2d9b3c64b62327 COCOAPODS: 1.0.1 diff --git a/Vector/Info.plist b/Vector/Info.plist index 1c0d039d7b..360d55c2bf 100644 --- a/Vector/Info.plist +++ b/Vector/Info.plist @@ -36,7 +36,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 0.1.11 + 0.1.12 CFBundleSignature ???? CFBundleVersion