diff --git a/Signal/src/ViewControllers/OWSTableViewController.h b/Signal/src/ViewControllers/OWSTableViewController.h index db2476363..bb6218b52 100644 --- a/Signal/src/ViewControllers/OWSTableViewController.h +++ b/Signal/src/ViewControllers/OWSTableViewController.h @@ -66,6 +66,10 @@ typedef UITableViewCell *_Nonnull (^OWSTableCustomCellBlock)(); + (OWSTableItem *)disclosureItemWithText:(NSString *)text actionBlock:(nullable OWSTableActionBlock)actionBlock; ++ (OWSTableItem *)disclosureItemWithText:(NSString *)text + customRowHeight:(CGFloat)customRowHeight + actionBlock:(nullable OWSTableActionBlock)actionBlock; + + (OWSTableItem *)actionItemWithText:(NSString *)text actionBlock:(nullable OWSTableActionBlock)actionBlock; + (OWSTableItem *)labelItemWithText:(NSString *)text; diff --git a/Signal/src/ViewControllers/OWSTableViewController.m b/Signal/src/ViewControllers/OWSTableViewController.m index 9980e2cb6..578071160 100644 --- a/Signal/src/ViewControllers/OWSTableViewController.m +++ b/Signal/src/ViewControllers/OWSTableViewController.m @@ -169,6 +169,15 @@ const CGFloat kOWSTable_DefaultCellHeight = 45.f; return item; } ++ (OWSTableItem *)disclosureItemWithText:(NSString *)text + customRowHeight:(CGFloat)customRowHeight + actionBlock:(nullable OWSTableActionBlock)actionBlock +{ + OWSTableItem *item = [self disclosureItemWithText:text actionBlock:actionBlock]; + item.customRowHeight = @(customRowHeight); + return item; +} + + (OWSTableItem *)actionItemWithText:(NSString *)text actionBlock:(nullable OWSTableActionBlock)actionBlock { OWSAssert(text.length > 0); diff --git a/Signal/src/ViewControllers/ShowGroupMembersViewController.m b/Signal/src/ViewControllers/ShowGroupMembersViewController.m index 48a400bf3..44f284cf7 100644 --- a/Signal/src/ViewControllers/ShowGroupMembersViewController.m +++ b/Signal/src/ViewControllers/ShowGroupMembersViewController.m @@ -121,6 +121,7 @@ NS_ASSUME_NONNULL_BEGIN OWSTableContents *contents = [OWSTableContents new]; + __weak ShowGroupMembersViewController *weakSelf = self; ContactsViewHelper *helper = self.contactsViewHelper; OWSTableSection *membersSection = [OWSTableSection new]; @@ -136,6 +137,14 @@ NS_ASSUME_NONNULL_BEGIN @"Title for the 'no longer verified' section of the 'group members' view."); membersSection.headerTitle = NSLocalizedString( @"GROUP_MEMBERS_SECTION_TITLE_MEMBERS", @"Title for the 'members' section of the 'group members' view."); + [noLongerVerifiedSection + addItem:[OWSTableItem disclosureItemWithText:NSLocalizedString(@"GROUP_MEMBERS_RESET_NO_LONGER_VERIFIED", + @"Label for the button that clears all verification " + @"errors in the 'group members' view.") + customRowHeight:ContactTableViewCell.rowHeight + actionBlock:^{ + [weakSelf offerResetAllNoLongerVerified]; + }]]; [self addMembers:noLongerVerifiedRecipientIds toSection:noLongerVerifiedSection useVerifyAction:YES]; [contents addSection:noLongerVerifiedSection]; } @@ -200,6 +209,57 @@ NS_ASSUME_NONNULL_BEGIN } } +- (void)offerResetAllNoLongerVerified +{ + OWSAssert([NSThread isMainThread]); + + UIAlertController *actionSheetController = [UIAlertController + alertControllerWithTitle:nil + message:NSLocalizedString(@"GROUP_MEMBERS_RESET_NO_LONGER_VERIFIED_ALERT_MESSAGE", + @"Label for the 'reset all no-longer-verified group members' confirmation alert.") + preferredStyle:UIAlertControllerStyleAlert]; + + __weak ShowGroupMembersViewController *weakSelf = self; + UIAlertAction *verifyAction = [UIAlertAction + actionWithTitle:NSLocalizedString(@"OK", nil) + style:UIAlertActionStyleDestructive + handler:^(UIAlertAction *_Nonnull action) { + [weakSelf resetAllNoLongerVerified]; + }]; + [actionSheetController addAction:verifyAction]; + + UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"TXT_CANCEL_TITLE", @"") + style:UIAlertActionStyleCancel + handler:nil]; + [actionSheetController addAction:cancelAction]; + + [self presentViewController:actionSheetController animated:YES completion:nil]; +} + +- (void)resetAllNoLongerVerified +{ + OWSAssert([NSThread isMainThread]); + + OWSIdentityManager *identityManger = [OWSIdentityManager sharedManager]; + NSArray *recipientIds = [self noLongerVerifiedRecipientIds]; + for (NSString *recipientId in recipientIds) { + OWSVerificationState verificationState = [identityManger verificationStateForRecipientId:recipientId]; + if (verificationState == OWSVerificationStateNoLongerVerified) { + NSData *identityKey = [identityManger identityKeyForRecipientId:recipientId]; + if (identityKey.length < 1) { + OWSFail(@"Missing identity key for: %@", recipientId); + continue; + } + [identityManger setVerificationState:OWSVerificationStateDefault + identityKey:identityKey + recipientId:recipientId + isUserInitiatedChange:YES]; + } + } + + [self updateTableContents]; +} + // Returns a collection of the group members who are "no longer verified". - (NSArray *)noLongerVerifiedRecipientIds { diff --git a/Signal/translations/en.lproj/Localizable.strings b/Signal/translations/en.lproj/Localizable.strings index 1b32fac93..7b5fb53d6 100644 --- a/Signal/translations/en.lproj/Localizable.strings +++ b/Signal/translations/en.lproj/Localizable.strings @@ -580,6 +580,12 @@ /* Button label for the 'call group member' button */ "GROUP_MEMBERS_CALL" = "Call"; +/* Label for the button that clears all verification errors in the 'group members' view. */ +"GROUP_MEMBERS_RESET_NO_LONGER_VERIFIED" = "Mark All As Not Verified"; + +/* Label for the 'reset all no-longer-verified group members' confirmation alert. */ +"GROUP_MEMBERS_RESET_NO_LONGER_VERIFIED_ALERT_MESSAGE" = "This will mark all of the group members whose safety numbers have changed since they were last verified as not verified."; + /* Title for the 'members' section of the 'group members' view. */ "GROUP_MEMBERS_SECTION_TITLE_MEMBERS" = "Members";