Honour animated property better.
Also: don't need to force a layout if not in an animation block.
This commit is contained in:
parent
f80ffd078b
commit
b428ee0003
@ -512,132 +512,140 @@
|
|||||||
|
|
||||||
- (void)updateAnimated:(BOOL)animated {
|
- (void)updateAnimated:(BOOL)animated {
|
||||||
|
|
||||||
Weakify( self );
|
|
||||||
if (![NSThread isMainThread]) {
|
if (![NSThread isMainThread]) {
|
||||||
PearlMainQueueOperation( ^{
|
PearlMainQueueOperation( ^{
|
||||||
Strongify( self );
|
|
||||||
[self updateAnimated:animated];
|
[self updateAnimated:animated];
|
||||||
} );
|
} );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
[UIView animateWithDuration:animated? .3f: 0 animations:^{
|
if (animated)
|
||||||
MPSiteEntity *mainSite = [self siteInContext:[MPiOSAppDelegate managedObjectContextForMainThreadIfReady]];
|
[UIView animateWithDuration:.3f animations:^{
|
||||||
|
[self updateWasAnimated:animated];
|
||||||
|
}];
|
||||||
|
else
|
||||||
|
[self updateWasAnimated:animated];
|
||||||
|
}
|
||||||
|
|
||||||
// UI
|
- (void)updateWasAnimated:(BOOL)animated {
|
||||||
//self.backgroundColor = mainSite.url? [UIColor greenColor]: [UIColor redColor];
|
|
||||||
self.upgradeButton.gone = !mainSite.requiresExplicitMigration && ![[MPiOSConfig get].allowDowngrade boolValue];
|
|
||||||
self.answersButton.gone = ![[MPiOSAppDelegate get] isFeatureUnlocked:MPProductGenerateAnswers];
|
|
||||||
BOOL settingsMode = self.mode == MPPasswordCellModeSettings;
|
|
||||||
self.loginNameContainer.visible = settingsMode || mainSite.loginGenerated || [mainSite.loginName length];
|
|
||||||
self.modeButton.visible = !self.transientSite;
|
|
||||||
self.modeButton.alpha = settingsMode? 0.5f: 0.1f;
|
|
||||||
self.counterLabel.visible = self.counterButton.visible = mainSite.type & MPResultTypeClassTemplate;
|
|
||||||
self.modeButton.selected = settingsMode;
|
|
||||||
self.strengthLabel.gone = !settingsMode;
|
|
||||||
self.modeScrollView.scrollEnabled = !self.transientSite;
|
|
||||||
[self.modeScrollView setContentOffset:CGPointMake( self.mode * self.modeScrollView.frame.size.width, 0 ) animated:animated];
|
|
||||||
if (!settingsMode) {
|
|
||||||
[self.loginNameField resignFirstResponder];
|
|
||||||
[self.passwordField resignFirstResponder];
|
|
||||||
}
|
|
||||||
if ([[MPiOSAppDelegate get] isFeatureUnlocked:MPProductGenerateLogins])
|
|
||||||
self.loginNameHint.text = @"Tap here to ⚙ generate username or the pencil to type one";
|
|
||||||
else
|
|
||||||
self.loginNameHint.text = @"Tap the pencil to type a username";
|
|
||||||
|
|
||||||
// Site Name
|
Weakify( self );
|
||||||
[self updateSiteName:mainSite];
|
MPSiteEntity *mainSite = [self siteInContext:[MPiOSAppDelegate managedObjectContextForMainThreadIfReady]];
|
||||||
|
|
||||||
// Site Counter
|
// UI
|
||||||
if ([mainSite isKindOfClass:[MPGeneratedSiteEntity class]])
|
//self.backgroundColor = mainSite.url? [UIColor greenColor]: [UIColor redColor];
|
||||||
self.counterLabel.text = strf( @"%lu", (unsigned long)((MPGeneratedSiteEntity *)mainSite).counter );
|
self.upgradeButton.gone = !mainSite.requiresExplicitMigration && ![[MPiOSConfig get].allowDowngrade boolValue];
|
||||||
|
self.answersButton.gone = ![[MPiOSAppDelegate get] isFeatureUnlocked:MPProductGenerateAnswers];
|
||||||
|
BOOL settingsMode = self.mode == MPPasswordCellModeSettings;
|
||||||
|
self.loginNameContainer.visible = settingsMode || mainSite.loginGenerated || [mainSite.loginName length];
|
||||||
|
self.modeButton.visible = !self.transientSite;
|
||||||
|
self.modeButton.alpha = settingsMode? 0.5f: 0.1f;
|
||||||
|
self.counterLabel.visible = self.counterButton.visible = mainSite.type & MPResultTypeClassTemplate;
|
||||||
|
self.modeButton.selected = settingsMode;
|
||||||
|
self.strengthLabel.gone = !settingsMode;
|
||||||
|
self.modeScrollView.scrollEnabled = !self.transientSite;
|
||||||
|
[self.modeScrollView setContentOffset:CGPointMake( self.mode * self.modeScrollView.frame.size.width, 0 ) animated:animated];
|
||||||
|
if (!settingsMode) {
|
||||||
|
[self.loginNameField resignFirstResponder];
|
||||||
|
[self.passwordField resignFirstResponder];
|
||||||
|
}
|
||||||
|
if ([[MPiOSAppDelegate get] isFeatureUnlocked:MPProductGenerateLogins])
|
||||||
|
self.loginNameHint.text = @"Tap here to ⚙ generate username or the pencil to type one";
|
||||||
|
else
|
||||||
|
self.loginNameHint.text = @"Tap the pencil to type a username";
|
||||||
|
|
||||||
// Site Login Name
|
// Site Name
|
||||||
self.loginNameField.enabled = self.passwordField.enabled = //
|
[self updateSiteName:mainSite];
|
||||||
[self.loginNameField isFirstResponder] || [self.passwordField isFirstResponder];
|
|
||||||
|
|
||||||
// Site Password
|
// Site Counter
|
||||||
self.passwordField.secureTextEntry = [[MPiOSConfig get].hidePasswords boolValue];
|
if ([mainSite isKindOfClass:[MPGeneratedSiteEntity class]])
|
||||||
self.passwordField.attributedPlaceholder = stra(
|
self.counterLabel.text = strf( @"%lu", (unsigned long)((MPGeneratedSiteEntity *)mainSite).counter );
|
||||||
mainSite.type & MPResultTypeClassStateful? strl( @"No password" ):
|
|
||||||
mainSite.type & MPResultTypeClassTemplate? strl( @"..." ): @"", @{
|
|
||||||
NSForegroundColorAttributeName: [UIColor whiteColor]
|
|
||||||
} );
|
|
||||||
|
|
||||||
// Calculate Fields
|
// Site Login Name
|
||||||
if (![MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
|
self.loginNameField.enabled = self.passwordField.enabled = //
|
||||||
MPKey *key = [MPiOSAppDelegate get].key;
|
[self.loginNameField isFirstResponder] || [self.passwordField isFirstResponder];
|
||||||
if (!key) {
|
|
||||||
wrn( @"Could not load cell content: key unavailable." );
|
|
||||||
PearlMainQueueOperation( ^{
|
|
||||||
Strongify( self );
|
|
||||||
[self updateAnimated:YES];
|
|
||||||
} );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
MPSiteEntity *site = [self siteInContext:context];
|
// Site Password
|
||||||
BOOL loginGenerated = site.loginGenerated;
|
self.passwordField.secureTextEntry = [[MPiOSConfig get].hidePasswords boolValue];
|
||||||
NSString *password = nil, *loginName = [site resolveLoginUsingKey:key];
|
self.passwordField.attributedPlaceholder = stra(
|
||||||
MPResultType transientType = [[MPiOSAppDelegate get] activeUserInContext:context].defaultType?: MPAlgorithmDefault.defaultType;
|
mainSite.type & MPResultTypeClassStateful? strl( @"No password" ):
|
||||||
if (self.transientSite && transientType & MPResultTypeClassTemplate)
|
mainSite.type & MPResultTypeClassTemplate? strl( @"..." ): @"", @{
|
||||||
password = [MPAlgorithmDefault mpwTemplateForSiteNamed:self.transientSite ofType:transientType
|
NSForegroundColorAttributeName: [UIColor whiteColor]
|
||||||
withCounter:1 usingKey:key];
|
|
||||||
else if (site)
|
|
||||||
password = [site resolvePasswordUsingKey:key];
|
|
||||||
|
|
||||||
TimeToCrack timeToCrack;
|
|
||||||
NSString *timeToCrackString = nil;
|
|
||||||
id<MPAlgorithm> algorithm = site.algorithm?: MPAlgorithmDefault;
|
|
||||||
MPAttacker attackHardware = [[MPConfig get].siteAttacker integerValue];
|
|
||||||
if ([algorithm timeToCrack:&timeToCrack passwordOfType:site.type byAttacker:attackHardware] ||
|
|
||||||
[algorithm timeToCrack:&timeToCrack passwordString:password byAttacker:attackHardware])
|
|
||||||
timeToCrackString = NSStringFromTimeToCrack( timeToCrack );
|
|
||||||
|
|
||||||
BOOL requiresExplicitMigration = site.requiresExplicitMigration;
|
|
||||||
|
|
||||||
PearlMainQueue( ^{
|
|
||||||
self.passwordField.text = password;
|
|
||||||
self.strengthLabel.text = timeToCrackString;
|
|
||||||
self.loginNameGenerated.hidden = !loginGenerated;
|
|
||||||
self.loginNameField.attributedText =
|
|
||||||
strarm( stra( loginName?: @"", self.siteNameLabel.textAttributes ), NSParagraphStyleAttributeName, nil );
|
|
||||||
self.loginNameHint.hidden = [loginName length] || self.loginNameField.enabled;
|
|
||||||
|
|
||||||
if (![password length]) {
|
|
||||||
self.indicatorView.hidden = NO;
|
|
||||||
[self.indicatorView removeFromSuperview];
|
|
||||||
[self.modeScrollView addSubview:self.indicatorView];
|
|
||||||
[self.contentView addConstraintsWithVisualFormat:@"V:[indicator][target]" options:NSLayoutFormatAlignAllCenterX
|
|
||||||
metrics:nil views:@{
|
|
||||||
@"indicator": self.indicatorView,
|
|
||||||
@"target" : settingsMode? self.editButton: self.modeButton
|
|
||||||
}];
|
|
||||||
}
|
|
||||||
else if (requiresExplicitMigration) {
|
|
||||||
self.indicatorView.hidden = NO;
|
|
||||||
[self.indicatorView removeFromSuperview];
|
|
||||||
[self.modeScrollView addSubview:self.indicatorView];
|
|
||||||
[self.contentView addConstraintsWithVisualFormat:@"V:[indicator][target]" options:NSLayoutFormatAlignAllCenterX
|
|
||||||
metrics:nil views:@{
|
|
||||||
@"indicator": self.indicatorView,
|
|
||||||
@"target" : settingsMode? self.upgradeButton: self.modeButton
|
|
||||||
}];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
self.indicatorView.hidden = YES;
|
|
||||||
} );
|
} );
|
||||||
}]) {
|
|
||||||
wrn( @"Could not load cell content: store unavailable." );
|
// Calculate Fields
|
||||||
|
if (![MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
|
||||||
|
MPKey *key = [MPiOSAppDelegate get].key;
|
||||||
|
if (!key) {
|
||||||
|
wrn( @"Could not load cell content: key unavailable." );
|
||||||
PearlMainQueueOperation( ^{
|
PearlMainQueueOperation( ^{
|
||||||
Strongify( self );
|
Strongify( self );
|
||||||
[self updateAnimated:YES];
|
[self updateAnimated:animated];
|
||||||
} );
|
} );
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MPSiteEntity *site = [self siteInContext:context];
|
||||||
|
BOOL loginGenerated = site.loginGenerated;
|
||||||
|
NSString *password = nil, *loginName = [site resolveLoginUsingKey:key];
|
||||||
|
MPResultType transientType = [[MPiOSAppDelegate get] activeUserInContext:context].defaultType?: MPAlgorithmDefault.defaultType;
|
||||||
|
if (self.transientSite && transientType & MPResultTypeClassTemplate)
|
||||||
|
password = [MPAlgorithmDefault mpwTemplateForSiteNamed:self.transientSite ofType:transientType
|
||||||
|
withCounter:1 usingKey:key];
|
||||||
|
else if (site)
|
||||||
|
password = [site resolvePasswordUsingKey:key];
|
||||||
|
|
||||||
|
TimeToCrack timeToCrack;
|
||||||
|
NSString *timeToCrackString = nil;
|
||||||
|
id<MPAlgorithm> algorithm = site.algorithm?: MPAlgorithmDefault;
|
||||||
|
MPAttacker attackHardware = [[MPConfig get].siteAttacker integerValue];
|
||||||
|
if ([algorithm timeToCrack:&timeToCrack passwordOfType:site.type byAttacker:attackHardware] ||
|
||||||
|
[algorithm timeToCrack:&timeToCrack passwordString:password byAttacker:attackHardware])
|
||||||
|
timeToCrackString = NSStringFromTimeToCrack( timeToCrack );
|
||||||
|
|
||||||
|
BOOL requiresExplicitMigration = site.requiresExplicitMigration;
|
||||||
|
|
||||||
|
PearlMainQueue( ^{
|
||||||
|
self.passwordField.text = password;
|
||||||
|
self.strengthLabel.text = timeToCrackString;
|
||||||
|
self.loginNameGenerated.hidden = !loginGenerated;
|
||||||
|
self.loginNameField.attributedText =
|
||||||
|
strarm( stra( loginName?: @"", self.siteNameLabel.textAttributes ), NSParagraphStyleAttributeName, nil );
|
||||||
|
self.loginNameHint.hidden = [loginName length] || self.loginNameField.enabled;
|
||||||
|
|
||||||
|
if (![password length]) {
|
||||||
|
self.indicatorView.hidden = NO;
|
||||||
|
[self.indicatorView removeFromSuperview];
|
||||||
|
[self.modeScrollView addSubview:self.indicatorView];
|
||||||
|
[self.contentView addConstraintsWithVisualFormat:@"V:[indicator][target]" options:NSLayoutFormatAlignAllCenterX
|
||||||
|
metrics:nil views:@{
|
||||||
|
@"indicator": self.indicatorView,
|
||||||
|
@"target" : settingsMode? self.editButton: self.modeButton
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
else if (requiresExplicitMigration) {
|
||||||
|
self.indicatorView.hidden = NO;
|
||||||
|
[self.indicatorView removeFromSuperview];
|
||||||
|
[self.modeScrollView addSubview:self.indicatorView];
|
||||||
|
[self.contentView addConstraintsWithVisualFormat:@"V:[indicator][target]" options:NSLayoutFormatAlignAllCenterX
|
||||||
|
metrics:nil views:@{
|
||||||
|
@"indicator": self.indicatorView,
|
||||||
|
@"target" : settingsMode? self.upgradeButton: self.modeButton
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
self.indicatorView.hidden = YES;
|
||||||
|
} );
|
||||||
|
}]) {
|
||||||
|
wrn( @"Could not load cell content: store unavailable." );
|
||||||
|
PearlMainQueueOperation( ^{
|
||||||
|
Strongify( self );
|
||||||
|
[self updateAnimated:animated];
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
if (animated)
|
||||||
[self.contentView layoutIfNeeded];
|
[self.contentView layoutIfNeeded];
|
||||||
}];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)updateSiteName:(MPSiteEntity *)site {
|
- (void)updateSiteName:(MPSiteEntity *)site {
|
||||||
|
Loading…
Reference in New Issue
Block a user