Leave group when blocking it

This commit is contained in:
Michael Kirk 2018-09-10 12:25:38 -05:00
parent 13cf9eab31
commit b6eb1476cb
8 changed files with 140 additions and 54 deletions

View File

@ -1076,41 +1076,31 @@ NSString *const kArchivedConversationsReuseIdentifier = @"kArchivedConversations
}
TSThread *thread = [self threadForIndexPath:indexPath];
if ([thread isKindOfClass:[TSGroupThread class]]) {
if ([thread isKindOfClass:[TSGroupThread class]]) {
TSGroupThread *gThread = (TSGroupThread *)thread;
if ([gThread.groupModel.groupMemberIds containsObject:[TSAccountManager localNumber]]) {
UIAlertController *removingFromGroup = [UIAlertController
alertControllerWithTitle:[NSString
stringWithFormat:NSLocalizedString(@"GROUP_REMOVING", nil), [thread name]]
message:nil
preferredStyle:UIAlertControllerStyleAlert];
[self presentViewController:removingFromGroup animated:YES completion:nil];
[ThreadUtil sendLeaveGroupMessageInThread:gThread
presentingViewController:self
messageSender:self.messageSender
completion:^(NSError *_Nullable error) {
if (error) {
NSString *title = NSLocalizedString(@"GROUP_REMOVING_FAILED",
@"Title of alert indicating that group deletion failed.");
TSOutgoingMessage *message = [TSOutgoingMessage outgoingMessageInThread:thread
groupMetaMessage:TSGroupMessageQuit
expiresInSeconds:0];
[self.messageSender enqueueMessage:message
success:^{
[self dismissViewControllerAnimated:YES
completion:^{
[self deleteThread:thread];
}];
}
failure:^(NSError *error) {
[self dismissViewControllerAnimated:YES
completion:^{
[OWSAlerts
showAlertWithTitle:
NSLocalizedString(@"GROUP_REMOVING_FAILED",
@"Title of alert indicating that group deletion failed.")
message:error.localizedRecoverySuggestion];
}];
}];
[OWSAlerts showAlertWithTitle:title
message:error.localizedRecoverySuggestion];
return;
}
[self deleteThread:thread];
}];
} else {
// MJK - turn these trailing elses into guards
[self deleteThread:thread];
}
} else {
// MJK - turn these trailing elses into guards
[self deleteThread:thread];
}
}

View File

@ -1009,10 +1009,10 @@ const CGFloat kIconViewLength = 24;
DDLogWarn(@"%@ Failed to leave group with error: %@", self.logTag, error);
}];
NSMutableArray *newGroupMemberIds = [NSMutableArray arrayWithArray:gThread.groupModel.groupMemberIds];
[newGroupMemberIds removeObject:[self.accountManager localNumber]];
gThread.groupModel.groupMemberIds = newGroupMemberIds;
[gThread save];
[self.editingDatabaseConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) {
[gThread leaveGroupWithTransaction:transaction];
}];
[self.navigationController popViewControllerAnimated:YES];
}
@ -1042,12 +1042,14 @@ const CGFloat kIconViewLength = 24;
}
[BlockListUIUtils showBlockThreadActionSheet:self.thread
fromViewController:self
blockingManager:_blockingManager
contactsManager:_contactsManager
blockingManager:self.blockingManager
contactsManager:self.contactsManager
messageSender:self.messageSender
completionBlock:^(BOOL isBlocked) {
// Update switch state if user cancels action.
blockConversationSwitch.on = isBlocked;
}];
} else {
OWSAssert(isCurrentlyBlocked);
if (!isCurrentlyBlocked) {

View File

@ -9,6 +9,7 @@ NS_ASSUME_NONNULL_BEGIN
@class Contact;
@class OWSBlockingManager;
@class OWSContactsManager;
@class OWSMessageSender;
@class SignalAccount;
@class TSThread;
@ -24,6 +25,7 @@ typedef void (^BlockActionCompletionBlock)(BOOL isBlocked);
fromViewController:(UIViewController *)fromViewController
blockingManager:(OWSBlockingManager *)blockingManager
contactsManager:(OWSContactsManager *)contactsManager
messageSender:(OWSMessageSender *)messageSender
completionBlock:(nullable BlockActionCompletionBlock)completionBlock;
+ (void)showBlockPhoneNumberActionSheet:(NSString *)phoneNumber

View File

@ -10,6 +10,7 @@
#import <SignalServiceKit/OWSBlockingManager.h>
#import <SignalServiceKit/SignalAccount.h>
#import <SignalServiceKit/TSAccountManager.h>
#import <SignalServiceKit/TSGroupThread.h>
NS_ASSUME_NONNULL_BEGIN
@ -23,6 +24,7 @@ typedef void (^BlockAlertCompletionBlock)(UIAlertAction *action);
fromViewController:(UIViewController *)fromViewController
blockingManager:(OWSBlockingManager *)blockingManager
contactsManager:(OWSContactsManager *)contactsManager
messageSender:(OWSMessageSender *)messageSender
completionBlock:(nullable BlockActionCompletionBlock)completionBlock
{
if ([thread isKindOfClass:[TSContactThread class]]) {
@ -34,10 +36,10 @@ typedef void (^BlockAlertCompletionBlock)(UIAlertAction *action);
completionBlock:completionBlock];
} else if ([thread isKindOfClass:[TSGroupThread class]]) {
TSGroupThread *groupThread = (TSGroupThread *)thread;
[self showBlockGroupActionSheet:groupThread.groupModel
displayName:groupThread.name
[self showBlockGroupActionSheet:groupThread
fromViewController:fromViewController
blockingManager:blockingManager
messageSender:messageSender
completionBlock:completionBlock];
} else {
OWSFail(@"unexpected thread type: %@", thread.class);
@ -142,20 +144,20 @@ typedef void (^BlockAlertCompletionBlock)(UIAlertAction *action);
[fromViewController presentViewController:actionSheetController animated:YES completion:nil];
}
+ (void)showBlockGroupActionSheet:(TSGroupModel *)groupModel
displayName:(NSString *)displayName
+ (void)showBlockGroupActionSheet:(TSGroupThread *)groupThread
fromViewController:(UIViewController *)fromViewController
blockingManager:(OWSBlockingManager *)blockingManager
messageSender:(OWSMessageSender *)messageSender
completionBlock:(nullable BlockActionCompletionBlock)completionBlock
{
OWSAssert(displayName.length > 0);
OWSAssert(groupThread);
OWSAssert(fromViewController);
OWSAssert(blockingManager);
NSString *title = [NSString
stringWithFormat:NSLocalizedString(@"BLOCK_LIST_BLOCK_GROUP_TITLE_FORMAT",
@"A format for the 'block group' action sheet title. Embeds the {{group name}}."),
[self formatDisplayNameForAlertTitle:displayName]];
[self formatDisplayNameForAlertTitle:groupThread.name]];
UIAlertController *actionSheetController =
[UIAlertController alertControllerWithTitle:title
@ -167,10 +169,10 @@ typedef void (^BlockAlertCompletionBlock)(UIAlertAction *action);
actionWithTitle:NSLocalizedString(@"BLOCK_LIST_BLOCK_BUTTON", @"Button label for the 'block' button")
style:UIAlertActionStyleDestructive
handler:^(UIAlertAction *_Nonnull action) {
[self blockGroup:groupModel
displayName:displayName
[self blockGroup:groupThread
fromViewController:fromViewController
blockingManager:blockingManager
messageSender:messageSender
completionBlock:^(UIAlertAction *ignore) {
if (completionBlock) {
completionBlock(YES);
@ -218,27 +220,46 @@ typedef void (^BlockAlertCompletionBlock)(UIAlertAction *action);
completionBlock:completionBlock];
}
+ (void)blockGroup:(TSGroupModel *)groupModel
displayName:(NSString *)displayName
+ (void)blockGroup:(TSGroupThread *)groupThread
fromViewController:(UIViewController *)fromViewController
blockingManager:(OWSBlockingManager *)blockingManager
messageSender:(OWSMessageSender *)messageSender
completionBlock:(BlockAlertCompletionBlock)completionBlock
{
OWSAssert(displayName.length > 0);
OWSAssert(groupThread);
OWSAssert(fromViewController);
OWSAssert(blockingManager);
[blockingManager addBlockedGroupId:groupModel.groupId];
// block the group regardless of the ability to deliver the "leave group" message.
[blockingManager addBlockedGroupId:groupThread.groupModel.groupId];
[self showOkAlertWithTitle:NSLocalizedString(@"BLOCK_LIST_VIEW_BLOCKED_GROUP_ALERT_TITLE",
@"The title of the 'group blocked' alert.")
message:[NSString
stringWithFormat:NSLocalizedString(@"BLOCK_LIST_VIEW_BLOCKED_ALERT_MESSAGE_FORMAT",
@"The message format of the 'conversation blocked' alert. "
@"Embeds the {{conversation title}}."),
[self formatDisplayNameForAlertMessage:displayName]]
fromViewController:fromViewController
completionBlock:completionBlock];
// blockingManager.addBlocked* creates sneaky transactions, so we can't pass in a transaction
// via params and instead have to create our own sneaky transaction here.
[groupThread leaveGroupWithSneakyTransaction];
[ThreadUtil
sendLeaveGroupMessageInThread:groupThread
presentingViewController:fromViewController
messageSender:messageSender
completion:^(NSError *_Nullable error) {
if (error) {
DDLogError(@"Failed to leave blocked group with error: %@", error);
}
[self
showOkAlertWithTitle:NSLocalizedString(@"BLOCK_LIST_VIEW_BLOCKED_GROUP_ALERT_TITLE",
@"The title of the 'group blocked' alert.")
message:[NSString
stringWithFormat:
NSLocalizedString(
@"BLOCK_LIST_VIEW_BLOCKED_ALERT_MESSAGE_FORMAT",
@"The message format of the 'conversation blocked' "
@"alert. "
@"Embeds the {{conversation title}}."),
[self formatDisplayNameForAlertMessage:groupThread.name]]
fromViewController:fromViewController
completionBlock:completionBlock];
}];
}
#pragma mark - Unblock

View File

@ -10,6 +10,7 @@ NS_ASSUME_NONNULL_BEGIN
@class OWSUnreadIndicator;
@class SignalAttachment;
@class TSContactThread;
@class TSGroupThread;
@class TSInteraction;
@class TSThread;
@class YapDatabaseConnection;
@ -71,6 +72,13 @@ NS_ASSUME_NONNULL_BEGIN
messageSender:(OWSMessageSender *)messageSender
completion:(void (^_Nullable)(NSError *_Nullable error))completion;
+ (void)sendLeaveGroupMessageInThread:(TSGroupThread *)thread
presentingViewController:(UIViewController *)presentingViewController
messageSender:(OWSMessageSender *)messageSender
completion:(void (^_Nullable)(NSError *_Nullable error))completion;
#pragma mark - dynamic interactions
// This method will create and/or remove any offers and indicators
// necessary for this thread. This includes:
//

View File

@ -212,6 +212,48 @@ NS_ASSUME_NONNULL_BEGIN
return message;
}
+ (void)sendLeaveGroupMessageInThread:(TSGroupThread *)thread
presentingViewController:(UIViewController *)presentingViewController
messageSender:(OWSMessageSender *)messageSender
completion:(void (^_Nullable)(NSError *_Nullable error))completion
{
OWSAssert([thread isKindOfClass:[TSGroupThread class]]);
OWSAssert(presentingViewController);
OWSAssert(messageSender);
NSString *title = [NSString
stringWithFormat:NSLocalizedString(@"GROUP_REMOVING", @"Modal text when removing a group"), thread.name];
UIAlertController *removingFromGroup =
[UIAlertController alertControllerWithTitle:title message:title preferredStyle:UIAlertControllerStyleAlert];
[presentingViewController presentViewController:removingFromGroup animated:YES completion:nil];
TSOutgoingMessage *message =
[TSOutgoingMessage outgoingMessageInThread:thread groupMetaMessage:TSGroupMessageQuit expiresInSeconds:0];
[messageSender enqueueMessage:message
success:^{
dispatch_async(dispatch_get_main_queue(), ^{
[presentingViewController dismissViewControllerAnimated:YES
completion:^{
if (completion) {
completion(nil);
}
}];
});
}
failure:^(NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
[presentingViewController dismissViewControllerAnimated:YES
completion:^{
if (completion) {
completion(error);
}
}];
});
}];
}
#pragma mark - Dynamic Interactions
+ (ThreadDynamicInteractions *)ensureDynamicInteractionsForThread:(TSThread *)thread
contactsManager:(OWSContactsManager *)contactsManager
blockingManager:(OWSBlockingManager *)blockingManager

View File

@ -33,6 +33,9 @@ extern NSString *const TSGroupThread_NotificationKey_UniqueId;
+ (NSArray<TSGroupThread *> *)groupThreadsWithRecipientId:(NSString *)recipientId
transaction:(YapDatabaseReadWriteTransaction *)transaction;
- (void)leaveGroupWithSneakyTransaction;
- (void)leaveGroupWithTransaction:(YapDatabaseReadWriteTransaction *)transaction;
- (void)updateAvatarWithAttachmentStream:(TSAttachmentStream *)attachmentStream;
- (void)updateAvatarWithAttachmentStream:(TSAttachmentStream *)attachmentStream
transaction:(YapDatabaseReadWriteTransaction *)transaction;

View File

@ -178,6 +178,24 @@ NSString *const TSGroupThread_NotificationKey_UniqueId = @"TSGroupThread_Notific
return self.groupModel.groupName ? self.groupModel.groupName : NSLocalizedString(@"NEW_GROUP_DEFAULT_TITLE", @"");
}
- (void)leaveGroupWithSneakyTransaction
{
[self.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) {
[self leaveGroupWithTransaction:transaction];
}];
}
- (void)leaveGroupWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
{
NSMutableArray *newGroupMemberIds = [self.groupModel.groupMemberIds mutableCopy];
[newGroupMemberIds removeObject:[TSAccountManager localNumber]];
self.groupModel.groupMemberIds = newGroupMemberIds;
[self saveWithTransaction:transaction];
}
#pragma mark - Avatar
- (void)updateAvatarWithAttachmentStream:(TSAttachmentStream *)attachmentStream
{
[self.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {