Leave group when blocking it

pull/1/head
Michael Kirk 7 years ago
parent 13cf9eab31
commit b6eb1476cb

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

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

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

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

@ -10,6 +10,7 @@ NS_ASSUME_NONNULL_BEGIN
@class OWSUnreadIndicator; @class OWSUnreadIndicator;
@class SignalAttachment; @class SignalAttachment;
@class TSContactThread; @class TSContactThread;
@class TSGroupThread;
@class TSInteraction; @class TSInteraction;
@class TSThread; @class TSThread;
@class YapDatabaseConnection; @class YapDatabaseConnection;
@ -71,6 +72,13 @@ NS_ASSUME_NONNULL_BEGIN
messageSender:(OWSMessageSender *)messageSender messageSender:(OWSMessageSender *)messageSender
completion:(void (^_Nullable)(NSError *_Nullable error))completion; 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 // This method will create and/or remove any offers and indicators
// necessary for this thread. This includes: // necessary for this thread. This includes:
// //

@ -212,6 +212,48 @@ NS_ASSUME_NONNULL_BEGIN
return message; 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 + (ThreadDynamicInteractions *)ensureDynamicInteractionsForThread:(TSThread *)thread
contactsManager:(OWSContactsManager *)contactsManager contactsManager:(OWSContactsManager *)contactsManager
blockingManager:(OWSBlockingManager *)blockingManager blockingManager:(OWSBlockingManager *)blockingManager

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

@ -178,6 +178,24 @@ NSString *const TSGroupThread_NotificationKey_UniqueId = @"TSGroupThread_Notific
return self.groupModel.groupName ? self.groupModel.groupName : NSLocalizedString(@"NEW_GROUP_DEFAULT_TITLE", @""); 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 - (void)updateAvatarWithAttachmentStream:(TSAttachmentStream *)attachmentStream
{ {
[self.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { [self.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {

Loading…
Cancel
Save