Commit 5b85d12f authored by Moe Ahmadi's avatar Moe Ahmadi Committed by Commit Bot

[iOS][Translate] Fix translate infobar being created in "translating" state


Currently TranslateInforbarView and its subviews assume that the translate
infobar is always created in "before translate" state, i.e., the source
language tab would be selected and the target language tab would be
unselected.

The translate infobar, however, can be created in "translating" or "after
translate" states, i.e., the target language tab would be in loading or
selected states respectively. This CL removes the assumed default state and
instead propagates the default state to the TranslateInforbarView (and its
subviews) after creation.

TBR=droger@

Bug: 910994
Change-Id: Ifdb280a104e61cde81c703a490f7637986b76a72
Reviewed-on: https://chromium-review.googlesource.com/c/1448807
Commit-Queue: Moe Ahmadi <mahmadi@chromium.org>
Reviewed-by: default avatarSergio Collazos <sczs@chromium.org>
Cr-Commit-Position: refs/heads/master@{#630049}
parent ef214ff9
...@@ -111,6 +111,9 @@ typedef NS_OPTIONS(NSUInteger, UserAction) { ...@@ -111,6 +111,9 @@ typedef NS_OPTIONS(NSUInteger, UserAction) {
infobarView.sourceLanguage = self.sourceLanguage; infobarView.sourceLanguage = self.sourceLanguage;
infobarView.targetLanguage = self.targetLanguage; infobarView.targetLanguage = self.targetLanguage;
infobarView.delegate = self; infobarView.delegate = self;
infobarView.state =
[self translateInfobarViewStateForTranslateStep:self.infoBarDelegate
->translate_step()];
_infobarView = infobarView; _infobarView = infobarView;
return infobarView; return infobarView;
} }
...@@ -120,22 +123,10 @@ typedef NS_OPTIONS(NSUInteger, UserAction) { ...@@ -120,22 +123,10 @@ typedef NS_OPTIONS(NSUInteger, UserAction) {
- (void)translateInfoBarDelegate:(translate::TranslateInfoBarDelegate*)delegate - (void)translateInfoBarDelegate:(translate::TranslateInfoBarDelegate*)delegate
didChangeTranslateStep:(translate::TranslateStep)step didChangeTranslateStep:(translate::TranslateStep)step
withErrorType:(translate::TranslateErrors::Type)errorType { withErrorType:(translate::TranslateErrors::Type)errorType {
switch (step) { _infobarView.state = [self translateInfobarViewStateForTranslateStep:step];
case translate::TranslateStep::TRANSLATE_STEP_BEFORE_TRANSLATE:
_infobarView.state = TranslateInfobarViewStateBeforeTranslate; if (step == translate::TranslateStep::TRANSLATE_STEP_TRANSLATE_ERROR) {
break; [self.translateNotificationHandler showTranslateErrorNotification];
case translate::TranslateStep::TRANSLATE_STEP_TRANSLATING:
_infobarView.state = TranslateInfobarViewStateTranslating;
break;
case translate::TranslateStep::TRANSLATE_STEP_AFTER_TRANSLATE:
_infobarView.state = TranslateInfobarViewStateAfterTranslate;
break;
case translate::TranslateStep::TRANSLATE_STEP_NEVER_TRANSLATE:
// Noop.
break;
case translate::TranslateStep::TRANSLATE_STEP_TRANSLATE_ERROR:
_infobarView.state = TranslateInfobarViewStateBeforeTranslate;
[self.translateNotificationHandler showTranslateErrorNotification];
} }
} }
...@@ -343,6 +334,23 @@ typedef NS_OPTIONS(NSUInteger, UserAction) { ...@@ -343,6 +334,23 @@ typedef NS_OPTIONS(NSUInteger, UserAction) {
#pragma mark - Private #pragma mark - Private
// Returns the infobar view state for the given translate::TranslateStep.
- (TranslateInfobarViewState)translateInfobarViewStateForTranslateStep:
(translate::TranslateStep)step {
switch (step) {
case translate::TranslateStep::TRANSLATE_STEP_BEFORE_TRANSLATE:
case translate::TranslateStep::TRANSLATE_STEP_TRANSLATE_ERROR:
return TranslateInfobarViewStateBeforeTranslate;
case translate::TranslateStep::TRANSLATE_STEP_TRANSLATING:
return TranslateInfobarViewStateTranslating;
case translate::TranslateStep::TRANSLATE_STEP_AFTER_TRANSLATE:
return TranslateInfobarViewStateAfterTranslate;
case translate::TranslateStep::TRANSLATE_STEP_NEVER_TRANSLATE:
NOTREACHED() << "Translate infobar should never be in this state.";
return TranslateInfobarViewStateBeforeTranslate;
}
}
- (void)showTranslateOptionSelector { - (void)showTranslateOptionSelector {
[self.translateOptionSelectionHandler [self.translateOptionSelectionHandler
showTranslateOptionSelectorWithInfoBarDelegate:self.infoBarDelegate showTranslateOptionSelectorWithInfoBarDelegate:self.infoBarDelegate
......
...@@ -146,6 +146,7 @@ CGFloat kScrollViewTrailingGradientStart = 0.975; ...@@ -146,6 +146,7 @@ CGFloat kScrollViewTrailingGradientStart = 0.975;
self.sourceLanguageTab = sourceLanguageTab; self.sourceLanguageTab = sourceLanguageTab;
self.sourceLanguageTab.translatesAutoresizingMaskIntoConstraints = NO; self.sourceLanguageTab.translatesAutoresizingMaskIntoConstraints = NO;
self.sourceLanguageTab.title = self.sourceLanguage; self.sourceLanguageTab.title = self.sourceLanguage;
self.sourceLanguageTab.state = self.sourceLanguageTabState;
self.sourceLanguageTab.delegate = self; self.sourceLanguageTab.delegate = self;
[self.languagesScrollView addSubview:self.sourceLanguageTab]; [self.languagesScrollView addSubview:self.sourceLanguageTab];
...@@ -154,6 +155,7 @@ CGFloat kScrollViewTrailingGradientStart = 0.975; ...@@ -154,6 +155,7 @@ CGFloat kScrollViewTrailingGradientStart = 0.975;
self.targetLanguageTab = targetLanguageTab; self.targetLanguageTab = targetLanguageTab;
self.targetLanguageTab.translatesAutoresizingMaskIntoConstraints = NO; self.targetLanguageTab.translatesAutoresizingMaskIntoConstraints = NO;
self.targetLanguageTab.title = self.targetLanguage; self.targetLanguageTab.title = self.targetLanguage;
self.targetLanguageTab.state = self.targetLanguageTabState;
self.targetLanguageTab.delegate = self; self.targetLanguageTab.delegate = self;
[self.languagesScrollView addSubview:self.targetLanguageTab]; [self.languagesScrollView addSubview:self.targetLanguageTab];
......
...@@ -26,6 +26,9 @@ const CGFloat kActivityIndicatorSize = 24; ...@@ -26,6 +26,9 @@ const CGFloat kActivityIndicatorSize = 24;
// Radius of the activity indicator. // Radius of the activity indicator.
const CGFloat kActivityIndicatorRadius = 10; const CGFloat kActivityIndicatorRadius = 10;
// Duration to wait before changing visibility of subviews after they are added.
const CGFloat kUpdateSubviewsDelay = 0.1;
// Duration of the animation to make the activity indicator visible. // Duration of the animation to make the activity indicator visible.
const NSTimeInterval kActivityIndicatorVisbilityAnimationDuration = 0.4; const NSTimeInterval kActivityIndicatorVisbilityAnimationDuration = 0.4;
...@@ -55,6 +58,14 @@ const CGFloat kButtonPadding = 12; ...@@ -55,6 +58,14 @@ const CGFloat kButtonPadding = 12;
// Create and add subviews the first time this moves to a superview. // Create and add subviews the first time this moves to a superview.
if (newSuperview && !self.subviews.count) { if (newSuperview && !self.subviews.count) {
[self setupSubviews]; [self setupSubviews];
// Delay updating visiblity of the subviews. Otherwise the activity
// indicator will not animate in the loading state.
dispatch_after(
dispatch_time(DISPATCH_TIME_NOW, kUpdateSubviewsDelay * NSEC_PER_SEC),
dispatch_get_main_queue(), ^{
[self updateSubviewsForState:self.state];
});
} }
[super willMoveToSuperview:newSuperview]; [super willMoveToSuperview:newSuperview];
} }
...@@ -69,22 +80,7 @@ const CGFloat kButtonPadding = 12; ...@@ -69,22 +80,7 @@ const CGFloat kButtonPadding = 12;
- (void)setState:(TranslateInfobarLanguageTabViewState)state { - (void)setState:(TranslateInfobarLanguageTabViewState)state {
_state = state; _state = state;
if (state == TranslateInfobarLanguageTabViewStateLoading) { [self updateSubviewsForState:state];
[self.activityIndicator startAnimating];
// Animate showing the activity indicator and hiding the button. Otherwise
// the ripple effect on the button won't be seen.
[UIView animateWithDuration:kActivityIndicatorVisbilityAnimationDuration
animations:^{
self.activityIndicator.alpha = 1.0;
self.button.alpha = 0.0;
}];
} else {
self.button.alpha = 1.0;
self.activityIndicator.alpha = 0.0;
[self.activityIndicator stopAnimating];
[self.button setTitleColor:[self titleColor] forState:UIControlStateNormal];
}
} }
#pragma mark - Private #pragma mark - Private
...@@ -96,7 +92,6 @@ const CGFloat kButtonPadding = 12; ...@@ -96,7 +92,6 @@ const CGFloat kButtonPadding = 12;
self.activityIndicator.cycleColors = self.activityIndicator.cycleColors =
@[ [[MDCPalette cr_bluePalette] tint500] ]; @[ [[MDCPalette cr_bluePalette] tint500] ];
[self.activityIndicator setRadius:kActivityIndicatorRadius]; [self.activityIndicator setRadius:kActivityIndicatorRadius];
self.activityIndicator.alpha = 0.0; // Initially hidden.
[self addSubview:self.activityIndicator]; [self addSubview:self.activityIndicator];
[NSLayoutConstraint activateConstraints:@[ [NSLayoutConstraint activateConstraints:@[
...@@ -128,6 +123,26 @@ const CGFloat kButtonPadding = 12; ...@@ -128,6 +123,26 @@ const CGFloat kButtonPadding = 12;
AddSameConstraints(self, self.button); AddSameConstraints(self, self.button);
} }
// Updates visibility of the subviews depending on |state|.
- (void)updateSubviewsForState:(TranslateInfobarLanguageTabViewState)state {
if (state == TranslateInfobarLanguageTabViewStateLoading) {
[self.activityIndicator startAnimating];
// Animate showing the activity indicator and hiding the button. Otherwise
// the ripple effect on the button won't be seen.
[UIView animateWithDuration:kActivityIndicatorVisbilityAnimationDuration
animations:^{
self.activityIndicator.alpha = 1.0;
self.button.alpha = 0.0;
}];
} else {
self.button.alpha = 1.0;
self.activityIndicator.alpha = 0.0;
[self.activityIndicator stopAnimating];
[self.button setTitleColor:[self titleColor] forState:UIControlStateNormal];
}
}
// Returns the button's title color depending on the state. // Returns the button's title color depending on the state.
- (UIColor*)titleColor { - (UIColor*)titleColor {
return self.state == TranslateInfobarLanguageTabViewStateSelected return self.state == TranslateInfobarLanguageTabViewStateSelected
......
...@@ -87,8 +87,6 @@ const CGFloat kIconTrailingMargin = 12; ...@@ -87,8 +87,6 @@ const CGFloat kIconTrailingMargin = 12;
if (!self.superview) if (!self.superview)
return; return;
self.state = TranslateInfobarViewStateBeforeTranslate;
[NamedGuide guideWithName:kTranslateInfobarOptionsGuide [NamedGuide guideWithName:kTranslateInfobarOptionsGuide
view:self.optionsButton] view:self.optionsButton]
.constrainedView = self.optionsButton; .constrainedView = self.optionsButton;
...@@ -138,26 +136,10 @@ const CGFloat kIconTrailingMargin = 12; ...@@ -138,26 +136,10 @@ const CGFloat kIconTrailingMargin = 12;
- (void)setState:(TranslateInfobarViewState)state { - (void)setState:(TranslateInfobarViewState)state {
_state = state; _state = state;
switch (state) { self.languagesView.sourceLanguageTabState =
case TranslateInfobarViewStateBeforeTranslate: [self sourceLanguageTabStateFromTranslateInfobarViewState:state];
self.languagesView.sourceLanguageTabState = self.languagesView.targetLanguageTabState =
TranslateInfobarLanguageTabViewStateSelected; [self targetLanguageTabStateFromTranslateInfobarViewState:state];
self.languagesView.targetLanguageTabState =
TranslateInfobarLanguageTabViewStateDefault;
break;
case TranslateInfobarViewStateTranslating:
self.languagesView.sourceLanguageTabState =
TranslateInfobarLanguageTabViewStateDefault;
self.languagesView.targetLanguageTabState =
TranslateInfobarLanguageTabViewStateLoading;
break;
case TranslateInfobarViewStateAfterTranslate:
self.languagesView.sourceLanguageTabState =
TranslateInfobarLanguageTabViewStateDefault;
self.languagesView.targetLanguageTabState =
TranslateInfobarLanguageTabViewStateSelected;
break;
}
} }
#pragma mark - Public #pragma mark - Public
...@@ -219,7 +201,11 @@ const CGFloat kIconTrailingMargin = 12; ...@@ -219,7 +201,11 @@ const CGFloat kIconTrailingMargin = 12;
self.languagesView = languagesView; self.languagesView = languagesView;
self.languagesView.translatesAutoresizingMaskIntoConstraints = NO; self.languagesView.translatesAutoresizingMaskIntoConstraints = NO;
self.languagesView.sourceLanguage = self.sourceLanguage; self.languagesView.sourceLanguage = self.sourceLanguage;
self.languagesView.sourceLanguageTabState =
[self sourceLanguageTabStateFromTranslateInfobarViewState:self.state];
self.languagesView.targetLanguage = self.targetLanguage; self.languagesView.targetLanguage = self.targetLanguage;
self.languagesView.targetLanguageTabState =
[self targetLanguageTabStateFromTranslateInfobarViewState:self.state];
self.languagesView.delegate = self; self.languagesView.delegate = self;
[contentView addSubview:self.languagesView]; [contentView addSubview:self.languagesView];
...@@ -266,6 +252,34 @@ const CGFloat kIconTrailingMargin = 12; ...@@ -266,6 +252,34 @@ const CGFloat kIconTrailingMargin = 12;
AddSameCenterYConstraint(contentView, self.dismissButton); AddSameCenterYConstraint(contentView, self.dismissButton);
} }
// Returns the source language tab view state for the given infobar view state.
- (TranslateInfobarLanguageTabViewState)
sourceLanguageTabStateFromTranslateInfobarViewState:
(TranslateInfobarViewState)state {
switch (state) {
case TranslateInfobarViewStateBeforeTranslate:
return TranslateInfobarLanguageTabViewStateSelected;
case TranslateInfobarViewStateTranslating:
return TranslateInfobarLanguageTabViewStateDefault;
case TranslateInfobarViewStateAfterTranslate:
return TranslateInfobarLanguageTabViewStateDefault;
}
}
// Returns the target language tab view state for the given infobar view state.
- (TranslateInfobarLanguageTabViewState)
targetLanguageTabStateFromTranslateInfobarViewState:
(TranslateInfobarViewState)state {
switch (state) {
case TranslateInfobarViewStateBeforeTranslate:
return TranslateInfobarLanguageTabViewStateDefault;
case TranslateInfobarViewStateTranslating:
return TranslateInfobarLanguageTabViewStateLoading;
case TranslateInfobarViewStateAfterTranslate:
return TranslateInfobarLanguageTabViewStateSelected;
}
}
- (ToolbarButton*)toolbarButtonWithImageNamed:(NSString*)name - (ToolbarButton*)toolbarButtonWithImageNamed:(NSString*)name
target:(id)target target:(id)target
action:(SEL)action { action:(SEL)action {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment