2014-01-06 17:55:14 -08:00
//
// OSKAccountChooserViewController . m
// Overshare
//
// Created by Jared Sinclair on 10 / 18 / 13.
// Copyright ( c ) 2013 Overshare Kit . All rights reserved .
//
# import "OSKAccountChooserViewController.h"
# import "OSKActivity.h"
# import "OSKManagedAccount.h"
# import "OSKPresentationManager.h"
# import "OSKAuthenticationViewController.h"
# import "OSKManagedAccountStore.h"
2014-05-19 13:33:42 -07:00
# import "OSKSystemAccountStore.h"
2014-01-06 17:55:14 -08:00
# import "OSKNavigationController.h"
# import "OSKActivity_ManagedAccounts.h"
# import "OSKLogger.h"
# import "OSKActionSheet.h"
@ interface OSKAccountChooserViewController ( ) < OSKAuthenticationViewControllerDelegate >
// SELECTING ACCOUNTS FOR ACTIVITIES
@ property ( copy , nonatomic ) OSKActivity < OSKActivity_ManagedAccounts > * managedAccountActivity ;
@ property ( strong , nonatomic ) ACAccount * selectedSystemAccount ;
2014-05-19 13:33:42 -07:00
@ property ( copy , nonatomic ) NSString * systemAccountTypeIdentifier ;
2014-01-06 17:55:14 -08:00
@ property ( strong , nonatomic ) OSKManagedAccount * selectedManagedAccount ;
@ property ( weak , nonatomic ) id < OSKAccountChooserViewControllerDelegate > delegate ;
// GENERAL ACCOUNT MANAGEMENT
@ property ( assign , nonatomic ) OSKAuthenticationMethod authenticationMethod ;
@ property ( strong , nonatomic ) NSMutableArray * accounts ;
@ property ( assign , nonatomic ) BOOL allowsEditing ;
@ property ( assign , nonatomic ) BOOL allowsSelection ;
@ end
@ implementation OSKAccountChooserViewController
- ( id ) initWithStyle : ( UITableViewStyle ) style {
self = [ super initWithStyle : style ] ;
if ( self ) {
}
return self ;
}
- ( instancetype ) initForManagingAccountsOfActivityClass : ( Class ) activityClass {
NSAssert ( [ activityClass isSubclassOfClass : [ OSKActivity class ] ] , @ "OSKAccountChooserViewController requires an OSKActivity subclass passed to initForManagingAccountsOfActivityClass:" ) ;
NSAssert ( [ activityClass authenticationMethod ] = = OSKAuthenticationMethod_ManagedAccounts , @ "OSKAccountChooserViewController requires a subclass of OSKActivity that conforms to OSKActivity_ManagedAccounts" ) ;
self = [ self initWithStyle : UITableViewStylePlain ] ;
if ( self ) {
self . title = [ activityClass activityName ] ;
_authenticationMethod = OSKAuthenticationMethod_ManagedAccounts ;
_accounts = [ [ [ OSKManagedAccountStore sharedInstance ] accountsForActivityType : [ activityClass activityType ] ] mutableCopy ] ;
_managedAccountActivity = [ [ activityClass alloc ] initWithContentItem : nil ] ;
_allowsEditing = YES ;
_allowsSelection = YES ;
_selectedManagedAccount = [ [ OSKManagedAccountStore sharedInstance ] activeAccountForActivityType : [ activityClass activityType ] ] ;
2014-02-27 16:54:25 -08:00
NSString * addTitle = [ OSKPresentationManager sharedInstance ] . localizedText_Add ;
self . navigationItem . rightBarButtonItem = [ [ UIBarButtonItem alloc ] initWithTitle : addTitle
2014-09-17 16:58:44 -07:00
style : UIBarButtonItemStylePlain
2014-02-27 16:54:25 -08:00
target : self
action : @ selector ( addAccountButtonPressed : ) ] ;
2014-01-06 17:55:14 -08:00
}
return self ;
}
2014-05-19 13:33:42 -07:00
- ( instancetype ) initWithManagedAccountActivity : ( OSKActivity < OSKActivity_ManagedAccounts > * ) activity
activeAccount : ( OSKManagedAccount * ) account
delegate : ( id < OSKAccountChooserViewControllerDelegate > ) delegate {
2014-01-06 17:55:14 -08:00
self = [ self initWithStyle : UITableViewStylePlain ] ;
if ( self ) {
self . title = [ [ OSKPresentationManager sharedInstance ] localizedText_Accounts ] ;
_managedAccountActivity = activity ;
_authenticationMethod = OSKAuthenticationMethod_ManagedAccounts ;
_accounts = [ [ [ OSKManagedAccountStore sharedInstance ] accountsForActivityType : [ activity . class activityType ] ] mutableCopy ] ;
_selectedManagedAccount = account ;
_delegate = delegate ;
_allowsEditing = YES ;
_allowsSelection = YES ;
2014-02-27 16:54:25 -08:00
NSString * addTitle = [ OSKPresentationManager sharedInstance ] . localizedText_Add ;
self . navigationItem . rightBarButtonItem = [ [ UIBarButtonItem alloc ] initWithTitle : addTitle
style : UIBarButtonItemStyleBordered
target : self
action : @ selector ( addAccountButtonPressed : ) ] ;
2014-01-06 17:55:14 -08:00
}
return self ;
}
2014-05-19 13:33:42 -07:00
- ( instancetype ) initWithSystemAccounts : ( NSArray * ) systemAccounts
activeAccount : ( ACAccount * ) account
accountTypeIdentifier : ( NSString * ) accountTypeIdentifier
delegate : ( id < OSKAccountChooserViewControllerDelegate > ) delegate {
2014-01-06 17:55:14 -08:00
self = [ self initWithStyle : UITableViewStylePlain ] ;
if ( self ) {
self . title = [ [ OSKPresentationManager sharedInstance ] localizedText_Accounts ] ;
_authenticationMethod = OSKAuthenticationMethod_SystemAccounts ;
_accounts = systemAccounts . mutableCopy ;
_selectedSystemAccount = account ;
_delegate = delegate ;
_allowsEditing = NO ;
_allowsSelection = YES ;
2014-05-19 13:33:42 -07:00
_systemAccountTypeIdentifier = [ accountTypeIdentifier copy ] ;
2014-01-06 17:55:14 -08:00
}
return self ;
}
- ( void ) viewDidLoad {
[ super viewDidLoad ] ;
OSKPresentationManager * presentationManager = [ OSKPresentationManager sharedInstance ] ;
UIColor * bgColor = [ presentationManager color_opaqueBackground ] ;
self . view . backgroundColor = bgColor ;
self . tableView . backgroundColor = bgColor ;
self . tableView . backgroundView . backgroundColor = bgColor ;
self . tableView . separatorColor = presentationManager . color_separators ;
}
# pragma mark - Table view data source
- ( NSInteger ) numberOfSectionsInTableView : ( UITableView * ) tableView {
return 1 ;
}
- ( NSInteger ) tableView : ( UITableView * ) tableView numberOfRowsInSection : ( NSInteger ) section {
return self . accounts . count ;
}
- ( UITableViewCell * ) tableView : ( UITableView * ) tableView cellForRowAtIndexPath : ( NSIndexPath * ) indexPath {
static NSString * CellIdentifier = @ "Cell" ;
UITableViewCell * cell = [ tableView dequeueReusableCellWithIdentifier : CellIdentifier ] ;
if ( cell = = nil ) {
cell = [ [ UITableViewCell alloc ] initWithStyle : UITableViewCellStyleDefault reuseIdentifier : CellIdentifier ] ;
OSKPresentationManager * presentationManager = [ OSKPresentationManager sharedInstance ] ;
UIColor * bgColor = [ presentationManager color_opaqueBackground ] ;
cell . backgroundColor = bgColor ;
cell . backgroundView . backgroundColor = bgColor ;
cell . textLabel . textColor = [ presentationManager color_text ] ;
cell . selectedBackgroundView = [ [ UIView alloc ] initWithFrame : cell . bounds ] ;
cell . selectedBackgroundView . backgroundColor = presentationManager . color_cancelButtonColor _BackgroundHighlighted ;
cell . tintColor = presentationManager . color_action ;
UIFontDescriptor * descriptor = [ [ OSKPresentationManager sharedInstance ] normalFontDescriptor ] ;
if ( descriptor ) {
[ cell . textLabel setFont : [ UIFont fontWithDescriptor : descriptor size : 17 ] ] ;
} else {
[ cell . textLabel setFont : [ UIFont systemFontOfSize : 17 ] ] ;
}
}
if ( self . authenticationMethod = = OSKAuthenticationMethod_SystemAccounts ) {
ACAccount * account = [ self . accounts objectAtIndex : indexPath . row ] ;
NSString * name = ( account . username . length ) ? account . username : account . userFullName ;
[ cell . textLabel setText : name ] ;
if ( [ account . identifier isEqualToString : self . selectedSystemAccount . identifier ] ) {
cell . accessoryType = UITableViewCellAccessoryCheckmark ;
} else {
cell . accessoryType = UITableViewCellAccessoryNone ;
}
}
else if ( self . authenticationMethod = = OSKAuthenticationMethod_ManagedAccounts ) {
OSKManagedAccount * account = [ self . accounts objectAtIndex : indexPath . row ] ;
NSString * name = [ account nonNilDisplayName ] ;
[ cell . textLabel setText : name ] ;
if ( account = = self . selectedManagedAccount ) {
cell . accessoryType = UITableViewCellAccessoryCheckmark ;
} else {
cell . accessoryType = UITableViewCellAccessoryNone ;
}
}
return cell ;
}
# pragma mark - Table view delegate
- ( void ) tableView : ( UITableView * ) tableView didSelectRowAtIndexPath : ( NSIndexPath * ) indexPath {
[ tableView deselectRowAtIndexPath : indexPath animated : YES ] ;
if ( self . allowsSelection ) {
if ( self . authenticationMethod = = OSKAuthenticationMethod_ManagedAccounts ) {
OSKManagedAccount * account = [ self . accounts objectAtIndex : indexPath . row ] ;
if ( account ! = self . selectedManagedAccount ) {
[ self setSelectedManagedAccount : account ] ;
[ self . tableView reloadData ] ;
[ self . delegate accountChooserDidSelectManagedAccount : account ] ;
}
}
else if ( self . authenticationMethod = = OSKAuthenticationMethod_SystemAccounts ) {
ACAccount * account = [ self . accounts objectAtIndex : indexPath . row ] ;
if ( [ account . identifier isEqualToString : self . selectedSystemAccount . identifier ] = = NO ) {
[ self setSelectedSystemAccount : account ] ;
[ self . tableView reloadData ] ;
[ self . delegate accountChooserDidSelectSystemAccount : account ] ;
}
}
// A tiny delay feels less jarring . . .
__weak OSKAccountChooserViewController * weakSelf = self ;
dispatch_after ( dispatch_time ( DISPATCH_TIME _NOW , 0.25 * NSEC_PER _SEC ) , dispatch_get _main _queue ( ) , ^ {
[ weakSelf . navigationController popViewControllerAnimated : YES ] ;
} ) ;
} else {
[ self showAccountSignOutActionSheet : indexPath ] ;
}
}
- ( BOOL ) tableView : ( UITableView * ) tableView canEditRowAtIndexPath : ( NSIndexPath * ) indexPath {
return [ self allowsEditing ] ;
}
- ( void ) tableView : ( UITableView * ) tableView commitEditingStyle : ( UITableViewCellEditingStyle ) editingStyle forRowAtIndexPath : ( NSIndexPath * ) indexPath {
if ( [ self allowsEditing ] ) {
if ( editingStyle = = UITableViewCellEditingStyleDelete ) {
OSKManagedAccount * account = self . accounts [ indexPath . row ] ;
OSKManagedAccountStore * store = [ OSKManagedAccountStore sharedInstance ] ;
[ store removeAccount : account forActivityType : account . activityType ] ;
[ self . accounts removeObject : account ] ;
if ( self . allowsSelection ) {
OSKManagedAccount * newActiveAccount = [ self . accounts firstObject ] ;
if ( newActiveAccount ! = self . selectedManagedAccount ) {
[ self setSelectedManagedAccount : newActiveAccount ] ;
[ self . delegate accountChooserDidSelectManagedAccount : newActiveAccount ] ;
}
[ CATransaction begin ] ;
__weak OSKAccountChooserViewController * weakSelf = self ;
[ CATransaction setCompletionBlock : ^ {
if ( weakSelf . selectedManagedAccount ) {
NSInteger index = [ weakSelf . accounts indexOfObject : weakSelf . selectedManagedAccount ] ;
NSIndexPath * indexPathToUpdate = [ NSIndexPath indexPathForRow : index inSection : 0 ] ;
[ weakSelf . tableView reloadRowsAtIndexPaths : @ [ indexPathToUpdate ] withRowAnimation : UITableViewRowAnimationNone ] ;
}
} ] ;
[ tableView deleteRowsAtIndexPaths : @ [ indexPath ] withRowAnimation : UITableViewRowAnimationFade ] ;
[ CATransaction commit ] ;
} else {
[ tableView deleteRowsAtIndexPaths : @ [ indexPath ] withRowAnimation : UITableViewRowAnimationFade ] ;
}
}
}
}
# pragma mark - Add Accounts
- ( void ) addAccountButtonPressed : ( id ) sender {
OSKManagedAccountAuthenticationViewControllerType type ;
type = [ self . managedAccountActivity . class authenticationViewControllerType ] ;
if ( type = = OSKManagedAccountAuthenticationViewControllerType_None ) {
[ self authenticateNewAccountWithoutViewController ] ;
} else {
[ self showAuthViewController ] ;
}
}
- ( void ) authenticateNewAccountWithoutViewController {
__weak OSKAccountChooserViewController * weakSelf = self ;
[ self . managedAccountActivity authenticateNewAccountWithoutViewController : ^ ( OSKManagedAccount * account , NSError * error ) {
dispatch_async ( dispatch_get _main _queue ( ) , ^ {
if ( account ) {
[ weakSelf handleNewManagedAccount : account ] ;
} else {
OSKLog ( @ "Failed to add new account: %@" , error . localizedDescription ) ;
}
} ) ;
} ] ;
}
- ( void ) showAuthViewController {
OSKPresentationManager * presManager = [ OSKPresentationManager sharedInstance ] ;
UIViewController < OSKAuthenticationViewController > * authViewController = [ presManager authenticationViewControllerForActivity : self . managedAccountActivity ] ;
[ authViewController prepareAuthenticationViewForActivity : self . managedAccountActivity delegate : self ] ;
if ( [ [ UIDevice currentDevice ] userInterfaceIdiom ] = = UIUserInterfaceIdiomPhone ) {
OSKNavigationController * navController = [ [ OSKNavigationController alloc ] initWithRootViewController : authViewController ] ;
[ self presentViewController : navController animated : YES completion : nil ] ;
} else {
[ self . navigationController pushViewController : authViewController animated : YES ] ;
}
}
- ( void ) handleNewManagedAccount : ( OSKManagedAccount * ) account {
OSKManagedAccountStore * accountStore = [ OSKManagedAccountStore sharedInstance ] ;
[ accountStore addAccount : account forActivityType : [ self . managedAccountActivity . class activityType ] ] ;
_accounts = [ [ accountStore accountsForActivityType : [ self . managedAccountActivity . class activityType ] ] mutableCopy ] ;
if ( self . allowsSelection ) {
[ self setSelectedManagedAccount : account ] ;
[ self . tableView reloadData ] ;
[ self . delegate accountChooserDidSelectManagedAccount : account ] ;
} else {
[ self . tableView reloadData ] ;
}
}
- ( void ) showAccountSignOutActionSheet : ( NSIndexPath * ) indexPath {
__weak OSKAccountChooserViewController * weakSelf = self ;
OSKPresentationManager * presentationManager = [ OSKPresentationManager sharedInstance ] ;
NSString * removeTitle = [ presentationManager localizedText_SignOut ] ;
OSKManagedAccount * account = weakSelf . accounts [ indexPath . row ] ;
OSKActionSheetButtonItem * removeItem = [ [ OSKActionSheetButtonItem alloc ] initWithTitle : removeTitle actionBlock : ^ {
OSKManagedAccountStore * store = [ OSKManagedAccountStore sharedInstance ] ;
[ store removeAccount : account forActivityType : account . activityType ] ;
[ weakSelf . accounts removeObject : account ] ;
[ weakSelf . tableView deleteRowsAtIndexPaths : @ [ indexPath ] withRowAnimation : UITableViewRowAnimationFade ] ;
} ] ;
OSKActionSheetButtonItem * cancelItem = [ OSKActionSheet cancelItem ] ;
OSKActionSheet * sheet = [ [ OSKActionSheet alloc ] initWithTitle : [ account nonNilDisplayName ] cancelButtonItem : cancelItem destructiveButtonItem : removeItem otherButtonItems : nil ] ;
[ sheet showInView : self . view ] ;
}
2014-05-19 13:33:42 -07:00
# pragma mark - Selected Accounts
2014-01-06 17:55:14 -08:00
- ( void ) setSelectedManagedAccount : ( OSKManagedAccount * ) selectedManagedAccount {
_selectedManagedAccount = selectedManagedAccount ;
if ( _selectedManagedAccount ) {
[ [ OSKManagedAccountStore sharedInstance ] setActiveAccount : _selectedManagedAccount forActivityType : _selectedManagedAccount . activityType ] ;
}
}
2014-05-19 13:33:42 -07:00
- ( void ) setSelectedSystemAccount : ( ACAccount * ) selectedSystemAccount {
_selectedSystemAccount = selectedSystemAccount ;
if ( _selectedSystemAccount ) {
[ [ OSKSystemAccountStore sharedInstance ] setLastUsedAccountIdentifier : _selectedSystemAccount . identifier
forType : self . systemAccountTypeIdentifier ] ;
}
}
2014-01-06 17:55:14 -08:00
# pragma mark - Authentication View Controller Delegate
- ( void ) authenticationViewController : ( UIViewController < OSKAuthenticationViewController > * ) viewController didAuthenticateNewAccount : ( OSKManagedAccount * ) account withActivity : ( OSKActivity < OSKActivity_ManagedAccounts > * ) activity {
[ self handleNewManagedAccount : account ] ;
if ( [ [ UIDevice currentDevice ] userInterfaceIdiom ] = = UIUserInterfaceIdiomPhone ) {
[ viewController dismissViewControllerAnimated : YES completion : nil ] ;
} else {
[ self . navigationController popViewControllerAnimated : YES ] ;
}
}
- ( void ) authenticationViewControllerDidCancel : ( UIViewController < OSKAuthenticationViewController > * ) viewController withActivity : ( OSKActivity < OSKActivity_ManagedAccounts > * ) activity {
if ( [ [ UIDevice currentDevice ] userInterfaceIdiom ] = = UIUserInterfaceIdiomPhone ) {
[ viewController dismissViewControllerAnimated : YES completion : nil ] ;
} else {
[ self . navigationController popViewControllerAnimated : YES ] ;
}
}
@ end