2012-06-04 09:27:02 +00:00
|
|
|
//
|
|
|
|
// MPPreferencesViewController.m
|
|
|
|
// MasterPassword-iOS
|
|
|
|
//
|
|
|
|
// Created by Maarten Billemont on 04/06/12.
|
|
|
|
// Copyright (c) 2012 Lyndir. All rights reserved.
|
|
|
|
//
|
|
|
|
|
|
|
|
#import "MPPreferencesViewController.h"
|
2013-04-25 01:26:04 +00:00
|
|
|
#import "MPiOSAppDelegate.h"
|
2012-06-07 22:40:30 +00:00
|
|
|
#import "MPAppDelegate_Key.h"
|
2012-06-11 14:15:49 +00:00
|
|
|
#import "MPAppDelegate_Store.h"
|
2014-04-20 15:09:49 +00:00
|
|
|
#import "UIColor+Expanded.h"
|
2014-04-25 01:43:47 +00:00
|
|
|
#import "MPPasswordsViewController.h"
|
2016-01-14 15:03:30 +00:00
|
|
|
#import "MPAppDelegate_InApp.h"
|
2012-06-04 09:27:02 +00:00
|
|
|
|
2013-04-20 18:11:19 +00:00
|
|
|
@interface MPPreferencesViewController()
|
2012-06-04 09:27:02 +00:00
|
|
|
|
|
|
|
@end
|
|
|
|
|
|
|
|
@implementation MPPreferencesViewController
|
|
|
|
|
|
|
|
- (void)viewDidLoad {
|
2012-06-08 21:46:13 +00:00
|
|
|
|
2012-06-04 09:27:02 +00:00
|
|
|
[super viewDidLoad];
|
2014-04-20 15:09:49 +00:00
|
|
|
|
|
|
|
self.view.backgroundColor = [UIColor clearColor];
|
2016-01-14 15:03:30 +00:00
|
|
|
|
|
|
|
self.tableView.rowHeight = UITableViewAutomaticDimension;
|
|
|
|
self.tableView.estimatedRowHeight = 100;
|
|
|
|
self.tableView.contentInset = UIEdgeInsetsMake( 64, 0, 49, 0 );
|
2012-06-04 09:27:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void)viewWillAppear:(BOOL)animated {
|
2012-06-08 21:46:13 +00:00
|
|
|
|
2014-04-26 18:03:44 +00:00
|
|
|
inf( @"Preferences will appear" );
|
2014-04-20 15:09:49 +00:00
|
|
|
[super viewWillAppear:animated];
|
2014-09-29 02:15:55 +00:00
|
|
|
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"tipped.passwordsPreferences"];
|
2014-10-24 04:35:05 +00:00
|
|
|
if (![[NSUserDefaults standardUserDefaults] synchronize])
|
|
|
|
wrn( @"Couldn't synchronize after preferences appearance." );
|
2012-06-05 22:59:09 +00:00
|
|
|
|
2016-01-14 14:58:04 +00:00
|
|
|
[self reload];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)reload {
|
|
|
|
|
2013-06-16 16:39:52 +00:00
|
|
|
MPUserEntity *activeUser = [[MPiOSAppDelegate get] activeUserForMainThread];
|
2014-04-26 00:02:58 +00:00
|
|
|
self.generatedTypeControl.selectedSegmentIndex = [self generatedSegmentIndexForType:activeUser.defaultType];
|
|
|
|
self.storedTypeControl.selectedSegmentIndex = [self storedSegmentIndexForType:activeUser.defaultType];
|
2016-01-14 14:58:04 +00:00
|
|
|
self.avatarImage.image = [UIImage imageNamed:strf( @"avatar-%lu", (unsigned long)activeUser.avatar )];
|
2013-04-18 02:00:15 +00:00
|
|
|
self.savePasswordSwitch.on = activeUser.saveKey;
|
2016-01-14 07:14:36 +00:00
|
|
|
self.touchIDSwitch.on = activeUser.touchID;
|
2016-01-14 16:22:15 +00:00
|
|
|
self.touchIDSwitch.enabled = self.savePasswordSwitch.on && [[MPiOSAppDelegate get] isFeatureUnlocked:MPProductTouchID];
|
2012-06-04 09:27:02 +00:00
|
|
|
}
|
|
|
|
|
2014-04-20 15:09:49 +00:00
|
|
|
#pragma mark - UITableViewDelegate
|
2013-04-30 01:15:14 +00:00
|
|
|
|
2014-04-20 15:09:49 +00:00
|
|
|
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
|
2013-04-30 01:15:14 +00:00
|
|
|
|
2014-04-20 15:09:49 +00:00
|
|
|
UITableViewCell *cell = [super tableView:tableView cellForRowAtIndexPath:indexPath];
|
|
|
|
if (cell.selectionStyle != UITableViewCellSelectionStyleNone) {
|
|
|
|
cell.selectedBackgroundView = [[UIView alloc] initWithFrame:cell.bounds];
|
|
|
|
cell.selectedBackgroundView.backgroundColor = [UIColor colorWithRGBAHex:0x78DDFB33];
|
2013-04-30 01:15:14 +00:00
|
|
|
}
|
2013-04-20 18:11:19 +00:00
|
|
|
|
2014-04-20 15:09:49 +00:00
|
|
|
return cell;
|
2012-06-04 09:27:02 +00:00
|
|
|
}
|
|
|
|
|
2016-01-14 15:03:30 +00:00
|
|
|
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
|
|
|
|
|
|
|
|
return UITableViewAutomaticDimension;
|
|
|
|
}
|
|
|
|
|
2012-06-05 22:59:09 +00:00
|
|
|
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
|
2012-06-08 21:46:13 +00:00
|
|
|
|
2012-06-05 22:59:09 +00:00
|
|
|
UITableViewCell *cell = [self tableView:tableView cellForRowAtIndexPath:indexPath];
|
2014-05-18 00:12:59 +00:00
|
|
|
if (cell == self.signOutCell) {
|
2014-05-18 03:52:51 +00:00
|
|
|
[self dismissPopup];
|
2014-05-18 00:12:59 +00:00
|
|
|
[[MPiOSAppDelegate get] signOutAnimated:YES];
|
|
|
|
}
|
2014-04-25 01:43:47 +00:00
|
|
|
if (cell == self.feedbackCell)
|
|
|
|
[[MPiOSAppDelegate get] showFeedbackWithLogs:YES forVC:self];
|
2012-06-05 22:59:09 +00:00
|
|
|
if (cell == self.exportCell)
|
2014-04-25 01:43:47 +00:00
|
|
|
[[MPiOSAppDelegate get] showExportForVC:self];
|
2014-06-22 01:59:14 +00:00
|
|
|
if (cell == self.showHelpCell) {
|
2014-05-18 00:12:59 +00:00
|
|
|
MPPasswordsViewController *passwordsVC = [self dismissPopup];
|
2014-06-22 01:59:14 +00:00
|
|
|
[passwordsVC performSegueWithIdentifier:@"guide" sender:self];
|
2014-04-25 01:43:47 +00:00
|
|
|
}
|
2014-04-26 18:03:44 +00:00
|
|
|
if (cell == self.checkInconsistencies)
|
|
|
|
[MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
|
|
|
|
if ([[MPiOSAppDelegate get] findAndFixInconsistenciesSaveInContext:context] == MPFixableResultNoProblems)
|
|
|
|
[PearlAlert showAlertWithTitle:@"No Inconsistencies" message:
|
|
|
|
@"No inconsistencies were detected in your sites."
|
|
|
|
viewStyle:UIAlertViewStyleDefault initAlert:nil
|
|
|
|
tappedButtonBlock:nil cancelTitle:[PearlStrings get].commonButtonOkay otherTitles:nil];
|
|
|
|
}];
|
2012-06-05 22:59:09 +00:00
|
|
|
|
2012-06-06 20:38:43 +00:00
|
|
|
[tableView deselectRowAtIndexPath:indexPath animated:YES];
|
2012-06-05 22:59:09 +00:00
|
|
|
}
|
|
|
|
|
2014-04-20 15:09:49 +00:00
|
|
|
#pragma mark - IBActions
|
2012-06-11 14:15:49 +00:00
|
|
|
|
2014-04-20 15:09:49 +00:00
|
|
|
- (IBAction)valueChanged:(id)sender {
|
2012-06-11 14:15:49 +00:00
|
|
|
|
2014-04-20 15:09:49 +00:00
|
|
|
if (sender == self.savePasswordSwitch)
|
|
|
|
[MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
|
|
|
|
MPUserEntity *activeUser = [[MPiOSAppDelegate get] activeUserInContext:context];
|
|
|
|
if ((activeUser.saveKey = self.savePasswordSwitch.on))
|
|
|
|
[[MPiOSAppDelegate get] storeSavedKeyFor:activeUser];
|
2016-01-14 07:14:36 +00:00
|
|
|
else
|
|
|
|
[[MPiOSAppDelegate get] forgetSavedKeyFor:activeUser];
|
|
|
|
[context saveToStore];
|
2016-01-14 14:58:04 +00:00
|
|
|
|
|
|
|
PearlMainQueue(^{
|
|
|
|
[self reload];
|
|
|
|
});
|
2016-01-14 07:14:36 +00:00
|
|
|
}];
|
|
|
|
|
|
|
|
if (sender == self.touchIDSwitch)
|
|
|
|
[MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
|
|
|
|
MPUserEntity *activeUser = [[MPiOSAppDelegate get] activeUserInContext:context];
|
|
|
|
if ((activeUser.touchID = self.touchIDSwitch.on))
|
|
|
|
[[MPiOSAppDelegate get] storeSavedKeyFor:activeUser];
|
2014-04-20 15:09:49 +00:00
|
|
|
else
|
|
|
|
[[MPiOSAppDelegate get] forgetSavedKeyFor:activeUser];
|
|
|
|
[context saveToStore];
|
2016-01-14 14:58:04 +00:00
|
|
|
|
|
|
|
PearlMainQueue( ^{
|
|
|
|
[self reload];
|
|
|
|
} );
|
2014-04-20 15:09:49 +00:00
|
|
|
}];
|
|
|
|
|
2014-04-26 00:02:58 +00:00
|
|
|
if (sender == self.generatedTypeControl || sender == self.storedTypeControl) {
|
|
|
|
if (sender == self.generatedTypeControl)
|
|
|
|
self.storedTypeControl.selectedSegmentIndex = -1;
|
|
|
|
else if (sender == self.storedTypeControl)
|
|
|
|
self.generatedTypeControl.selectedSegmentIndex = -1;
|
2014-04-26 18:03:44 +00:00
|
|
|
|
2016-01-14 14:58:04 +00:00
|
|
|
MPSiteType defaultType = [self typeForSelectedSegment];
|
2014-04-20 15:09:49 +00:00
|
|
|
[MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
|
2016-01-14 14:58:04 +00:00
|
|
|
[[MPiOSAppDelegate get] activeUserInContext:context].defaultType = defaultType;
|
2014-04-20 15:09:49 +00:00
|
|
|
[context saveToStore];
|
2014-04-26 00:02:58 +00:00
|
|
|
|
|
|
|
PearlMainQueue( ^{
|
2016-01-14 14:58:04 +00:00
|
|
|
[self reload];
|
2014-04-26 00:02:58 +00:00
|
|
|
} );
|
2014-04-20 15:09:49 +00:00
|
|
|
}];
|
2014-04-26 00:02:58 +00:00
|
|
|
}
|
2014-04-20 15:09:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (IBAction)previousAvatar:(id)sender {
|
2012-06-11 14:15:49 +00:00
|
|
|
|
2013-05-16 02:42:21 +00:00
|
|
|
[MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
|
|
|
|
MPUserEntity *activeUser = [[MPiOSAppDelegate get] activeUserInContext:context];
|
2014-04-20 15:09:49 +00:00
|
|
|
activeUser.avatar = (activeUser.avatar - 1 + MPAvatarCount) % MPAvatarCount;
|
2013-05-16 02:42:21 +00:00
|
|
|
[context saveToStore];
|
2014-04-20 15:09:49 +00:00
|
|
|
|
2016-01-14 14:58:04 +00:00
|
|
|
NSUInteger avatar = activeUser.avatar;
|
2014-04-20 15:09:49 +00:00
|
|
|
PearlMainQueue( ^{
|
2016-01-14 14:58:04 +00:00
|
|
|
self.avatarImage.image = [UIImage imageNamed:strf( @"avatar-%lu", (unsigned long)avatar )];
|
2014-04-20 15:09:49 +00:00
|
|
|
} );
|
2013-05-16 02:42:21 +00:00
|
|
|
}];
|
2012-06-11 14:15:49 +00:00
|
|
|
}
|
|
|
|
|
2014-04-20 15:09:49 +00:00
|
|
|
- (IBAction)nextAvatar:(id)sender {
|
2012-06-11 14:15:49 +00:00
|
|
|
|
2014-04-20 15:09:49 +00:00
|
|
|
[MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
|
|
|
|
MPUserEntity *activeUser = [[MPiOSAppDelegate get] activeUserInContext:context];
|
|
|
|
activeUser.avatar = (activeUser.avatar + 1 + MPAvatarCount) % MPAvatarCount;
|
|
|
|
[context saveToStore];
|
2012-06-11 14:15:49 +00:00
|
|
|
|
2016-01-14 14:58:04 +00:00
|
|
|
NSUInteger avatar = activeUser.avatar;
|
2014-04-20 15:09:49 +00:00
|
|
|
PearlMainQueue( ^{
|
2016-01-14 14:58:04 +00:00
|
|
|
self.avatarImage.image = [UIImage imageNamed:strf( @"avatar-%lu", (unsigned long)avatar )];
|
2014-04-20 15:09:49 +00:00
|
|
|
} );
|
|
|
|
}];
|
|
|
|
}
|
2012-06-05 22:59:09 +00:00
|
|
|
|
2014-06-04 01:04:22 +00:00
|
|
|
- (IBAction)homePageButton:(id)sender {
|
|
|
|
|
|
|
|
[[self dismissPopup].navigationController performSegueWithIdentifier:@"web" sender:
|
|
|
|
[NSURL URLWithString:@"http://masterpasswordapp.com"]];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (IBAction)securityButton:(id)sender {
|
|
|
|
|
|
|
|
[[self dismissPopup].navigationController performSegueWithIdentifier:@"web" sender:
|
|
|
|
[NSURL URLWithString:@"http://masterpasswordapp.com/security.html"]];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (IBAction)sourceButton:(id)sender {
|
|
|
|
|
|
|
|
[[self dismissPopup].navigationController performSegueWithIdentifier:@"web" sender:
|
|
|
|
[NSURL URLWithString:@"https://github.com/Lyndir/MasterPassword/"]];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (IBAction)thanksButton:(id)sender {
|
|
|
|
|
|
|
|
[[self dismissPopup].navigationController performSegueWithIdentifier:@"web" sender:
|
|
|
|
[NSURL URLWithString:@"http://thanks.lhunath.com"]];
|
|
|
|
}
|
|
|
|
|
2014-04-20 15:09:49 +00:00
|
|
|
#pragma mark - Private
|
|
|
|
|
2014-05-18 00:12:59 +00:00
|
|
|
- (MPPasswordsViewController *)dismissPopup {
|
|
|
|
|
|
|
|
for (UIViewController *vc = self; (vc = vc.parentViewController);)
|
|
|
|
if ([vc isKindOfClass:[MPPasswordsViewController class]]) {
|
|
|
|
MPPasswordsViewController *passwordsVC = (MPPasswordsViewController *)vc;
|
|
|
|
[passwordsVC dismissPopdown:self];
|
|
|
|
return passwordsVC;
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
|
2015-01-15 22:43:41 +00:00
|
|
|
- (MPSiteType)typeForSelectedSegment {
|
2014-04-20 15:09:49 +00:00
|
|
|
|
2014-04-26 00:02:58 +00:00
|
|
|
NSInteger selectedGeneratedIndex = self.generatedTypeControl.selectedSegmentIndex;
|
|
|
|
NSInteger selectedStoredIndex = self.storedTypeControl.selectedSegmentIndex;
|
|
|
|
|
|
|
|
switch (selectedGeneratedIndex) {
|
2014-04-20 15:09:49 +00:00
|
|
|
case 0:
|
2014-09-21 14:39:09 +00:00
|
|
|
return MPSiteTypeGeneratedMaximum;
|
2014-04-20 15:09:49 +00:00
|
|
|
case 1:
|
2014-09-21 14:39:09 +00:00
|
|
|
return MPSiteTypeGeneratedLong;
|
2014-04-20 15:09:49 +00:00
|
|
|
case 2:
|
2014-09-21 14:39:09 +00:00
|
|
|
return MPSiteTypeGeneratedMedium;
|
2014-04-20 15:09:49 +00:00
|
|
|
case 3:
|
2014-09-21 14:39:09 +00:00
|
|
|
return MPSiteTypeGeneratedBasic;
|
2014-04-20 15:09:49 +00:00
|
|
|
case 4:
|
2014-09-21 14:39:09 +00:00
|
|
|
return MPSiteTypeGeneratedShort;
|
2014-04-20 15:09:49 +00:00
|
|
|
case 5:
|
2014-09-21 14:39:09 +00:00
|
|
|
return MPSiteTypeGeneratedPIN;
|
2014-04-20 15:09:49 +00:00
|
|
|
default:
|
2014-04-26 00:02:58 +00:00
|
|
|
|
|
|
|
switch (selectedStoredIndex) {
|
|
|
|
case 0:
|
2014-09-21 14:39:09 +00:00
|
|
|
return MPSiteTypeStoredPersonal;
|
2014-04-26 00:02:58 +00:00
|
|
|
case 1:
|
2014-09-21 14:39:09 +00:00
|
|
|
return MPSiteTypeStoredDevicePrivate;
|
2014-04-26 00:02:58 +00:00
|
|
|
default:
|
2014-05-18 00:12:59 +00:00
|
|
|
Throw( @"unsupported selected type index: generated=%ld, stored=%ld", (long)selectedGeneratedIndex,
|
|
|
|
(long)selectedStoredIndex );
|
2014-04-26 00:02:58 +00:00
|
|
|
}
|
2014-04-20 15:09:49 +00:00
|
|
|
}
|
|
|
|
}
|
2012-06-08 21:46:13 +00:00
|
|
|
|
2014-09-21 14:39:09 +00:00
|
|
|
- (NSInteger)generatedSegmentIndexForType:(MPSiteType)type {
|
2014-04-20 15:09:49 +00:00
|
|
|
|
|
|
|
switch (type) {
|
2014-09-21 14:39:09 +00:00
|
|
|
case MPSiteTypeGeneratedMaximum:
|
2014-04-20 15:09:49 +00:00
|
|
|
return 0;
|
2014-09-21 14:39:09 +00:00
|
|
|
case MPSiteTypeGeneratedLong:
|
2014-04-20 15:09:49 +00:00
|
|
|
return 1;
|
2014-09-21 14:39:09 +00:00
|
|
|
case MPSiteTypeGeneratedMedium:
|
2014-04-20 15:09:49 +00:00
|
|
|
return 2;
|
2014-09-21 14:39:09 +00:00
|
|
|
case MPSiteTypeGeneratedBasic:
|
2014-04-20 15:09:49 +00:00
|
|
|
return 3;
|
2014-09-21 14:39:09 +00:00
|
|
|
case MPSiteTypeGeneratedShort:
|
2014-04-20 15:09:49 +00:00
|
|
|
return 4;
|
2014-09-21 14:39:09 +00:00
|
|
|
case MPSiteTypeGeneratedPIN:
|
2014-04-20 15:09:49 +00:00
|
|
|
return 5;
|
|
|
|
default:
|
2014-04-26 00:02:58 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-09-21 14:39:09 +00:00
|
|
|
- (NSInteger)storedSegmentIndexForType:(MPSiteType)type {
|
2014-04-26 00:02:58 +00:00
|
|
|
|
|
|
|
switch (type) {
|
2014-09-21 14:39:09 +00:00
|
|
|
case MPSiteTypeStoredPersonal:
|
2014-04-26 00:02:58 +00:00
|
|
|
return 0;
|
2014-09-21 14:39:09 +00:00
|
|
|
case MPSiteTypeStoredDevicePrivate:
|
2014-04-26 00:02:58 +00:00
|
|
|
return 1;
|
|
|
|
default:
|
|
|
|
return -1;
|
2014-04-20 15:09:49 +00:00
|
|
|
}
|
2012-06-04 09:27:02 +00:00
|
|
|
}
|
2012-06-05 22:59:09 +00:00
|
|
|
|
2012-06-04 09:27:02 +00:00
|
|
|
@end
|