2017-02-17 23:30:49 +01:00
//
2019-01-04 15:19:41 +01:00
// Copyright ( c ) 2019 Open Whisper Systems . All rights reserved .
2017-02-17 23:30:49 +01:00
//
2016-09-21 14:37:51 +02:00
2017-08-01 22:16:33 +02:00
# import "OWSConversationSettingsViewController.h"
2017-04-03 16:29:11 +02:00
# import "BlockListUIUtils.h"
2017-05-09 23:55:18 +02:00
# import "ContactsViewHelper.h"
2016-09-21 14:37:51 +02:00
# import "FingerprintViewController.h"
2017-07-04 22:40:28 +02:00
# import "OWSAddToContactViewController.h"
2017-04-03 16:29:11 +02:00
# import "OWSBlockingManager.h"
2018-02-22 04:31:55 +01:00
# import "OWSSoundSettingsViewController.h"
2016-09-21 14:37:51 +02:00
# import "PhoneNumber.h"
# import "ShowGroupMembersViewController.h"
2019-05-02 23:58:48 +02:00
# import "Session-Swift.h"
2016-10-06 15:44:25 +02:00
# import "UIFont+OWS.h"
2017-04-17 21:13:15 +02:00
# import "UIView+OWS.h"
2017-04-28 18:18:42 +02:00
# import "UpdateGroupViewController.h"
2020-06-05 02:38:44 +02:00
# import < SessionCurve25519Kit / Curve25519 . h >
# import < SessionCoreKit / NSDate + OWS . h >
2017-12-19 03:50:51 +01:00
# import < SignalMessaging / Environment . h >
2017-12-08 17:50:35 +01:00
# import < SignalMessaging / OWSAvatarBuilder . h >
2017-12-19 03:50:51 +01:00
# import < SignalMessaging / OWSContactsManager . h >
2017-12-04 16:35:47 +01:00
# import < SignalMessaging / OWSProfileManager . h >
2018-02-22 20:38:40 +01:00
# import < SignalMessaging / OWSSounds . h >
2017-12-08 19:45:24 +01:00
# import < SignalMessaging / OWSUserProfile . h >
2018-09-27 03:10:28 +02:00
# import < SignalMessaging / SignalMessaging - Swift . h >
2017-12-08 17:50:35 +01:00
# import < SignalMessaging / UIUtil . h >
2020-06-05 02:38:44 +02:00
# import < SessionServiceKit / OWSDisappearingConfigurationUpdateInfoMessage . h >
# import < SessionServiceKit / OWSDisappearingMessagesConfiguration . h >
# import < SessionServiceKit / OWSMessageSender . h >
# import < SessionServiceKit / OWSPrimaryStorage . h >
# import < SessionServiceKit / TSGroupThread . h >
# import < SessionServiceKit / TSOutgoingMessage . h >
# import < SessionServiceKit / TSThread . h >
2016-09-21 14:37:51 +02:00
2017-05-09 23:55:18 +02:00
@ import ContactsUI ;
2020-09-25 05:41:35 +02:00
@ import PromiseKit ;
2017-05-09 23:55:18 +02:00
2016-09-21 14:37:51 +02:00
NS_ASSUME _NONNULL _BEGIN
2018-10-09 22:06:23 +02:00
// # define SHOW_COLOR _PICKER
2018-07-03 18:57:51 +02:00
const CGFloat kIconViewLength = 24 ;
2018-06-28 19:28:14 +02:00
@ interface OWSConversationSettingsViewController ( ) < ContactEditingDelegate ,
ContactsViewHelperDelegate ,
2018-10-09 22:06:23 +02:00
# ifdef SHOW_COLOR _PICKER
2018-09-27 03:10:28 +02:00
ColorPickerDelegate ,
2018-10-09 22:06:23 +02:00
# endif
2018-09-27 03:10:28 +02:00
OWSSheetViewControllerDelegate >
2016-09-21 14:37:51 +02:00
@ property ( nonatomic ) TSThread * thread ;
2018-03-19 17:22:39 +01:00
@ property ( nonatomic ) YapDatabaseConnection * uiDatabaseConnection ;
2018-06-28 19:28:14 +02:00
@ property ( nonatomic , readonly ) YapDatabaseConnection * editingDatabaseConnection ;
2016-09-21 14:37:51 +02:00
@ property ( nonatomic ) NSArray < NSNumber * > * disappearingMessagesDurations ;
@ property ( nonatomic ) OWSDisappearingMessagesConfiguration * disappearingMessagesConfiguration ;
2018-11-15 01:53:58 +01:00
@ property ( nullable , nonatomic ) MediaGallery * mediaGallery ;
2017-05-09 23:55:18 +02:00
@ property ( nonatomic , readonly ) ContactsViewHelper * contactsViewHelper ;
2017-04-21 21:37:51 +02:00
@ property ( nonatomic , readonly ) UIImageView * avatarView ;
2017-04-17 21:13:15 +02:00
@ property ( nonatomic , readonly ) UILabel * disappearingMessagesDurationLabel ;
2018-10-09 22:06:23 +02:00
# ifdef SHOW_COLOR _PICKER
2018-09-27 03:10:28 +02:00
@ property ( nonatomic ) OWSColorPicker * colorPicker ;
2018-10-09 22:06:23 +02:00
# endif
2017-04-17 21:13:15 +02:00
2016-09-21 14:37:51 +02:00
@ end
2017-04-17 21:13:15 +02:00
# pragma mark -
2017-08-01 22:16:33 +02:00
@ implementation OWSConversationSettingsViewController
2016-09-21 14:37:51 +02:00
- ( instancetype ) init
{
self = [ super init ] ;
if ( ! self ) {
return self ;
}
2017-03-10 14:59:59 +01:00
[ self commonInit ] ;
2016-09-21 14:37:51 +02:00
return self ;
}
- ( nullable instancetype ) initWithCoder : ( NSCoder * ) aDecoder
{
self = [ super initWithCoder : aDecoder ] ;
if ( ! self ) {
return self ;
}
2017-03-10 14:59:59 +01:00
[ self commonInit ] ;
return self ;
}
2017-08-01 22:16:33 +02:00
- ( instancetype ) initWithNibName : ( nullable NSString * ) nibNameOrNil bundle : ( nullable NSBundle * ) nibBundleOrNil
{
2017-03-10 14:59:59 +01:00
self = [ super initWithNibName : nibNameOrNil bundle : nibBundleOrNil ] ;
if ( ! self ) {
return self ;
}
2017-08-01 22:16:33 +02:00
2017-03-10 14:59:59 +01:00
[ self commonInit ] ;
2017-08-01 22:16:33 +02:00
2017-03-10 14:59:59 +01:00
return self ;
}
- ( void ) commonInit
{
2017-05-12 17:09:25 +02:00
_contactsViewHelper = [ [ ContactsViewHelper alloc ] initWithDelegate : self ] ;
2017-06-09 22:21:59 +02:00
[ self observeNotifications ] ;
}
- ( void ) dealloc
{
[ [ NSNotificationCenter defaultCenter ] removeObserver : self ] ;
}
2018-10-20 19:51:48 +02:00
# pragma mark - Dependencies
- ( SSKMessageSenderJobQueue * ) messageSenderJobQueue
{
return SSKEnvironment . shared . messageSenderJobQueue ;
}
2018-12-21 19:03:09 +01:00
- ( TSAccountManager * ) tsAccountManager
{
OWSAssertDebug ( SSKEnvironment . shared . tsAccountManager ) ;
return SSKEnvironment . shared . tsAccountManager ;
}
- ( OWSContactsManager * ) contactsManager
{
return Environment . shared . contactsManager ;
}
- ( OWSMessageSender * ) messageSender
{
return SSKEnvironment . shared . messageSender ;
}
- ( OWSBlockingManager * ) blockingManager
{
return [ OWSBlockingManager sharedManager ] ;
}
- ( OWSProfileManager * ) profileManager
{
return [ OWSProfileManager sharedManager ] ;
}
2018-10-20 19:51:48 +02:00
# pragma mark
2017-06-09 22:21:59 +02:00
- ( void ) observeNotifications
{
[ [ NSNotificationCenter defaultCenter ] addObserver : self
selector : @ selector ( identityStateDidChange : )
name : kNSNotificationName_IdentityStateDidChange
object : nil ] ;
2017-08-23 23:09:43 +02:00
[ [ NSNotificationCenter defaultCenter ] addObserver : self
selector : @ selector ( otherUsersProfileDidChange : )
name : kNSNotificationName_OtherUsersProfileDidChange
object : nil ] ;
2016-09-21 14:37:51 +02:00
}
2018-06-28 19:28:14 +02:00
- ( YapDatabaseConnection * ) editingDatabaseConnection
{
return [ OWSPrimaryStorage sharedManager ] . dbReadWriteConnection ;
}
2020-10-29 06:13:16 +01:00
- ( nullable NSString * ) threadName
2017-04-17 21:13:15 +02:00
{
NSString * threadName = self . thread . name ;
2019-05-28 06:01:24 +02:00
if ( self . thread . contactIdentifier ) {
return [ self . contactsManager profileNameForRecipientId : self . thread . contactIdentifier ] ;
2017-04-17 21:13:15 +02:00
} else if ( threadName . length = = 0 && [ self isGroupThread ] ) {
2017-10-14 19:20:46 +02:00
threadName = [ MessageStrings newGroupDefaultTitle ] ;
2017-04-17 21:13:15 +02:00
}
return threadName ;
}
- ( BOOL ) isGroupThread
{
return [ self . thread isKindOfClass : [ TSGroupThread class ] ] ;
}
2020-08-13 07:08:26 +02:00
- ( BOOL ) isOpenGroupChat
{
2020-08-18 05:58:24 +02:00
if ( [ self isGroupThread ] ) {
TSGroupThread * thread = ( TSGroupThread * ) self . thread ;
return thread . isPublicChat ;
}
return false ;
2020-08-13 07:08:26 +02:00
}
2020-01-13 01:14:49 +01:00
- ( BOOL ) isPrivateGroupChat
{
if ( self . isGroupThread ) {
2020-01-28 05:08:42 +01:00
TSGroupThread * thread = ( TSGroupThread * ) self . thread ;
return ! thread . isRSSFeed && ! thread . isPublicChat ;
2020-01-13 01:14:49 +01:00
}
2020-01-28 05:08:42 +01:00
return false ;
2020-01-13 01:14:49 +01:00
}
2018-03-19 17:22:39 +01:00
- ( void ) configureWithThread : ( TSThread * ) thread uiDatabaseConnection : ( YapDatabaseConnection * ) uiDatabaseConnection
2016-09-21 14:37:51 +02:00
{
2018-09-06 19:01:24 +02:00
OWSAssertDebug ( thread ) ;
2016-09-21 14:37:51 +02:00
self . thread = thread ;
2018-03-19 17:22:39 +01:00
self . uiDatabaseConnection = uiDatabaseConnection ;
2017-05-12 21:30:06 +02:00
2017-05-09 23:55:18 +02:00
[ self updateEditButton ] ;
}
- ( void ) updateEditButton
{
2018-09-06 19:01:24 +02:00
OWSAssertDebug ( self . thread ) ;
2017-05-09 23:55:18 +02:00
2017-07-04 22:40:28 +02:00
if ( [ self . thread isKindOfClass : [ TSContactThread class ] ] && self . contactsManager . supportsContactEditing
&& self . hasExistingContact ) {
2017-05-09 23:55:18 +02:00
self . navigationItem . rightBarButtonItem =
[ [ UIBarButtonItem alloc ] initWithTitle : NSLocalizedString ( @ "EDIT_TXT" , nil )
style : UIBarButtonItemStylePlain
target : self
2019-03-22 20:54:35 +01:00
action : @ selector ( didTapEditButton )
accessibilityIdentifier : ACCESSIBILITY_IDENTIFIER _WITH _NAME ( self , @ "edit" ) ] ;
2017-05-09 23:55:18 +02:00
}
}
2017-07-04 22:40:28 +02:00
- ( BOOL ) hasExistingContact
{
2018-09-06 19:01:24 +02:00
OWSAssertDebug ( [ self . thread isKindOfClass : [ TSContactThread class ] ] ) ;
2017-07-04 22:40:28 +02:00
TSContactThread * contactThread = ( TSContactThread * ) self . thread ;
NSString * recipientId = contactThread . contactIdentifier ;
2017-12-14 16:51:46 +01:00
return [ self . contactsManager hasSignalAccountForRecipientId : recipientId ] ;
2017-07-04 22:40:28 +02:00
}
2017-05-09 23:55:18 +02:00
# pragma mark - ContactEditingDelegate
- ( void ) didFinishEditingContact
{
2017-07-04 22:40:28 +02:00
[ self updateTableContents ] ;
2018-08-27 18:09:39 +02:00
OWSLogDebug ( @ "" ) ;
2017-05-10 18:02:14 +02:00
[ self dismissViewControllerAnimated : NO completion : nil ] ;
2017-05-09 23:55:18 +02:00
}
# pragma mark - CNContactViewControllerDelegate
- ( void ) contactViewController : ( CNContactViewController * ) viewController
didCompleteWithContact : ( nullable CNContact * ) contact
{
2017-07-04 22:40:28 +02:00
[ self updateTableContents ] ;
2017-05-10 18:02:14 +02:00
if ( contact ) {
// Saving normally returns you to the "Show Contact" view
// which we ' re not interested in , so we skip it here . There is
// an unfortunate blip of the "Show Contact" view on slower devices .
2018-08-27 18:51:32 +02:00
OWSLogDebug ( @ "completed editing contact." ) ;
2017-05-10 18:02:14 +02:00
[ self dismissViewControllerAnimated : NO completion : nil ] ;
} else {
2018-08-27 18:51:32 +02:00
OWSLogDebug ( @ "canceled editing contact." ) ;
2017-05-10 18:02:14 +02:00
[ self dismissViewControllerAnimated : YES completion : nil ] ;
}
2017-05-09 23:55:18 +02:00
}
# pragma mark - ContactsViewHelperDelegate
- ( void ) contactsViewHelperDidUpdateContacts
{
2019-05-14 07:54:39 +02:00
// Loki : Original code
// === === = =
// [ self updateTableContents ] ;
// === === = =
2016-09-21 14:37:51 +02:00
}
# pragma mark - View Lifecycle
- ( void ) viewDidLoad
{
[ super viewDidLoad ] ;
2018-07-17 20:24:21 +02:00
self . tableView . estimatedRowHeight = 45 ;
self . tableView . rowHeight = UITableViewAutomaticDimension ;
2017-04-17 21:13:15 +02:00
_disappearingMessagesDurationLabel = [ UILabel new ] ;
2019-03-22 20:54:35 +01:00
SET_SUBVIEW _ACCESSIBILITY _IDENTIFIER ( self , _disappearingMessagesDurationLabel ) ;
2016-09-21 14:37:51 +02:00
self . disappearingMessagesDurations = [ OWSDisappearingMessagesConfiguration validDurationsSeconds ] ;
self . disappearingMessagesConfiguration =
[ OWSDisappearingMessagesConfiguration fetchObjectWithUniqueID : self . thread . uniqueId ] ;
if ( ! self . disappearingMessagesConfiguration ) {
self . disappearingMessagesConfiguration =
[ [ OWSDisappearingMessagesConfiguration alloc ] initDefaultWithThreadId : self . thread . uniqueId ] ;
}
2018-10-09 22:06:23 +02:00
# ifdef SHOW_COLOR _PICKER
2018-09-27 22:25:20 +02:00
self . colorPicker = [ [ OWSColorPicker alloc ] initWithThread : self . thread ] ;
2018-09-27 03:10:28 +02:00
self . colorPicker . delegate = self ;
2018-10-09 22:06:23 +02:00
# endif
2018-09-27 03:10:28 +02:00
2017-04-03 16:29:11 +02:00
[ self updateTableContents ] ;
2019-10-03 03:30:45 +02:00
2020-08-28 05:48:27 +02:00
NSString * title ;
2019-12-13 01:23:45 +01:00
if ( [ self . thread isKindOfClass : [ TSContactThread class ] ] ) {
2020-08-28 05:48:27 +02:00
title = NSLocalizedString ( @ "Settings" , @ "" ) ;
2019-12-13 01:23:45 +01:00
} else {
2020-08-28 05:48:27 +02:00
title = NSLocalizedString ( @ "Group Settings" , @ "" ) ;
2019-12-13 01:23:45 +01:00
}
2020-08-28 05:48:27 +02:00
[ LKViewControllerUtilities setUpDefaultSessionStyleForVC : self withTitle : title customBackButton : YES ] ;
self . tableView . backgroundColor = UIColor . clearColor ;
2017-04-03 16:29:11 +02:00
}
2017-06-09 22:21:59 +02:00
- ( void ) viewDidAppear : ( BOOL ) animated
{
[ super viewDidAppear : animated ] ;
if ( self . showVerificationOnAppear ) {
self . showVerificationOnAppear = NO ;
if ( self . isGroupThread ) {
[ self showGroupMembersView ] ;
} else {
[ self showVerificationView ] ;
}
}
}
2017-04-03 16:29:11 +02:00
- ( void ) updateTableContents
{
OWSTableContents * contents = [ OWSTableContents new ] ;
contents . title = NSLocalizedString ( @ "CONVERSATION_SETTINGS" , @ "title for conversation settings screen" ) ;
2019-01-04 15:19:41 +01:00
BOOL isNoteToSelf = self . thread . isNoteToSelf ;
2018-12-21 19:03:09 +01:00
2017-08-01 22:16:33 +02:00
__weak OWSConversationSettingsViewController * weakSelf = self ;
2017-04-03 16:29:11 +02:00
2017-07-04 22:40:28 +02:00
// Main section .
2017-04-10 21:58:34 +02:00
2017-07-04 22:40:28 +02:00
OWSTableSection * mainSection = [ OWSTableSection new ] ;
2017-04-03 16:29:11 +02:00
2017-07-04 22:40:28 +02:00
mainSection . customHeaderView = [ self mainSectionHeader ] ;
2020-05-29 07:11:08 +02:00
if ( self . isGroupThread ) {
mainSection . customHeaderHeight = @ ( 147. f ) ;
} else {
BOOL isSmallScreen = ( UIScreen . mainScreen . bounds . size . height - 568 ) < 1 ;
mainSection . customHeaderHeight = isSmallScreen ? @ ( 201. f ) : @ ( 208. f ) ;
}
2017-07-04 22:40:28 +02:00
2019-06-14 07:25:39 +02:00
/ * *
* Loki : Original code
* === === = =
2017-07-04 22:40:28 +02:00
if ( [ self . thread isKindOfClass : [ TSContactThread class ] ] && self . contactsManager . supportsContactEditing
&& ! self . hasExistingContact ) {
2019-03-22 20:54:35 +01:00
[ mainSection
addItem : [ OWSTableItem
itemWithCustomCellBlock : ^ {
return [ weakSelf
disclosureCellWithName :
NSLocalizedString ( @ "CONVERSATION_SETTINGS_NEW_CONTACT" ,
@ "Label for 'new contact' button in conversation settings view." )
iconName : @ "table_ic_new_contact"
accessibilityIdentifier : ACCESSIBILITY_IDENTIFIER _WITH _NAME (
OWSConversationSettingsViewController , @ "new_contact" ) ] ;
}
actionBlock : ^ {
[ weakSelf presentContactViewController ] ;
} ] ] ;
[ mainSection addItem : [ OWSTableItem
itemWithCustomCellBlock : ^ {
return [ weakSelf
disclosureCellWithName :
NSLocalizedString ( @ "CONVERSATION_SETTINGS_ADD_TO_EXISTING_CONTACT" ,
@ "Label for 'new contact' button in conversation settings view." )
iconName : @ "table_ic_add_to_existing_contact"
accessibilityIdentifier : ACCESSIBILITY_IDENTIFIER _WITH _NAME (
OWSConversationSettingsViewController ,
@ "add_to_existing_contact" ) ] ;
}
2017-07-04 22:40:28 +02:00
actionBlock : ^ {
2017-08-01 22:16:33 +02:00
OWSConversationSettingsViewController * strongSelf = weakSelf ;
2018-09-06 19:01:24 +02:00
OWSCAssertDebug ( strongSelf ) ;
2017-07-25 19:56:16 +02:00
TSContactThread * contactThread = ( TSContactThread * ) strongSelf . thread ;
2017-07-04 22:40:28 +02:00
NSString * recipientId = contactThread . contactIdentifier ;
2017-07-25 19:56:16 +02:00
[ strongSelf presentAddToContactViewControllerWithRecipientId : recipientId ] ;
2017-07-04 22:40:28 +02:00
} ] ] ;
}
2020-09-16 02:08:46 +02:00
if ( SSKFeatureFlags . conversationSearch ) {
* === === = =
* /
2017-04-10 21:58:34 +02:00
2020-09-16 02:50:48 +02:00
if ( [ self . thread isKindOfClass : TSContactThread . class ] ) {
[ mainSection addItem : [ OWSTableItem
itemWithCustomCellBlock : ^ {
return [ weakSelf
disclosureCellWithName : @ "Copy Session ID"
iconName : @ "ic_copy"
accessibilityIdentifier : ACCESSIBILITY_IDENTIFIER _WITH _NAME (
OWSConversationSettingsViewController , @ "copy_session_id" ) ] ;
}
actionBlock : ^ {
[ weakSelf copySessionID ] ;
} ] ] ;
}
2019-02-11 17:49:26 +01:00
[ mainSection addItem : [ OWSTableItem
itemWithCustomCellBlock : ^ {
2019-03-22 20:54:35 +01:00
return [ weakSelf
disclosureCellWithName : MediaStrings . allMedia
iconName : @ "actionsheet_camera_roll_black"
accessibilityIdentifier : ACCESSIBILITY_IDENTIFIER _WITH _NAME (
OWSConversationSettingsViewController , @ "all_media" ) ] ;
2019-02-11 17:49:26 +01:00
}
actionBlock : ^ {
[ weakSelf showMediaGallery ] ;
} ] ] ;
2020-09-16 02:08:46 +02:00
[ mainSection addItem : [ OWSTableItem
itemWithCustomCellBlock : ^ {
NSString * title = NSLocalizedString ( @ "CONVERSATION_SETTINGS_SEARCH" ,
@ "Table cell label in conversation settings which returns the user to the "
@ "conversation with 'search mode' activated" ) ;
return [ weakSelf
disclosureCellWithName : title
iconName : @ "conversation_settings_search"
accessibilityIdentifier : ACCESSIBILITY_IDENTIFIER _WITH _NAME (
OWSConversationSettingsViewController , @ "search" ) ] ;
}
actionBlock : ^ {
[ weakSelf tappedConversationSearch ] ;
} ] ] ;
2019-09-10 07:47:34 +02:00
/ *
2019-04-01 21:56:20 +02:00
}
2019-02-11 17:49:26 +01:00
2018-12-21 19:03:09 +01:00
if ( ! isNoteToSelf && ! self . isGroupThread && self . thread . hasSafetyNumbers ) {
2019-03-22 20:54:35 +01:00
[ mainSection
addItem : [ OWSTableItem
itemWithCustomCellBlock : ^ {
return [ weakSelf
disclosureCellWithName : NSLocalizedString ( @ "VERIFY_PRIVACY" ,
@ "Label for button or row which allows users to verify the "
@ "safety number of another user." )
iconName : @ "table_ic_not_verified"
accessibilityIdentifier : ACCESSIBILITY_IDENTIFIER _WITH _NAME (
OWSConversationSettingsViewController , @ "safety_numbers" ) ] ;
}
actionBlock : ^ {
[ weakSelf showVerificationView ] ;
} ] ] ;
2017-04-10 21:58:34 +02:00
}
2018-12-21 19:03:09 +01:00
if ( isNoteToSelf ) {
// Skip the profile whitelist .
} else if ( [ self . profileManager isThreadInProfileWhitelist : self . thread ] ) {
2018-11-15 01:53:26 +01:00
[ mainSection
addItem : [ OWSTableItem
itemWithCustomCellBlock : ^ {
OWSConversationSettingsViewController * strongSelf = weakSelf ;
OWSCAssertDebug ( strongSelf ) ;
return [ strongSelf
2019-03-22 20:54:35 +01:00
labelCellWithName :
( strongSelf . isGroupThread
? NSLocalizedString (
@ "CONVERSATION_SETTINGS_VIEW_PROFILE_IS_SHARED_WITH_GROUP" ,
@ "Indicates that user's profile has been shared with a group." )
: NSLocalizedString (
@ "CONVERSATION_SETTINGS_VIEW_PROFILE_IS_SHARED_WITH_USER" ,
@ "Indicates that user's profile has been shared with a user." ) )
iconName : @ "table_ic_share_profile"
accessibilityIdentifier : ACCESSIBILITY_IDENTIFIER _WITH _NAME (
OWSConversationSettingsViewController ,
@ "profile_is_shared" ) ] ;
2018-11-15 01:53:26 +01:00
}
actionBlock : nil ] ] ;
2017-08-01 22:16:33 +02:00
} else {
2018-09-11 01:48:37 +02:00
[ mainSection
addItem : [ OWSTableItem
itemWithCustomCellBlock : ^ {
2018-11-15 01:53:26 +01:00
OWSConversationSettingsViewController * strongSelf = weakSelf ;
OWSCAssertDebug ( strongSelf ) ;
UITableViewCell * cell = [ strongSelf
2019-03-22 20:54:35 +01:00
disclosureCellWithName :
( strongSelf . isGroupThread
? NSLocalizedString ( @ "CONVERSATION_SETTINGS_VIEW_SHARE_PROFILE_WITH_GROUP" ,
@ "Action that shares user profile with a group." )
: NSLocalizedString ( @ "CONVERSATION_SETTINGS_VIEW_SHARE_PROFILE_WITH_USER" ,
@ "Action that shares user profile with a user." ) )
iconName : @ "table_ic_share_profile"
accessibilityIdentifier : ACCESSIBILITY_IDENTIFIER _WITH _NAME (
OWSConversationSettingsViewController , @ "share_profile" ) ] ;
2018-11-15 01:53:26 +01:00
cell . userInteractionEnabled = ! strongSelf . hasLeftGroup ;
2018-09-11 01:48:37 +02:00
return cell ;
}
actionBlock : ^ {
[ weakSelf showShareProfileAlert ] ;
} ] ] ;
2017-08-01 22:16:33 +02:00
}
2019-06-14 07:25:39 +02:00
* === === =
* /
2017-08-01 22:16:33 +02:00
2020-08-13 07:08:26 +02:00
if ( ! [ self isOpenGroupChat ] ) {
2019-12-13 01:23:45 +01:00
[ mainSection addItem : [ OWSTableItem
itemWithCustomCellBlock : ^ {
UITableViewCell * cell = [ OWSTableItem newCell ] ;
OWSConversationSettingsViewController * strongSelf = weakSelf ;
OWSCAssertDebug ( strongSelf ) ;
cell . preservesSuperviewLayoutMargins = YES ;
cell . contentView . preservesSuperviewLayoutMargins = YES ;
cell . selectionStyle = UITableViewCellSelectionStyleNone ;
NSString * iconName
= ( strongSelf . disappearingMessagesConfiguration . isEnabled ? @ "ic_timer"
: @ "ic_timer_disabled" ) ;
UIImageView * iconView = [ strongSelf viewForIconWithName : iconName ] ;
UILabel * rowLabel = [ UILabel new ] ;
rowLabel . text = NSLocalizedString (
@ "DISAPPEARING_MESSAGES" , @ "table cell label in conversation settings" ) ;
rowLabel . textColor = LKColors . text ;
rowLabel . font = [ UIFont systemFontOfSize : LKValues . mediumFontSize ] ;
rowLabel . lineBreakMode = NSLineBreakByTruncatingTail ;
UISwitch * switchView = [ UISwitch new ] ;
switchView . on = strongSelf . disappearingMessagesConfiguration . isEnabled ;
[ switchView addTarget : strongSelf
action : @ selector ( disappearingMessagesSwitchValueDidChange : )
forControlEvents : UIControlEventValueChanged ] ;
UIStackView * topRow =
[ [ UIStackView alloc ] initWithArrangedSubviews : @ [ iconView , rowLabel , switchView ] ] ;
topRow . spacing = strongSelf . iconSpacing ;
topRow . alignment = UIStackViewAlignmentCenter ;
[ cell . contentView addSubview : topRow ] ;
[ topRow autoPinEdgesToSuperviewMarginsExcludingEdge : ALEdgeBottom ] ;
UILabel * subtitleLabel = [ UILabel new ] ;
2020-08-18 05:58:24 +02:00
NSString * displayName ;
2020-08-13 07:08:26 +02:00
if ( self . thread . isGroupThread ) {
2020-08-18 05:58:24 +02:00
displayName = @ "the group" ;
2020-08-13 07:08:26 +02:00
} else {
2020-08-18 05:58:24 +02:00
displayName = [ LKUserDisplayNameUtilities getPrivateChatDisplayNameFor : self . thread . contactIdentifier ] ;
2020-08-13 07:08:26 +02:00
}
2020-08-18 05:58:24 +02:00
subtitleLabel . text = [ NSString stringWithFormat : NSLocalizedString ( @ "When enabled, messages between you and %@ will disappear after they have been seen." , "" ) , displayName ] ;
2019-12-13 01:23:45 +01:00
subtitleLabel . textColor = LKColors . text ;
subtitleLabel . font = [ UIFont systemFontOfSize : LKValues . smallFontSize ] ;
subtitleLabel . numberOfLines = 0 ;
subtitleLabel . lineBreakMode = NSLineBreakByWordWrapping ;
[ cell . contentView addSubview : subtitleLabel ] ;
[ subtitleLabel autoPinEdge : ALEdgeTop toEdge : ALEdgeBottom ofView : topRow withOffset : 8 ] ;
[ subtitleLabel autoPinEdge : ALEdgeLeading toEdge : ALEdgeLeading ofView : rowLabel ] ;
[ subtitleLabel autoPinTrailingToSuperviewMargin ] ;
[ subtitleLabel autoPinBottomToSuperviewMargin ] ;
cell . userInteractionEnabled = ! strongSelf . hasLeftGroup ;
cell . accessibilityIdentifier = ACCESSIBILITY_IDENTIFIER _WITH _NAME (
OWSConversationSettingsViewController , @ "disappearing_messages" ) ;
return cell ;
}
customRowHeight : UITableViewAutomaticDimension
actionBlock : nil ] ] ;
2019-03-22 20:54:35 +01:00
2019-12-13 01:23:45 +01:00
if ( self . disappearingMessagesConfiguration . isEnabled ) {
[ mainSection
addItem : [ OWSTableItem
itemWithCustomCellBlock : ^ {
UITableViewCell * cell = [ OWSTableItem newCell ] ;
OWSConversationSettingsViewController * strongSelf = weakSelf ;
OWSCAssertDebug ( strongSelf ) ;
cell . preservesSuperviewLayoutMargins = YES ;
cell . contentView . preservesSuperviewLayoutMargins = YES ;
cell . selectionStyle = UITableViewCellSelectionStyleNone ;
UIImageView * iconView = [ strongSelf viewForIconWithName : @ "ic_timer" ] ;
UILabel * rowLabel = strongSelf . disappearingMessagesDurationLabel ;
[ strongSelf updateDisappearingMessagesDurationLabel ] ;
rowLabel . textColor = LKColors . text ;
rowLabel . font = [ UIFont systemFontOfSize : LKValues . mediumFontSize ] ;
// don ' t truncate useful duration info which is in the tail
rowLabel . lineBreakMode = NSLineBreakByTruncatingHead ;
UIStackView * topRow =
[ [ UIStackView alloc ] initWithArrangedSubviews : @ [ iconView , rowLabel ] ] ;
topRow . spacing = strongSelf . iconSpacing ;
topRow . alignment = UIStackViewAlignmentCenter ;
[ cell . contentView addSubview : topRow ] ;
[ topRow autoPinEdgesToSuperviewMarginsExcludingEdge : ALEdgeBottom ] ;
UISlider * slider = [ UISlider new ] ;
slider . maximumValue = ( float ) ( strongSelf . disappearingMessagesDurations . count - 1 ) ;
slider . minimumValue = 0 ;
slider . tintColor = LKColors . accent ;
2020-09-10 03:15:08 +02:00
slider . continuous = NO ;
2019-12-13 01:23:45 +01:00
slider . value = strongSelf . disappearingMessagesConfiguration . durationIndex ;
[ slider addTarget : strongSelf
action : @ selector ( durationSliderDidChange : )
forControlEvents : UIControlEventValueChanged ] ;
[ cell . contentView addSubview : slider ] ;
[ slider autoPinEdge : ALEdgeTop toEdge : ALEdgeBottom ofView : topRow withOffset : 6 ] ;
[ slider autoPinEdge : ALEdgeLeading toEdge : ALEdgeLeading ofView : rowLabel ] ;
[ slider autoPinTrailingToSuperviewMargin ] ;
[ slider autoPinBottomToSuperviewMargin ] ;
cell . userInteractionEnabled = ! strongSelf . hasLeftGroup ;
cell . accessibilityIdentifier = ACCESSIBILITY_IDENTIFIER _WITH _NAME (
OWSConversationSettingsViewController , @ "disappearing_messages_duration" ) ;
return cell ;
}
customRowHeight : UITableViewAutomaticDimension
actionBlock : nil ] ] ;
}
2017-04-03 16:29:11 +02:00
}
2018-10-09 22:06:23 +02:00
# ifdef SHOW_COLOR _PICKER
2018-10-01 22:44:45 +02:00
[ mainSection
addItem : [ OWSTableItem
itemWithCustomCellBlock : ^ {
2018-11-15 01:53:26 +01:00
OWSConversationSettingsViewController * strongSelf = weakSelf ;
OWSCAssertDebug ( strongSelf ) ;
ConversationColorName colorName = strongSelf . thread . conversationColorName ;
2018-10-01 22:44:45 +02:00
UIColor * currentColor =
[ OWSConversationColor conversationColorOrDefaultForColorName : colorName ] . themeColor ;
NSString * title = NSLocalizedString ( @ "CONVERSATION_SETTINGS_CONVERSATION_COLOR" ,
@ "Label for table cell which leads to picking a new conversation color" ) ;
2019-03-22 20:54:35 +01:00
return [ strongSelf
cellWithName : title
iconName : @ "ic_color_palette"
disclosureIconColor : currentColor
accessibilityIdentifier : ACCESSIBILITY_IDENTIFIER _WITH _NAME (
OWSConversationSettingsViewController , @ "conversation_color" ) ] ;
2018-10-01 22:44:45 +02:00
}
actionBlock : ^ {
[ weakSelf showColorPicker ] ;
} ] ] ;
2018-10-09 22:06:23 +02:00
# endif
2017-04-03 16:29:11 +02:00
2017-07-04 22:40:28 +02:00
[ contents addSection : mainSection ] ;
2017-04-17 21:13:15 +02:00
// Group settings section .
2017-04-03 16:29:11 +02:00
2020-09-30 02:13:49 +02:00
__block BOOL isUserMember = NO ;
if ( self . isGroupThread ) {
NSString * userPublicKey = OWSIdentityManager . sharedManager . identityKeyPair . hexEncodedPublicKey ;
[ LKStorage readWithBlock : ^ ( YapDatabaseReadTransaction * transaction ) {
isUserMember = [ ( TSGroupThread * ) self . thread isUserMemberInGroup : userPublicKey transaction : transaction ] ;
} ] ;
}
2020-09-29 06:36:18 +02:00
if ( self . isGroupThread && self . isPrivateGroupChat && isUserMember ) {
2020-09-25 08:20:42 +02:00
if ( ( ( TSGroupThread * ) self . thread ) . usesSharedSenderKeys ) {
[ mainSection addItem : [ OWSTableItem
itemWithCustomCellBlock : ^ {
UITableViewCell * cell =
[ weakSelf disclosureCellWithName : NSLocalizedString ( @ "EDIT_GROUP_ACTION" ,
@ "table cell label in conversation settings" )
iconName : @ "table_ic_group_edit"
accessibilityIdentifier : ACCESSIBILITY_IDENTIFIER _WITH _NAME (
OWSConversationSettingsViewController , @ "edit_group" ) ] ;
cell . userInteractionEnabled = ! weakSelf . hasLeftGroup ;
return cell ;
}
actionBlock : ^ {
[ weakSelf editGroup ] ;
} ]
] ;
}
// [ mainSection addItem : [ OWSTableItem
2020-01-29 01:50:32 +01:00
// itemWithCustomCellBlock : ^ {
// UITableViewCell * cell =
2020-09-25 08:20:42 +02:00
// [ weakSelf disclosureCellWithName : NSLocalizedString ( @ "LIST_GROUP_MEMBERS_ACTION" ,
2020-01-29 01:50:32 +01:00
// @ "table cell label in conversation settings" )
2020-09-25 08:20:42 +02:00
// iconName : @ "table_ic_group_members"
2020-01-29 01:50:32 +01:00
// accessibilityIdentifier : ACCESSIBILITY_IDENTIFIER _WITH _NAME (
2020-09-25 08:20:42 +02:00
// OWSConversationSettingsViewController , @ "group_members" ) ] ;
2020-01-29 01:50:32 +01:00
// return cell ;
// }
// actionBlock : ^ {
2020-09-25 08:20:42 +02:00
// [ weakSelf showGroupMembersView ] ;
// } ]
// ] ;
2020-09-29 06:36:18 +02:00
[ mainSection addItem : [ OWSTableItem
itemWithCustomCellBlock : ^ {
UITableViewCell * cell =
[ weakSelf disclosureCellWithName : NSLocalizedString ( @ "LEAVE_GROUP_ACTION" ,
@ "table cell label in conversation settings" )
iconName : @ "table_ic_group_leave"
accessibilityIdentifier : ACCESSIBILITY_IDENTIFIER _WITH _NAME (
OWSConversationSettingsViewController , @ "leave_group" ) ] ;
cell . userInteractionEnabled = ! weakSelf . hasLeftGroup ;
return cell ;
}
actionBlock : ^ {
[ weakSelf didTapLeaveGroup ] ;
} ]
] ;
2017-04-03 16:29:11 +02:00
}
2020-01-13 01:14:49 +01:00
2017-04-03 16:29:11 +02:00
2017-04-17 21:13:15 +02:00
// Mute thread section .
2018-12-21 19:03:09 +01:00
if ( ! isNoteToSelf ) {
2019-09-10 07:47:34 +02:00
// OWSTableSection * notificationsSection = [ OWSTableSection new ] ;
2018-12-21 19:03:09 +01:00
// We need a section header to separate the notifications UI from the group settings UI .
2019-09-10 07:47:34 +02:00
// notificationsSection . headerTitle = NSLocalizedString (
// @ "SETTINGS_SECTION_NOTIFICATIONS" , @ "Label for the notifications section of conversation settings view." ) ;
2018-02-23 21:25:58 +01:00
2019-09-10 07:47:34 +02:00
[ mainSection
2018-12-21 19:03:09 +01:00
addItem : [ OWSTableItem
itemWithCustomCellBlock : ^ {
UITableViewCell * cell =
[ [ UITableViewCell alloc ] initWithStyle : UITableViewCellStyleValue1 reuseIdentifier : nil ] ;
[ OWSTableItem configureCell : cell ] ;
OWSConversationSettingsViewController * strongSelf = weakSelf ;
OWSCAssertDebug ( strongSelf ) ;
cell . preservesSuperviewLayoutMargins = YES ;
cell . contentView . preservesSuperviewLayoutMargins = YES ;
2018-07-11 20:40:59 +02:00
2018-12-21 19:03:09 +01:00
UIImageView * iconView = [ strongSelf viewForIconWithName : @ "table_ic_notification_sound" ] ;
2018-07-11 20:40:59 +02:00
2018-12-21 19:03:09 +01:00
UILabel * rowLabel = [ UILabel new ] ;
rowLabel . text = NSLocalizedString ( @ "SETTINGS_ITEM_NOTIFICATION_SOUND" ,
@ "Label for settings view that allows user to change the notification sound." ) ;
2019-12-13 01:23:45 +01:00
rowLabel . textColor = LKColors . text ;
rowLabel . font = [ UIFont systemFontOfSize : LKValues . mediumFontSize ] ;
2018-12-21 19:03:09 +01:00
rowLabel . lineBreakMode = NSLineBreakByTruncatingTail ;
2018-07-17 20:24:21 +02:00
2018-12-21 19:03:09 +01:00
UIStackView * contentRow =
[ [ UIStackView alloc ] initWithArrangedSubviews : @ [ iconView , rowLabel ] ] ;
contentRow . spacing = strongSelf . iconSpacing ;
contentRow . alignment = UIStackViewAlignmentCenter ;
[ cell . contentView addSubview : contentRow ] ;
[ contentRow autoPinEdgesToSuperviewMargins ] ;
2018-07-11 20:40:59 +02:00
2018-12-21 19:03:09 +01:00
OWSSound sound = [ OWSSounds notificationSoundForThread : strongSelf . thread ] ;
cell . detailTextLabel . text = [ OWSSounds displayNameForSound : sound ] ;
2019-03-22 20:54:35 +01:00
cell . accessibilityIdentifier = ACCESSIBILITY_IDENTIFIER _WITH _NAME (
OWSConversationSettingsViewController , @ "notifications" ) ;
2018-12-21 19:03:09 +01:00
return cell ;
}
customRowHeight : UITableViewAutomaticDimension
actionBlock : ^ {
OWSSoundSettingsViewController * vc = [ OWSSoundSettingsViewController new ] ;
vc . thread = weakSelf . thread ;
[ weakSelf . navigationController pushViewController : vc animated : YES ] ;
} ] ] ;
2019-12-13 01:23:45 +01:00
[ mainSection
addItem :
[ OWSTableItem
itemWithCustomCellBlock : ^ {
UITableViewCell * cell =
[ [ UITableViewCell alloc ] initWithStyle : UITableViewCellStyleValue1 reuseIdentifier : nil ] ;
[ OWSTableItem configureCell : cell ] ;
OWSConversationSettingsViewController * strongSelf = weakSelf ;
OWSCAssertDebug ( strongSelf ) ;
cell . preservesSuperviewLayoutMargins = YES ;
cell . contentView . preservesSuperviewLayoutMargins = YES ;
2020-10-02 01:34:50 +02:00
UIImageView * iconView = [ strongSelf viewForIconWithName : @ "Mute" ] ;
2019-12-13 01:23:45 +01:00
UILabel * rowLabel = [ UILabel new ] ;
rowLabel . text = NSLocalizedString ( @ "CONVERSATION_SETTINGS_MUTE_LABEL" ,
@ "label for 'mute thread' cell in conversation settings" ) ;
rowLabel . textColor = LKColors . text ;
rowLabel . font = [ UIFont systemFontOfSize : LKValues . mediumFontSize ] ;
rowLabel . lineBreakMode = NSLineBreakByTruncatingTail ;
NSString * muteStatus = NSLocalizedString ( @ "CONVERSATION_SETTINGS_MUTE_NOT_MUTED" ,
@ "Indicates that the current thread is not muted." ) ;
NSDate * mutedUntilDate = strongSelf . thread . mutedUntilDate ;
NSDate * now = [ NSDate date ] ;
if ( mutedUntilDate ! = nil && [ mutedUntilDate timeIntervalSinceDate : now ] > 0 ) {
NSCalendar * calendar = [ NSCalendar currentCalendar ] ;
NSCalendarUnit calendarUnits = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay ;
NSDateComponents * muteUntilComponents =
[ calendar components : calendarUnits fromDate : mutedUntilDate ] ;
NSDateComponents * nowComponents = [ calendar components : calendarUnits fromDate : now ] ;
NSDateFormatter * dateFormatter = [ [ NSDateFormatter alloc ] init ] ;
if ( nowComponents . year ! = muteUntilComponents . year
|| nowComponents . month ! = muteUntilComponents . month
|| nowComponents . day ! = muteUntilComponents . day ) {
[ dateFormatter setDateStyle : NSDateFormatterShortStyle ] ;
[ dateFormatter setTimeStyle : NSDateFormatterShortStyle ] ;
} else {
[ dateFormatter setDateStyle : NSDateFormatterNoStyle ] ;
[ dateFormatter setTimeStyle : NSDateFormatterShortStyle ] ;
2019-09-10 08:26:45 +02:00
}
2018-07-17 20:24:21 +02:00
2019-12-13 01:23:45 +01:00
muteStatus = [ NSString
stringWithFormat : NSLocalizedString ( @ "CONVERSATION_SETTINGS_MUTED_UNTIL_FORMAT" ,
@ "Indicates that this thread is muted until a given date or time. "
@ "Embeds {{The date or time which the thread is muted until}}." ) ,
[ dateFormatter stringFromDate : mutedUntilDate ] ] ;
}
2019-03-22 20:54:35 +01:00
2019-12-13 01:23:45 +01:00
UIStackView * contentRow =
[ [ UIStackView alloc ] initWithArrangedSubviews : @ [ iconView , rowLabel ] ] ;
contentRow . spacing = strongSelf . iconSpacing ;
contentRow . alignment = UIStackViewAlignmentCenter ;
[ cell . contentView addSubview : contentRow ] ;
[ contentRow autoPinEdgesToSuperviewMargins ] ;
2019-03-22 20:54:35 +01:00
2019-12-13 01:23:45 +01:00
cell . detailTextLabel . text = muteStatus ;
2019-09-10 08:26:45 +02:00
2019-12-13 01:23:45 +01:00
cell . accessibilityIdentifier
= ACCESSIBILITY_IDENTIFIER _WITH _NAME ( OWSConversationSettingsViewController , @ "mute" ) ;
return cell ;
}
customRowHeight : UITableViewAutomaticDimension
actionBlock : ^ {
[ weakSelf showMuteUnmuteActionSheet ] ;
} ] ] ;
// mainSection . footerTitle = NSLocalizedString (
// @ "MUTE_BEHAVIOR_EXPLANATION" , @ "An explanation of the consequences of muting a thread." ) ;
2019-09-10 08:26:45 +02:00
// [ contents addSection : notificationsSection ] ;
2018-12-21 19:03:09 +01:00
}
2018-09-07 23:45:54 +02:00
// Block Conversation section .
2017-04-17 21:13:15 +02:00
2020-07-21 06:48:04 +02:00
if ( ! isNoteToSelf && [ self . thread isKindOfClass : TSContactThread . class ] ) {
2020-10-02 01:34:50 +02:00
[ mainSection addItem : [ OWSTableItem
itemWithCustomCellBlock : ^ {
return [ weakSelf
disclosureCellWithName : @ "Reset Secure Session"
iconName : @ "system_message_security"
accessibilityIdentifier : ACCESSIBILITY_IDENTIFIER _WITH _NAME (
OWSConversationSettingsViewController , @ "reset_secure_ession" ) ] ;
}
actionBlock : ^ {
[ weakSelf resetSecureSession ] ;
} ] ] ;
2020-09-04 03:02:17 +02:00
2020-07-21 06:48:04 +02:00
mainSection . footerTitle = NSLocalizedString (
@ "BLOCK_USER_BEHAVIOR_EXPLANATION" , @ "An explanation of the consequences of blocking another user." ) ;
2017-04-17 21:13:15 +02:00
2020-07-21 06:48:04 +02:00
[ mainSection addItem : [ OWSTableItem
2018-12-21 19:03:09 +01:00
itemWithCustomCellBlock : ^ {
OWSConversationSettingsViewController * strongSelf = weakSelf ;
if ( ! strongSelf ) {
return [ UITableViewCell new ] ;
}
2020-07-21 06:48:04 +02:00
NSString * cellTitle = NSLocalizedString ( @ "CONVERSATION_SETTINGS_BLOCK_THIS_USER" ,
@ "table cell label in conversation settings" ) ;
2019-03-22 20:54:35 +01:00
UITableViewCell * cell = [ strongSelf
disclosureCellWithName : cellTitle
iconName : @ "table_ic_block"
accessibilityIdentifier : ACCESSIBILITY_IDENTIFIER _WITH _NAME (
OWSConversationSettingsViewController , @ "block" ) ] ;
2018-12-21 19:03:09 +01:00
cell . selectionStyle = UITableViewCellSelectionStyleNone ;
2018-09-07 23:45:54 +02:00
2018-12-21 19:03:09 +01:00
UISwitch * blockConversationSwitch = [ UISwitch new ] ;
blockConversationSwitch . on =
[ strongSelf . blockingManager isThreadBlocked : strongSelf . thread ] ;
[ blockConversationSwitch addTarget : strongSelf
action : @ selector ( blockConversationSwitchDidChange : )
forControlEvents : UIControlEventValueChanged ] ;
cell . accessoryView = blockConversationSwitch ;
2019-03-22 20:54:35 +01:00
2018-12-21 19:03:09 +01:00
return cell ;
2018-09-07 23:45:54 +02:00
}
2018-12-21 19:03:09 +01:00
actionBlock : nil ] ] ;
}
2018-09-07 23:45:54 +02:00
2017-04-03 16:29:11 +02:00
self . contents = contents ;
2016-09-21 14:37:51 +02:00
}
2017-07-11 18:17:28 +02:00
- ( CGFloat ) iconSpacing
{
return 12. f ;
}
2018-10-01 22:15:25 +02:00
- ( UITableViewCell * ) cellWithName : ( NSString * ) name
iconName : ( NSString * ) iconName
disclosureIconColor : ( UIColor * ) disclosureIconColor
2018-06-28 19:28:14 +02:00
{
2018-10-01 22:44:45 +02:00
UITableViewCell * cell = [ self cellWithName : name iconName : iconName ] ;
2018-10-01 22:37:46 +02:00
OWSColorPickerAccessoryView * accessoryView =
[ [ OWSColorPickerAccessoryView alloc ] initWithColor : disclosureIconColor ] ;
2018-10-01 22:44:45 +02:00
[ accessoryView sizeToFit ] ;
cell . accessoryView = accessoryView ;
2018-06-28 19:28:14 +02:00
2018-10-01 22:15:25 +02:00
return cell ;
2018-06-28 19:28:14 +02:00
}
2017-08-01 22:16:33 +02:00
- ( UITableViewCell * ) cellWithName : ( NSString * ) name iconName : ( NSString * ) iconName
2017-06-05 23:33:29 +02:00
{
2018-09-06 19:01:24 +02:00
OWSAssertDebug ( iconName . length > 0 ) ;
2018-07-03 18:57:51 +02:00
UIImageView * iconView = [ self viewForIconWithName : iconName ] ;
return [ self cellWithName : name iconView : iconView ] ;
}
- ( UITableViewCell * ) cellWithName : ( NSString * ) name iconView : ( UIView * ) iconView
{
2018-09-06 19:01:24 +02:00
OWSAssertDebug ( name . length > 0 ) ;
2017-06-05 23:33:29 +02:00
2018-07-13 00:14:04 +02:00
UITableViewCell * cell = [ OWSTableItem newCell ] ;
2017-07-11 18:17:28 +02:00
cell . preservesSuperviewLayoutMargins = YES ;
cell . contentView . preservesSuperviewLayoutMargins = YES ;
2017-06-05 23:33:29 +02:00
UILabel * rowLabel = [ UILabel new ] ;
rowLabel . text = name ;
2019-12-13 01:23:45 +01:00
rowLabel . textColor = LKColors . text ;
rowLabel . font = [ UIFont systemFontOfSize : LKValues . mediumFontSize ] ;
2017-06-05 23:33:29 +02:00
rowLabel . lineBreakMode = NSLineBreakByTruncatingTail ;
2018-07-17 20:24:21 +02:00
UIStackView * contentRow = [ [ UIStackView alloc ] initWithArrangedSubviews : @ [ iconView , rowLabel ] ] ;
contentRow . spacing = self . iconSpacing ;
[ cell . contentView addSubview : contentRow ] ;
[ contentRow autoPinEdgesToSuperviewMargins ] ;
2017-06-05 23:33:29 +02:00
return cell ;
}
2019-03-22 20:54:35 +01:00
- ( UITableViewCell * ) disclosureCellWithName : ( NSString * ) name
iconName : ( NSString * ) iconName
accessibilityIdentifier : ( NSString * ) accessibilityIdentifier
2017-08-01 22:16:33 +02:00
{
UITableViewCell * cell = [ self cellWithName : name iconName : iconName ] ;
2019-03-22 20:54:35 +01:00
cell . accessibilityIdentifier = accessibilityIdentifier ;
2017-08-01 22:16:33 +02:00
return cell ;
}
2019-03-22 20:54:35 +01:00
- ( UITableViewCell * ) labelCellWithName : ( NSString * ) name
iconName : ( NSString * ) iconName
accessibilityIdentifier : ( NSString * ) accessibilityIdentifier
2017-08-01 22:16:33 +02:00
{
UITableViewCell * cell = [ self cellWithName : name iconName : iconName ] ;
cell . accessoryType = UITableViewCellAccessoryNone ;
2019-03-22 20:54:35 +01:00
cell . accessibilityIdentifier = accessibilityIdentifier ;
2017-08-01 22:16:33 +02:00
return cell ;
}
2020-10-29 06:13:16 +01:00
static CGRect oldframe ;
- ( void ) showProfilePicture : ( UITapGestureRecognizer * ) tapGesture
{
2020-10-30 00:04:30 +01:00
LKProfilePictureView * profilePictureView = ( LKProfilePictureView * ) tapGesture . view ;
UIImage * image = [ profilePictureView getProfilePicture ] ;
2020-10-29 06:13:16 +01:00
if ( image = = nil ) { return ; }
UIWindow * window = [ UIApplication sharedApplication ] . keyWindow ;
UIView * backgroundView = [ [ UIView alloc ] initWithFrame : CGRectMake ( 0 , 0 , [ UIScreen mainScreen ] . bounds . size . width , [ UIScreen mainScreen ] . bounds . size . height ) ] ;
2020-10-30 00:04:30 +01:00
oldframe = [ profilePictureView convertRect : profilePictureView . bounds toView : window ] ;
2020-10-29 06:13:16 +01:00
backgroundView . backgroundColor = [ UIColor blackColor ] ;
backgroundView . alpha = 0 ;
2020-10-30 00:04:30 +01:00
UIImageView * imageView = [ [ UIImageView alloc ] initWithFrame : oldframe ] ;
2020-10-29 06:13:16 +01:00
imageView . image = image ;
imageView . tag = 1 ;
imageView . layer . cornerRadius = [ UIScreen mainScreen ] . bounds . size . width / 2 ;
imageView . layer . masksToBounds = true ;
[ backgroundView addSubview : imageView ] ;
[ window addSubview : backgroundView ] ;
UITapGestureRecognizer * tap = [ [ UITapGestureRecognizer alloc ] initWithTarget : self action : @ selector ( hideImage : ) ] ;
[ backgroundView addGestureRecognizer : tap ] ;
2020-10-30 00:04:30 +01:00
[ UIView animateWithDuration : 0.25 animations : ^ {
2020-10-29 06:13:16 +01:00
imageView . frame = CGRectMake ( 0 , ( [ UIScreen mainScreen ] . bounds . size . height - oldframe . size . height * [ UIScreen mainScreen ] . bounds . size . width / oldframe . size . width ) / 2 , [ UIScreen mainScreen ] . bounds . size . width , oldframe . size . height * [ UIScreen mainScreen ] . bounds . size . width / oldframe . size . width ) ;
backgroundView . alpha = 1 ;
} completion : nil ] ;
}
- ( void ) hideImage : ( UITapGestureRecognizer * ) tap {
UIView * backgroundView = tap . view ;
2020-10-30 00:04:30 +01:00
UIImageView * imageView = ( UIImageView * ) [ tap . view viewWithTag : 1 ] ;
[ UIView animateWithDuration : 0.25 animations : ^ {
2020-10-29 06:13:16 +01:00
imageView . frame = oldframe ;
backgroundView . alpha = 0 ;
} completion : ^ ( BOOL finished ) {
[ backgroundView removeFromSuperview ] ;
} ] ;
}
2017-07-04 22:40:28 +02:00
- ( UIView * ) mainSectionHeader
2017-04-17 21:13:15 +02:00
{
2020-10-29 06:13:16 +01:00
UITapGestureRecognizer * profilePictureTapGestureRecognizer = [ [ UITapGestureRecognizer alloc ] initWithTarget : self action : @ selector ( showProfilePicture : ) ] ;
2019-12-13 01:23:45 +01:00
LKProfilePictureView * profilePictureView = [ LKProfilePictureView new ] ;
CGFloat size = LKValues . largeProfilePictureSize ;
profilePictureView . size = size ;
[ profilePictureView autoSetDimension : ALDimensionWidth toSize : size ] ;
[ profilePictureView autoSetDimension : ALDimensionHeight toSize : size ] ;
2020-10-29 06:13:16 +01:00
[ profilePictureView addGestureRecognizer : profilePictureTapGestureRecognizer ] ;
2019-12-13 01:23:45 +01:00
UILabel * titleView = [ UILabel new ] ;
titleView . textColor = LKColors . text ;
2019-12-13 05:02:05 +01:00
titleView . font = [ UIFont boldSystemFontOfSize : LKValues . largeFontSize ] ;
2019-12-13 01:23:45 +01:00
titleView . lineBreakMode = NSLineBreakByTruncatingTail ;
2019-12-13 05:02:05 +01:00
titleView . text = ( self . threadName ! = nil && self . threadName . length > 0 ) ? self . threadName : @ "Anonymous" ;
2019-12-13 01:23:45 +01:00
UIStackView * stackView = [ [ UIStackView alloc ] initWithArrangedSubviews : @ [ profilePictureView , titleView ] ] ;
stackView . axis = UILayoutConstraintAxisVertical ;
stackView . spacing = LKValues . mediumSpacing ;
stackView . distribution = UIStackViewDistributionEqualCentering ;
stackView . alignment = UIStackViewAlignmentCenter ;
2020-05-29 07:11:08 +02:00
BOOL isSmallScreen = ( UIScreen . mainScreen . bounds . size . height - 568 ) < 1 ;
CGFloat horizontalSpacing = isSmallScreen ? LKValues . largeSpacing : LKValues . veryLargeSpacing ;
stackView . layoutMargins = UIEdgeInsetsMake ( LKValues . mediumSpacing , horizontalSpacing , LKValues . mediumSpacing , horizontalSpacing ) ;
2019-12-13 01:23:45 +01:00
[ stackView setLayoutMarginsRelativeArrangement : YES ] ;
2020-09-14 03:31:45 +02:00
if ( ! self . isGroupThread ) {
2020-05-29 07:11:08 +02:00
SRCopyableLabel * subtitleView = [ SRCopyableLabel new ] ;
2019-12-13 01:23:45 +01:00
subtitleView . textColor = LKColors . text ;
2020-05-29 07:11:08 +02:00
subtitleView . font = [ LKFonts spaceMonoOfSize : LKValues . smallFontSize ] ;
2019-12-13 01:23:45 +01:00
subtitleView . lineBreakMode = NSLineBreakByCharWrapping ;
subtitleView . numberOfLines = 2 ;
subtitleView . text = self . thread . contactIdentifier ;
subtitleView . textAlignment = NSTextAlignmentCenter ;
[ stackView addArrangedSubview : subtitleView ] ;
2019-09-10 08:26:45 +02:00
}
2019-12-13 01:23:45 +01:00
2020-09-14 03:31:45 +02:00
[ profilePictureView updateForThread : self . thread ] ;
2019-12-13 01:23:45 +01:00
return stackView ;
2017-04-17 21:13:15 +02:00
}
2017-04-21 21:37:51 +02:00
- ( void ) conversationNameTouched : ( UIGestureRecognizer * ) sender
{
2017-04-28 18:18:42 +02:00
if ( sender . state = = UIGestureRecognizerStateRecognized ) {
2017-04-21 21:37:51 +02:00
if ( self . isGroupThread ) {
CGPoint location = [ sender locationInView : self . avatarView ] ;
if ( CGRectContainsPoint ( self . avatarView . bounds , location ) ) {
2017-05-02 16:54:07 +02:00
[ self showUpdateGroupView : UpdateGroupMode_EditGroupAvatar ] ;
2017-04-21 21:37:51 +02:00
} else {
2017-05-02 16:54:07 +02:00
[ self showUpdateGroupView : UpdateGroupMode_EditGroupName ] ;
2017-04-21 21:37:51 +02:00
}
} else {
2017-05-18 16:04:13 +02:00
if ( self . contactsManager . supportsContactEditing ) {
[ self presentContactViewController ] ;
}
2017-04-21 21:37:51 +02:00
}
}
}
2017-04-17 21:13:15 +02:00
- ( UIImageView * ) viewForIconWithName : ( NSString * ) iconName
{
UIImage * icon = [ UIImage imageNamed : iconName ] ;
2018-01-20 17:27:32 +01:00
2018-09-06 19:01:24 +02:00
OWSAssertDebug ( icon ) ;
2017-04-17 21:13:15 +02:00
UIImageView * iconView = [ UIImageView new ] ;
iconView . image = [ icon imageWithRenderingMode : UIImageRenderingModeAlwaysTemplate ] ;
2020-03-17 06:18:53 +01:00
iconView . tintColor = LKColors . text ;
2018-01-20 17:27:32 +01:00
iconView . contentMode = UIViewContentModeScaleAspectFit ;
iconView . layer . minificationFilter = kCAFilterTrilinear ;
iconView . layer . magnificationFilter = kCAFilterTrilinear ;
2018-07-03 18:57:51 +02:00
[ iconView autoSetDimensionsToSize : CGSizeMake ( kIconViewLength , kIconViewLength ) ] ;
2017-04-17 21:13:15 +02:00
return iconView ;
}
2016-09-21 14:37:51 +02:00
- ( void ) viewWillAppear : ( BOOL ) animated
{
[ super viewWillAppear : animated ] ;
2017-03-19 20:11:57 +01:00
2018-07-19 00:48:02 +02:00
NSIndexPath * _Nullable selectedPath = [ self . tableView indexPathForSelectedRow ] ;
if ( selectedPath ) {
// HACK to unselect rows when swiping back
// http : // stackoverflow . com / questions / 19379510 / uitableviewcell - doesnt - get - deselected - when - swiping - back - quickly
[ self . tableView deselectRowAtIndexPath : selectedPath animated : animated ] ;
}
2017-07-04 22:40:28 +02:00
[ self updateTableContents ] ;
2016-09-21 14:37:51 +02:00
}
- ( void ) viewWillDisappear : ( BOOL ) animated
{
[ super viewWillDisappear : animated ] ;
if ( self . disappearingMessagesConfiguration . isNewRecord && ! self . disappearingMessagesConfiguration . isEnabled ) {
// don ' t save defaults , else we ' ll unintentionally save the configuration and notify the contact .
return ;
}
if ( self . disappearingMessagesConfiguration . dictionaryValueDidChange ) {
2020-06-11 05:25:48 +02:00
[ LKStorage writeSyncWithBlock : ^ ( YapDatabaseReadWriteTransaction * _Nonnull transaction ) {
2018-10-20 19:51:48 +02:00
[ self . disappearingMessagesConfiguration saveWithTransaction : transaction ] ;
2018-10-03 23:41:43 +02:00
// MJK TODO - should be safe to remove this senderTimestamp
2018-10-20 19:51:48 +02:00
OWSDisappearingConfigurationUpdateInfoMessage * infoMessage =
[ [ OWSDisappearingConfigurationUpdateInfoMessage alloc ]
initWithTimestamp : [ NSDate ows_millisecondTimeStamp ]
thread : self . thread
configuration : self . disappearingMessagesConfiguration
createdByRemoteName : nil
createdInExistingGroup : NO ] ;
[ infoMessage saveWithTransaction : transaction ] ;
OWSDisappearingMessagesConfigurationMessage * message = [ [ OWSDisappearingMessagesConfigurationMessage alloc ]
initWithConfiguration : self . disappearingMessagesConfiguration
thread : self . thread ] ;
[ self . messageSenderJobQueue addMessage : message transaction : transaction ] ;
2020-11-04 01:46:30 +01:00
} ] ;
2016-09-21 14:37:51 +02:00
}
}
# pragma mark - Actions
2017-08-01 22:16:33 +02:00
- ( void ) showShareProfileAlert
{
2018-12-21 19:03:09 +01:00
[ self . profileManager presentAddThreadToProfileWhitelist : self . thread
fromViewController : self
success : ^ {
[ self updateTableContents ] ;
} ] ;
2017-08-01 22:16:33 +02:00
}
2017-06-09 22:21:59 +02:00
- ( void ) showVerificationView
{
2017-06-09 22:58:00 +02:00
NSString * recipientId = self . thread . contactIdentifier ;
2018-09-06 19:01:24 +02:00
OWSAssertDebug ( recipientId . length > 0 ) ;
2017-06-09 22:58:00 +02:00
2017-06-15 22:20:33 +02:00
[ FingerprintViewController presentFromViewController : self recipientId : recipientId ] ;
2017-06-09 22:21:59 +02:00
}
- ( void ) showGroupMembersView
{
2020-01-29 01:50:32 +01:00
TSGroupThread * thread = ( TSGroupThread * ) self . thread ;
LKGroupMembersVC * groupMembersVC = [ [ LKGroupMembersVC alloc ] initWithThread : thread ] ;
[ self . navigationController pushViewController : groupMembersVC animated : YES ] ;
2017-06-09 22:21:59 +02:00
}
2017-05-02 16:54:07 +02:00
- ( void ) showUpdateGroupView : ( UpdateGroupMode ) mode
{
2018-09-06 19:01:24 +02:00
OWSAssertDebug ( self . conversationSettingsViewDelegate ) ;
2017-05-02 16:54:07 +02:00
UpdateGroupViewController * updateGroupViewController = [ UpdateGroupViewController new ] ;
updateGroupViewController . conversationSettingsViewDelegate = self . conversationSettingsViewDelegate ;
updateGroupViewController . thread = ( TSGroupThread * ) self . thread ;
updateGroupViewController . mode = mode ;
2017-08-17 18:37:21 +02:00
[ self . navigationController pushViewController : updateGroupViewController animated : YES ] ;
2017-05-02 16:54:07 +02:00
}
2017-05-10 18:07:14 +02:00
- ( void ) presentContactViewController
{
2017-05-18 14:41:28 +02:00
if ( ! self . contactsManager . supportsContactEditing ) {
2018-08-27 18:51:32 +02:00
OWSFailDebug ( @ "Contact editing not supported" ) ;
2017-05-18 14:41:28 +02:00
return ;
}
2017-05-10 18:07:14 +02:00
if ( ! [ self . thread isKindOfClass : [ TSContactThread class ] ] ) {
2018-08-27 18:51:32 +02:00
OWSFailDebug ( @ "unexpected thread: %@" , [ self . thread class ] ) ;
2017-05-10 18:07:14 +02:00
return ;
}
TSContactThread * contactThread = ( TSContactThread * ) self . thread ;
[ self . contactsViewHelper presentContactViewControllerForRecipientId : contactThread . contactIdentifier
fromViewController : self
editImmediately : YES ] ;
2017-07-18 21:38:06 +02:00
}
- ( void ) presentAddToContactViewControllerWithRecipientId : ( NSString * ) recipientId
{
if ( ! self . contactsManager . supportsContactEditing ) {
// Should not expose UI that lets the user get here .
2018-08-27 18:51:32 +02:00
OWSFailDebug ( @ "Contact editing not supported." ) ;
2017-07-18 21:38:06 +02:00
return ;
}
if ( ! self . contactsManager . isSystemContactsAuthorized ) {
2017-07-19 15:33:17 +02:00
[ self . contactsViewHelper presentMissingContactAccessAlertControllerFromViewController : self ] ;
2017-07-18 21:38:06 +02:00
return ;
}
OWSAddToContactViewController * viewController = [ OWSAddToContactViewController new ] ;
[ viewController configureWithRecipientId : recipientId ] ;
[ self . navigationController pushViewController : viewController animated : YES ] ;
2017-05-10 18:07:14 +02:00
}
- ( void ) didTapEditButton
{
[ self presentContactViewController ] ;
}
2020-09-25 08:20:42 +02:00
- ( void ) editGroup
{
LKEditClosedGroupVC * editClosedGroupVC = [ [ LKEditClosedGroupVC alloc ] initWithThreadID : self . thread . uniqueId ] ;
2020-09-28 03:43:15 +02:00
[ self . navigationController pushViewController : editClosedGroupVC animated : YES completion : nil ] ;
2020-09-25 08:20:42 +02:00
}
2016-09-21 14:37:51 +02:00
- ( void ) didTapLeaveGroup
{
2019-03-21 15:55:04 +01:00
UIAlertController * alert =
2016-09-21 14:37:51 +02:00
[ UIAlertController alertControllerWithTitle : NSLocalizedString ( @ "CONFIRM_LEAVE_GROUP_TITLE" , @ "Alert title" )
message : NSLocalizedString ( @ "CONFIRM_LEAVE_GROUP_DESCRIPTION" , @ "Alert body" )
preferredStyle : UIAlertControllerStyleAlert ] ;
UIAlertAction * leaveAction = [ UIAlertAction
2019-03-22 20:54:35 +01:00
actionWithTitle : NSLocalizedString ( @ "LEAVE_BUTTON_TITLE" , @ "Confirmation button within contextual alert" )
accessibilityIdentifier : ACCESSIBILITY_IDENTIFIER _WITH _NAME ( self , @ "leave_group_confirm" )
style : UIAlertActionStyleDestructive
handler : ^ ( UIAlertAction * _Nonnull action ) {
[ self leaveGroup ] ;
} ] ;
2019-03-21 15:55:04 +01:00
[ alert addAction : leaveAction ] ;
[ alert addAction : [ OWSAlerts cancelAction ] ] ;
2016-09-21 14:37:51 +02:00
2019-03-21 15:55:04 +01:00
[ self presentAlert : alert ] ;
2016-09-21 14:37:51 +02:00
}
2018-09-11 01:48:37 +02:00
- ( BOOL ) hasLeftGroup
{
if ( self . isGroupThread ) {
TSGroupThread * groupThread = ( TSGroupThread * ) self . thread ;
2019-01-04 15:19:41 +01:00
return ! groupThread . isLocalUserInGroup ;
2018-09-11 01:48:37 +02:00
}
return NO ;
}
2016-09-21 14:37:51 +02:00
- ( void ) leaveGroup
{
TSGroupThread * gThread = ( TSGroupThread * ) self . thread ;
2018-09-10 19:25:38 +02:00
2020-09-25 05:41:35 +02:00
if ( gThread . usesSharedSenderKeys ) {
NSString * groupPublicKey = [ LKGroupUtilities getDecodedGroupID : gThread . groupModel . groupId ] ;
[ LKStorage writeSyncWithBlock : ^ ( YapDatabaseReadWriteTransaction * _Nonnull transaction ) {
[ [ LKClosedGroupsProtocol leaveGroupWithPublicKey : groupPublicKey transaction : transaction ] retainUntilComplete ] ;
2020-11-04 01:46:30 +01:00
} ] ;
2020-09-25 05:41:35 +02:00
} else {
TSOutgoingMessage * message =
[ TSOutgoingMessage outgoingMessageInThread : gThread groupMetaMessage : TSGroupMetaMessageQuit expiresInSeconds : 0 ] ;
[ LKStorage writeSyncWithBlock : ^ ( YapDatabaseReadWriteTransaction * _Nonnull transaction ) {
[ self . messageSenderJobQueue addMessage : message transaction : transaction ] ;
[ gThread leaveGroupWithTransaction : transaction ] ;
2020-11-04 01:46:30 +01:00
} ] ;
2020-09-25 05:41:35 +02:00
}
2016-09-21 14:37:51 +02:00
[ self . navigationController popViewControllerAnimated : YES ] ;
}
2017-04-17 21:13:15 +02:00
- ( void ) disappearingMessagesSwitchValueDidChange : ( UISwitch * ) sender
2016-09-21 14:37:51 +02:00
{
UISwitch * disappearingMessagesSwitch = ( UISwitch * ) sender ;
2017-04-17 21:13:15 +02:00
2016-09-21 14:37:51 +02:00
[ self toggleDisappearingMessages : disappearingMessagesSwitch . isOn ] ;
2017-04-03 16:29:11 +02:00
[ self updateTableContents ] ;
2016-09-21 14:37:51 +02:00
}
2018-09-07 23:45:54 +02:00
- ( void ) blockConversationSwitchDidChange : ( id ) sender
2016-09-21 14:37:51 +02:00
{
2017-04-03 16:29:11 +02:00
if ( ! [ sender isKindOfClass : [ UISwitch class ] ] ) {
2018-08-27 18:51:32 +02:00
OWSFailDebug ( @ "Unexpected sender for block user switch: %@" , sender ) ;
2017-04-03 16:29:11 +02:00
}
2018-09-07 23:45:54 +02:00
UISwitch * blockConversationSwitch = ( UISwitch * ) sender ;
2017-04-03 16:29:11 +02:00
2018-09-07 23:45:54 +02:00
BOOL isCurrentlyBlocked = [ self . blockingManager isThreadBlocked : self . thread ] ;
2016-09-21 14:37:51 +02:00
2019-02-25 18:58:15 +01:00
__weak OWSConversationSettingsViewController * weakSelf = self ;
2018-09-07 23:45:54 +02:00
if ( blockConversationSwitch . isOn ) {
2018-09-06 19:01:24 +02:00
OWSAssertDebug ( ! isCurrentlyBlocked ) ;
2017-04-03 16:29:11 +02:00
if ( isCurrentlyBlocked ) {
return ;
}
2018-09-07 23:45:54 +02:00
[ BlockListUIUtils showBlockThreadActionSheet : self . thread
fromViewController : self
2018-09-10 19:25:38 +02:00
blockingManager : self . blockingManager
contactsManager : self . contactsManager
messageSender : self . messageSender
2018-09-07 23:45:54 +02:00
completionBlock : ^ ( BOOL isBlocked ) {
// Update switch state if user cancels action .
blockConversationSwitch . on = isBlocked ;
2019-02-25 18:58:15 +01:00
[ weakSelf updateTableContents ] ;
2018-09-07 23:45:54 +02:00
} ] ;
2018-09-10 19:25:38 +02:00
2016-09-21 14:37:51 +02:00
} else {
2018-09-06 19:01:24 +02:00
OWSAssertDebug ( isCurrentlyBlocked ) ;
2017-04-03 16:29:11 +02:00
if ( ! isCurrentlyBlocked ) {
return ;
}
2018-09-07 23:45:54 +02:00
[ BlockListUIUtils showUnblockThreadActionSheet : self . thread
fromViewController : self
2018-12-21 19:03:09 +01:00
blockingManager : self . blockingManager
contactsManager : self . contactsManager
2018-09-07 23:45:54 +02:00
completionBlock : ^ ( BOOL isBlocked ) {
// Update switch state if user cancels action .
blockConversationSwitch . on = isBlocked ;
2019-02-25 18:58:15 +01:00
[ weakSelf updateTableContents ] ;
2018-09-07 23:45:54 +02:00
} ] ;
2016-09-21 14:37:51 +02:00
}
}
2017-04-03 16:29:11 +02:00
- ( void ) toggleDisappearingMessages : ( BOOL ) flag
2016-09-21 14:37:51 +02:00
{
2017-04-03 16:29:11 +02:00
self . disappearingMessagesConfiguration . enabled = flag ;
2017-07-25 19:56:16 +02:00
[ self updateTableContents ] ;
2016-09-21 14:37:51 +02:00
}
2017-04-17 21:13:15 +02:00
- ( void ) durationSliderDidChange : ( UISlider * ) slider
2016-09-21 14:37:51 +02:00
{
// snap the slider to a valid value
NSUInteger index = ( NSUInteger ) ( slider . value + 0.5 ) ;
[ slider setValue : index animated : YES ] ;
NSNumber * numberOfSeconds = self . disappearingMessagesDurations [ index ] ;
self . disappearingMessagesConfiguration . durationSeconds = [ numberOfSeconds unsignedIntValue ] ;
2017-04-17 21:13:15 +02:00
[ self updateDisappearingMessagesDurationLabel ] ;
}
- ( void ) updateDisappearingMessagesDurationLabel
{
2016-09-21 14:37:51 +02:00
if ( self . disappearingMessagesConfiguration . isEnabled ) {
2020-03-17 06:18:53 +01:00
NSString * keepForFormat = @ "Disappear after %@" ;
2016-09-21 14:37:51 +02:00
self . disappearingMessagesDurationLabel . text =
[ NSString stringWithFormat : keepForFormat , self . disappearingMessagesConfiguration . durationString ] ;
} else {
self . disappearingMessagesDurationLabel . text
= NSLocalizedString ( @ "KEEP_MESSAGES_FOREVER" , @ "Slider label when disappearing messages is off" ) ;
}
2017-04-17 21:13:15 +02:00
[ self . disappearingMessagesDurationLabel setNeedsLayout ] ;
[ self . disappearingMessagesDurationLabel . superview setNeedsLayout ] ;
}
- ( void ) showMuteUnmuteActionSheet
{
2017-04-18 18:41:56 +02:00
// The "unmute" action sheet has no title or message ; the
// action label speaks for itself .
NSString * title = nil ;
2017-04-17 21:13:15 +02:00
NSString * message = nil ;
2017-04-18 18:41:56 +02:00
if ( ! self . thread . isMuted ) {
2017-04-17 21:13:15 +02:00
title = NSLocalizedString (
@ "CONVERSATION_SETTINGS_MUTE_ACTION_SHEET_TITLE" , @ "Title of the 'mute this thread' action sheet." ) ;
message = NSLocalizedString (
@ "MUTE_BEHAVIOR_EXPLANATION" , @ "An explanation of the consequences of muting a thread." ) ;
}
2019-03-21 15:55:04 +01:00
UIAlertController * actionSheet = [ UIAlertController alertControllerWithTitle : title
message : message
preferredStyle : UIAlertControllerStyleActionSheet ] ;
2017-04-17 21:13:15 +02:00
2017-08-01 22:16:33 +02:00
__weak OWSConversationSettingsViewController * weakSelf = self ;
2017-04-17 21:13:15 +02:00
if ( self . thread . isMuted ) {
UIAlertAction * action = [ UIAlertAction actionWithTitle : NSLocalizedString ( @ "CONVERSATION_SETTINGS_UNMUTE_ACTION" ,
@ "Label for button to unmute a thread." )
2019-03-22 20:54:35 +01:00
accessibilityIdentifier : ACCESSIBILITY_IDENTIFIER _WITH _NAME ( self , @ "unmute" )
2017-04-17 21:13:15 +02:00
style : UIAlertActionStyleDestructive
handler : ^ ( UIAlertAction * _Nonnull ignore ) {
[ weakSelf setThreadMutedUntilDate : nil ] ;
} ] ;
2019-03-21 15:55:04 +01:00
[ actionSheet addAction : action ] ;
2017-04-17 21:13:15 +02:00
} else {
# ifdef DEBUG
2019-03-21 15:55:04 +01:00
[ actionSheet
2017-04-17 21:13:15 +02:00
addAction : [ UIAlertAction actionWithTitle : NSLocalizedString ( @ "CONVERSATION_SETTINGS_MUTE_ONE_MINUTE_ACTION" ,
@ "Label for button to mute a thread for a minute." )
2019-03-22 20:54:35 +01:00
accessibilityIdentifier : ACCESSIBILITY_IDENTIFIER _WITH _NAME ( self , @ "mute_1_minute" )
2017-04-17 21:13:15 +02:00
style : UIAlertActionStyleDestructive
handler : ^ ( UIAlertAction * _Nonnull ignore ) {
NSTimeZone * timeZone = [ NSTimeZone timeZoneWithName : @ "UTC" ] ;
NSCalendar * calendar = [ NSCalendar currentCalendar ] ;
[ calendar setTimeZone : timeZone ] ;
NSDateComponents * dateComponents = [ NSDateComponents new ] ;
[ dateComponents setMinute : 1 ] ;
NSDate * mutedUntilDate =
[ calendar dateByAddingComponents : dateComponents
toDate : [ NSDate date ]
options : 0 ] ;
[ weakSelf setThreadMutedUntilDate : mutedUntilDate ] ;
} ] ] ;
# endif
2019-03-21 15:55:04 +01:00
[ actionSheet
2017-04-17 21:13:15 +02:00
addAction : [ UIAlertAction actionWithTitle : NSLocalizedString ( @ "CONVERSATION_SETTINGS_MUTE_ONE_HOUR_ACTION" ,
@ "Label for button to mute a thread for a hour." )
2019-03-22 20:54:35 +01:00
accessibilityIdentifier : ACCESSIBILITY_IDENTIFIER _WITH _NAME ( self , @ "mute_1_hour" )
2017-04-17 21:13:15 +02:00
style : UIAlertActionStyleDestructive
handler : ^ ( UIAlertAction * _Nonnull ignore ) {
NSTimeZone * timeZone = [ NSTimeZone timeZoneWithName : @ "UTC" ] ;
NSCalendar * calendar = [ NSCalendar currentCalendar ] ;
[ calendar setTimeZone : timeZone ] ;
NSDateComponents * dateComponents = [ NSDateComponents new ] ;
[ dateComponents setHour : 1 ] ;
NSDate * mutedUntilDate =
[ calendar dateByAddingComponents : dateComponents
toDate : [ NSDate date ]
options : 0 ] ;
[ weakSelf setThreadMutedUntilDate : mutedUntilDate ] ;
} ] ] ;
2019-03-21 15:55:04 +01:00
[ actionSheet
2017-04-17 21:13:15 +02:00
addAction : [ UIAlertAction actionWithTitle : NSLocalizedString ( @ "CONVERSATION_SETTINGS_MUTE_ONE_DAY_ACTION" ,
@ "Label for button to mute a thread for a day." )
2019-03-22 20:54:35 +01:00
accessibilityIdentifier : ACCESSIBILITY_IDENTIFIER _WITH _NAME ( self , @ "mute_1_day" )
2017-04-17 21:13:15 +02:00
style : UIAlertActionStyleDestructive
handler : ^ ( UIAlertAction * _Nonnull ignore ) {
NSTimeZone * timeZone = [ NSTimeZone timeZoneWithName : @ "UTC" ] ;
NSCalendar * calendar = [ NSCalendar currentCalendar ] ;
[ calendar setTimeZone : timeZone ] ;
NSDateComponents * dateComponents = [ NSDateComponents new ] ;
[ dateComponents setDay : 1 ] ;
NSDate * mutedUntilDate =
[ calendar dateByAddingComponents : dateComponents
toDate : [ NSDate date ]
options : 0 ] ;
[ weakSelf setThreadMutedUntilDate : mutedUntilDate ] ;
} ] ] ;
2019-03-21 15:55:04 +01:00
[ actionSheet
2017-04-17 21:13:15 +02:00
addAction : [ UIAlertAction actionWithTitle : NSLocalizedString ( @ "CONVERSATION_SETTINGS_MUTE_ONE_WEEK_ACTION" ,
@ "Label for button to mute a thread for a week." )
2019-03-22 20:54:35 +01:00
accessibilityIdentifier : ACCESSIBILITY_IDENTIFIER _WITH _NAME ( self , @ "mute_1_week" )
2017-04-17 21:13:15 +02:00
style : UIAlertActionStyleDestructive
handler : ^ ( UIAlertAction * _Nonnull ignore ) {
NSTimeZone * timeZone = [ NSTimeZone timeZoneWithName : @ "UTC" ] ;
NSCalendar * calendar = [ NSCalendar currentCalendar ] ;
[ calendar setTimeZone : timeZone ] ;
NSDateComponents * dateComponents = [ NSDateComponents new ] ;
[ dateComponents setDay : 7 ] ;
NSDate * mutedUntilDate =
[ calendar dateByAddingComponents : dateComponents
toDate : [ NSDate date ]
options : 0 ] ;
[ weakSelf setThreadMutedUntilDate : mutedUntilDate ] ;
} ] ] ;
2019-03-21 15:55:04 +01:00
[ actionSheet
2017-04-17 21:13:15 +02:00
addAction : [ UIAlertAction actionWithTitle : NSLocalizedString ( @ "CONVERSATION_SETTINGS_MUTE_ONE_YEAR_ACTION" ,
@ "Label for button to mute a thread for a year." )
2019-03-22 20:54:35 +01:00
accessibilityIdentifier : ACCESSIBILITY_IDENTIFIER _WITH _NAME ( self , @ "mute_1_year" )
2017-04-17 21:13:15 +02:00
style : UIAlertActionStyleDestructive
handler : ^ ( UIAlertAction * _Nonnull ignore ) {
NSTimeZone * timeZone = [ NSTimeZone timeZoneWithName : @ "UTC" ] ;
NSCalendar * calendar = [ NSCalendar currentCalendar ] ;
[ calendar setTimeZone : timeZone ] ;
NSDateComponents * dateComponents = [ NSDateComponents new ] ;
[ dateComponents setYear : 1 ] ;
NSDate * mutedUntilDate =
[ calendar dateByAddingComponents : dateComponents
toDate : [ NSDate date ]
options : 0 ] ;
[ weakSelf setThreadMutedUntilDate : mutedUntilDate ] ;
} ] ] ;
}
2019-03-21 15:55:04 +01:00
[ actionSheet addAction : [ OWSAlerts cancelAction ] ] ;
2017-04-17 21:13:15 +02:00
2019-03-21 15:55:04 +01:00
[ self presentAlert : actionSheet ] ;
2017-04-17 21:13:15 +02:00
}
- ( void ) setThreadMutedUntilDate : ( nullable NSDate * ) value
{
2020-06-11 05:25:48 +02:00
[ LKStorage writeSyncWithBlock : ^ ( YapDatabaseReadWriteTransaction * _Nonnull transaction ) {
2018-06-28 19:28:14 +02:00
[ self . thread updateWithMutedUntilDate : value transaction : transaction ] ;
2020-11-04 01:46:30 +01:00
} ] ;
2018-06-28 19:28:14 +02:00
2017-07-25 19:56:16 +02:00
[ self updateTableContents ] ;
2020-09-16 02:50:48 +02:00
}
- ( void ) copySessionID
{
UIPasteboard . generalPasteboard . string = self . thread . contactIdentifier ;
2016-09-21 14:37:51 +02:00
}
2018-03-15 18:46:29 +01:00
- ( void ) showMediaGallery
{
2018-11-01 01:12:56 +01:00
OWSLogDebug ( @ "" ) ;
2018-03-15 18:46:29 +01:00
2018-11-01 01:12:56 +01:00
MediaGallery * mediaGallery = [ [ MediaGallery alloc ] initWithThread : self . thread
options : MediaGalleryOptionSliderEnabled ] ;
2018-03-19 17:22:39 +01:00
2018-11-15 01:53:58 +01:00
self . mediaGallery = mediaGallery ;
2018-03-19 20:20:33 +01:00
2018-09-06 19:01:24 +02:00
OWSAssertDebug ( [ self . navigationController isKindOfClass : [ OWSNavigationController class ] ] ) ;
2018-11-01 01:12:56 +01:00
[ mediaGallery pushTileViewFromNavController : ( OWSNavigationController * ) self . navigationController ] ;
2018-03-15 18:46:29 +01:00
}
2018-11-15 01:53:58 +01:00
2019-02-11 17:49:26 +01:00
- ( void ) tappedConversationSearch
{
[ self . conversationSettingsViewDelegate conversationSettingsDidRequestConversationSearch : self ] ;
}
2020-09-04 02:07:05 +02:00
- ( void ) resetSecureSession
{
if ( ! [ self . thread isKindOfClass : TSContactThread . class ] ) { return ; }
TSContactThread * thread = ( TSContactThread * ) self . thread ;
__weak OWSConversationSettingsViewController * weakSelf = self ;
NSString * message = @ "This may help if you're having encryption problems in this conversation. Your messages will be kept." ;
UIAlertController * alert = [ UIAlertController alertControllerWithTitle : @ "Reset Secure Session?" message : message preferredStyle : UIAlertControllerStyleAlert ] ;
[ alert addAction : [ UIAlertAction actionWithTitle : NSLocalizedString ( @ "TXT_CANCEL_TITLE" , @ "" ) style : UIAlertActionStyleDefault handler : nil ] ] ;
[ alert addAction : [ UIAlertAction actionWithTitle : @ "Reset" style : UIAlertActionStyleDefault handler : ^ ( UIAlertAction * action ) {
dispatch_async ( dispatch_get _main _queue ( ) , ^ {
[ LKStorage writeSyncWithBlock : ^ ( YapDatabaseReadWriteTransaction * transaction ) {
[ thread addSessionRestoreDevice : thread . contactIdentifier transaction : transaction ] ;
[ LKSessionManagementProtocol startSessionResetInThread : thread transaction : transaction ] ;
2020-11-04 01:46:30 +01:00
} ] ;
2020-09-04 02:07:05 +02:00
[ weakSelf . navigationController popViewControllerAnimated : YES ] ;
} ) ;
} ] ] ;
[ self presentViewController : alert animated : YES completion : nil ] ;
}
2017-06-09 22:21:59 +02:00
# pragma mark - Notifications
- ( void ) identityStateDidChange : ( NSNotification * ) notification
{
2017-12-19 17:38:25 +01:00
OWSAssertIsOnMainThread ( ) ;
2017-06-09 22:21:59 +02:00
[ self updateTableContents ] ;
}
2017-08-23 23:09:43 +02:00
- ( void ) otherUsersProfileDidChange : ( NSNotification * ) notification
{
2017-12-19 17:38:25 +01:00
OWSAssertIsOnMainThread ( ) ;
2017-08-23 23:09:43 +02:00
NSString * recipientId = notification . userInfo [ kNSNotificationKey_ProfileRecipientId ] ;
2018-09-06 19:01:24 +02:00
OWSAssertDebug ( recipientId . length > 0 ) ;
2017-08-23 23:09:43 +02:00
if ( recipientId . length > 0 && [ self . thread isKindOfClass : [ TSContactThread class ] ] &&
[ self . thread . contactIdentifier isEqualToString : recipientId ] ) {
[ self updateTableContents ] ;
}
}
2018-06-28 19:28:14 +02:00
# pragma mark - ColorPickerDelegate
2018-10-09 22:06:23 +02:00
# ifdef SHOW_COLOR _PICKER
2018-06-28 19:28:14 +02:00
- ( void ) showColorPicker
{
2018-09-27 03:10:28 +02:00
OWSSheetViewController * sheetViewController = self . colorPicker . sheetViewController ;
sheetViewController . delegate = self ;
[ self presentViewController : sheetViewController
animated : YES
completion : ^ ( ) {
OWSLogInfo ( @ "presented sheet view" ) ;
} ] ;
2018-06-28 19:28:14 +02:00
}
2018-09-27 03:10:28 +02:00
- ( void ) colorPicker : ( OWSColorPicker * ) colorPicker
didPickConversationColor : ( OWSConversationColor * _Nonnull ) conversationColor
2018-06-28 19:28:14 +02:00
{
2018-09-27 03:10:28 +02:00
OWSLogDebug ( @ "picked color: %@" , conversationColor . name ) ;
2020-06-11 05:25:48 +02:00
[ LKStorage writeSyncWithBlock : ^ ( YapDatabaseReadWriteTransaction * _Nonnull transaction ) {
2018-09-27 03:10:28 +02:00
[ self . thread updateConversationColorName : conversationColor . name transaction : transaction ] ;
2020-11-04 01:46:30 +01:00
} ] ;
2018-07-04 04:28:17 +02:00
[ self . contactsManager . avatarCache removeAllImages ] ;
[ self updateTableContents ] ;
[ self . conversationSettingsViewDelegate conversationColorWasUpdated ] ;
2018-07-04 04:31:26 +02:00
dispatch_async ( dispatch_get _global _queue ( DISPATCH_QUEUE _PRIORITY _DEFAULT , 0 ) , ^ {
ConversationConfigurationSyncOperation * operation =
[ [ ConversationConfigurationSyncOperation alloc ] initWithThread : self . thread ] ;
2018-09-06 19:01:24 +02:00
OWSAssertDebug ( operation . isReady ) ;
2018-07-04 04:31:26 +02:00
[ operation start ] ;
} ) ;
2018-06-28 19:28:14 +02:00
}
2018-10-09 22:06:23 +02:00
# endif
2018-09-27 03:10:28 +02:00
# pragma mark - OWSSheetViewController
- ( void ) sheetViewControllerRequestedDismiss : ( OWSSheetViewController * ) sheetViewController
2018-06-28 19:28:14 +02:00
{
[ self dismissViewControllerAnimated : YES completion : nil ] ;
}
2016-09-21 14:37:51 +02:00
@ end
NS_ASSUME _NONNULL _END