Commit e7898a3f authored by Moe Ahmadi's avatar Moe Ahmadi Committed by Commit Bot

[IOS][Language] Language Settings - Add language page.

Add language page allows the user to select a supported language to add to
the list of user preferred languages. Existing accepts languages are
excluded from the available options.

screenshot: https://drive.google.com/file/d/1gV24hPwP1Gpiw_whOW45GQGmfJn_byEi/view?usp=sharing

Bug: 957688
Change-Id: I63b261061cc867a1c7d5cd2373cb948eec1581f7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1611911Reviewed-by: default avatarPeter Lee <pkl@chromium.org>
Reviewed-by: default avatarSergio Collazos <sczs@chromium.org>
Commit-Queue: Moe Ahmadi <mahmadi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#660843}
parent a131184c
...@@ -42,6 +42,8 @@ source_set("settings") { ...@@ -42,6 +42,8 @@ source_set("settings") {
sources = [ sources = [
"about_chrome_table_view_controller.h", "about_chrome_table_view_controller.h",
"about_chrome_table_view_controller.mm", "about_chrome_table_view_controller.mm",
"add_language_table_view_controller.h",
"add_language_table_view_controller.mm",
"bandwidth_management_table_view_controller.h", "bandwidth_management_table_view_controller.h",
"bandwidth_management_table_view_controller.mm", "bandwidth_management_table_view_controller.mm",
"block_popups_table_view_controller.h", "block_popups_table_view_controller.h",
......
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_ADD_LANGUAGE_TABLE_VIEW_CONTROLLER_H_
#define IOS_CHROME_BROWSER_UI_SETTINGS_ADD_LANGUAGE_TABLE_VIEW_CONTROLLER_H_
#import "ios/chrome/browser/ui/settings/settings_root_table_view_controller.h"
@class AddLanguageTableViewController;
@protocol LanguageSettingsDataSource;
// Protocol used by AddLanguageTableViewController to communicate to its
// delegate.
@protocol AddLanguageTableViewControllerDelegate
// Informs the delegate that user selected a language with the given code.
- (void)addLanguageTableViewController:
(AddLanguageTableViewController*)tableViewController
didSelectLanguageCode:(const std::string&)languageCode;
@end
// Controller for the UI that allows the user to select a supported language to
// add to the accept languages list.
@interface AddLanguageTableViewController : SettingsRootTableViewController
// The designated initializer. |dataSource| and |delegate| must not be nil.
// |delegate| will not be retained.
- (instancetype)initWithDataSource:(id<LanguageSettingsDataSource>)dataSource
delegate:(id<AddLanguageTableViewControllerDelegate>)
delegate NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithTableViewStyle:(UITableViewStyle)style
appBarStyle:
(ChromeTableViewControllerStyle)appBarStyle
NS_UNAVAILABLE;
// Called when the list of supported languages changes so that the view
// controller can update its model from |dataSource|.
- (void)supportedLanguagesListChanged;
@end
#endif // IOS_CHROME_BROWSER_UI_SETTINGS_ADD_LANGUAGE_TABLE_VIEW_CONTROLLER_H_
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "ios/chrome/browser/ui/settings/add_language_table_view_controller.h"
#include "base/mac/foundation_util.h"
#import "ios/chrome/browser/ui/list_model/list_item+Controller.h"
#import "ios/chrome/browser/ui/settings/cells/language_item.h"
#import "ios/chrome/browser/ui/settings/language_settings_data_source.h"
#include "ios/chrome/browser/ui/ui_feature_flags.h"
#import "ios/chrome/browser/ui/util/uikit_ui_util.h"
#include "ios/chrome/grit/ios_strings.h"
#include "ui/base/l10n/l10n_util_mac.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
namespace {
NSString* const kAddLanguageTableViewAccessibilityIdentifier =
@"add_language_table_view";
typedef NS_ENUM(NSInteger, SectionIdentifier) {
SectionIdentifierLanguages = kSectionIdentifierEnumZero,
};
typedef NS_ENUM(NSInteger, ItemType) {
ItemTypeLanguage = kItemTypeEnumZero, // This is a repeating type.
};
} // namespace
@interface AddLanguageTableViewController ()
// The data source passed to this instance.
@property(nonatomic, strong) id<LanguageSettingsDataSource> dataSource;
// The delegate passed to this instance.
@property(nonatomic, weak) id<AddLanguageTableViewControllerDelegate> delegate;
@end
@implementation AddLanguageTableViewController
- (instancetype)initWithDataSource:(id<LanguageSettingsDataSource>)dataSource
delegate:(id<AddLanguageTableViewControllerDelegate>)
delegate {
DCHECK(dataSource);
DCHECK(delegate);
UITableViewStyle style = base::FeatureList::IsEnabled(kSettingsRefresh)
? UITableViewStylePlain
: UITableViewStyleGrouped;
self = [super initWithTableViewStyle:style
appBarStyle:ChromeTableViewControllerStyleNoAppBar];
if (self) {
_dataSource = dataSource;
_delegate = delegate;
}
return self;
}
#pragma mark - UIViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.title =
l10n_util::GetNSString(IDS_IOS_LANGUAGE_SETTINGS_ADD_LANGUAGE_TITLE);
self.shouldHideDoneButton = YES;
self.tableView.accessibilityIdentifier =
kAddLanguageTableViewAccessibilityIdentifier;
[self loadModel];
}
#pragma mark - ChromeTableViewController
- (void)loadModel {
[super loadModel];
[self.tableViewModel addSectionWithIdentifier:SectionIdentifierLanguages];
[self populateLanguagesSection];
}
#pragma mark - UITableViewDelegate
- (void)tableView:(UITableView*)tableView
didSelectRowAtIndexPath:(NSIndexPath*)indexPath {
LanguageItem* languageItem = base::mac::ObjCCastStrict<LanguageItem>(
[self.tableViewModel itemAtIndexPath:indexPath]);
[self.delegate addLanguageTableViewController:self
didSelectLanguageCode:languageItem.languageCode];
}
#pragma mark - Public methods
- (void)supportedLanguagesListChanged {
// Update the model and the table view.
[self updateLanguagesSection];
}
#pragma mark - Helper methods
- (void)populateLanguagesSection {
TableViewModel* model = self.tableViewModel;
// Languages items.
[[self.dataSource supportedLanguagesItems]
enumerateObjectsUsingBlock:^(LanguageItem* item, NSUInteger index,
BOOL* stop) {
item.type = ItemTypeLanguage;
[model addItem:item toSectionWithIdentifier:SectionIdentifierLanguages];
}];
}
- (void)updateLanguagesSection {
// Update the model.
[self.tableViewModel
deleteAllItemsFromSectionWithIdentifier:SectionIdentifierLanguages];
[self populateLanguagesSection];
// Update the table view.
NSUInteger index = [self.tableViewModel
sectionForSectionIdentifier:SectionIdentifierLanguages];
[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:index]
withRowAnimation:UITableViewRowAnimationNone];
}
@end
...@@ -21,6 +21,10 @@ ...@@ -21,6 +21,10 @@
downward:(BOOL)downward downward:(BOOL)downward
withOffset:(NSUInteger)offset; withOffset:(NSUInteger)offset;
// Informs the receiver to add the language with the given code to the list of
// accept languages.
- (void)addLanguage:(const std::string&)languageCode;
// Informs the receiver to remove the language with the given code from the list // Informs the receiver to remove the language with the given code from the list
// of accept languages. // of accept languages.
- (void)removeLanguage:(const std::string&)languageCode; - (void)removeLanguage:(const std::string&)languageCode;
......
...@@ -18,6 +18,10 @@ ...@@ -18,6 +18,10 @@
// Returns the accept languages list ordered according to the user prefs. // Returns the accept languages list ordered according to the user prefs.
- (NSArray<LanguageItem*>*)acceptLanguagesItems; - (NSArray<LanguageItem*>*)acceptLanguagesItems;
// Returns the supported languages list excluding the accept languages. This
// list is sorted alphabetically based on display names in the current locale.
- (NSArray<LanguageItem*>*)supportedLanguagesItems;
// Returns whether or not Translate is enabled. // Returns whether or not Translate is enabled.
- (BOOL)translateEnabled; - (BOOL)translateEnabled;
......
...@@ -169,6 +169,32 @@ ...@@ -169,6 +169,32 @@
return acceptLanguages; return acceptLanguages;
} }
- (NSArray<LanguageItem*>*)supportedLanguagesItems {
// Get the accept languages.
std::vector<std::string> acceptLanguageCodes;
_translatePrefs->GetLanguageList(&acceptLanguageCodes);
// Get the supported languages.
std::vector<translate::TranslateLanguageInfo> languages;
translate::TranslatePrefs::GetLanguageInfoList(
GetApplicationContext()->GetApplicationLocale(),
_translatePrefs->IsTranslateAllowedByPolicy(), &languages);
NSMutableArray<LanguageItem*>* supportedLanguages =
[NSMutableArray arrayWithCapacity:languages.size()];
for (const auto& language : languages) {
// Ignore languages already in the accept languages list.
if (std::find(acceptLanguageCodes.begin(), acceptLanguageCodes.end(),
language.code) != acceptLanguageCodes.end()) {
continue;
}
LanguageItem* languageItem = [self languageItemFromLanguage:language];
languageItem.accessibilityTraits |= UIAccessibilityTraitButton;
[supportedLanguages addObject:languageItem];
}
return supportedLanguages;
}
- (BOOL)translateEnabled { - (BOOL)translateEnabled {
return self.translateEnabledPref.value; return self.translateEnabledPref.value;
} }
...@@ -198,6 +224,10 @@ ...@@ -198,6 +224,10 @@
languageCodes); languageCodes);
} }
- (void)addLanguage:(const std::string&)languageCode {
_translatePrefs->AddToLanguageList(languageCode, /*force_blocked=*/false);
}
- (void)removeLanguage:(const std::string&)languageCode { - (void)removeLanguage:(const std::string&)languageCode {
_translatePrefs->RemoveFromLanguageList(languageCode); _translatePrefs->RemoveFromLanguageList(languageCode);
} }
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "base/logging.h" #include "base/logging.h"
#include "base/mac/foundation_util.h" #include "base/mac/foundation_util.h"
#import "ios/chrome/browser/ui/list_model/list_item+Controller.h" #import "ios/chrome/browser/ui/list_model/list_item+Controller.h"
#import "ios/chrome/browser/ui/settings/add_language_table_view_controller.h"
#import "ios/chrome/browser/ui/settings/cells/language_item.h" #import "ios/chrome/browser/ui/settings/cells/language_item.h"
#import "ios/chrome/browser/ui/settings/cells/settings_cells_constants.h" #import "ios/chrome/browser/ui/settings/cells/settings_cells_constants.h"
#import "ios/chrome/browser/ui/settings/cells/settings_switch_cell.h" #import "ios/chrome/browser/ui/settings/cells/settings_switch_cell.h"
...@@ -49,6 +50,7 @@ typedef NS_ENUM(NSInteger, ItemType) { ...@@ -49,6 +50,7 @@ typedef NS_ENUM(NSInteger, ItemType) {
} // namespace } // namespace
@interface LanguageSettingsTableViewController () < @interface LanguageSettingsTableViewController () <
AddLanguageTableViewControllerDelegate,
LanguageDetailsTableViewControllerDelegate> LanguageDetailsTableViewControllerDelegate>
// The data source passed to this instance. // The data source passed to this instance.
...@@ -63,6 +65,10 @@ typedef NS_ENUM(NSInteger, ItemType) { ...@@ -63,6 +65,10 @@ typedef NS_ENUM(NSInteger, ItemType) {
// A reference to the Translate switch item for quick access. // A reference to the Translate switch item for quick access.
@property(nonatomic, weak) SettingsSwitchItem* translateSwitchItem; @property(nonatomic, weak) SettingsSwitchItem* translateSwitchItem;
// A reference to the presented AddLanguageTableViewController, if any.
@property(nonatomic, weak)
AddLanguageTableViewController* addLanguageTableViewController;
@end @end
@implementation LanguageSettingsTableViewController @implementation LanguageSettingsTableViewController
...@@ -175,16 +181,36 @@ typedef NS_ENUM(NSInteger, ItemType) { ...@@ -175,16 +181,36 @@ typedef NS_ENUM(NSInteger, ItemType) {
didSelectRowAtIndexPath:(NSIndexPath*)indexPath { didSelectRowAtIndexPath:(NSIndexPath*)indexPath {
[super tableView:tableView didSelectRowAtIndexPath:indexPath]; [super tableView:tableView didSelectRowAtIndexPath:indexPath];
TableViewItem* item = [self.tableViewModel itemAtIndexPath:indexPath]; ItemType itemType =
if (item.type == ItemTypeLanguage) { (ItemType)[self.tableViewModel itemTypeForIndexPath:indexPath];
LanguageItem* languageItem = base::mac::ObjCCastStrict<LanguageItem>(item); switch (itemType) {
languageItem.canOfferTranslate = case ItemTypeLanguage: {
[self canOfferTranslateForLanguage:languageItem]; LanguageItem* languageItem = base::mac::ObjCCastStrict<LanguageItem>(
LanguageDetailsTableViewController* viewController = [self.tableViewModel itemAtIndexPath:indexPath]);
[[LanguageDetailsTableViewController alloc] languageItem.canOfferTranslate =
initWithLanguageItem:languageItem [self canOfferTranslateForLanguage:languageItem];
LanguageDetailsTableViewController* viewController =
[[LanguageDetailsTableViewController alloc]
initWithLanguageItem:languageItem
delegate:self];
[self.navigationController pushViewController:viewController
animated:YES];
break;
}
case ItemTypeAddLanguage: {
AddLanguageTableViewController* viewController =
[[AddLanguageTableViewController alloc]
initWithDataSource:self.dataSource
delegate:self]; delegate:self];
[self.navigationController pushViewController:viewController animated:YES]; [self.navigationController pushViewController:viewController
animated:YES];
self.addLanguageTableViewController = viewController;
break;
}
case ItemTypeHeader:
case ItemTypeTranslateSwitch:
// Not handled.
break;
} }
} }
...@@ -278,7 +304,9 @@ typedef NS_ENUM(NSInteger, ItemType) { ...@@ -278,7 +304,9 @@ typedef NS_ENUM(NSInteger, ItemType) {
cellForRowAtIndexPath:(NSIndexPath*)indexPath { cellForRowAtIndexPath:(NSIndexPath*)indexPath {
UITableViewCell* cell = [super tableView:tableView UITableViewCell* cell = [super tableView:tableView
cellForRowAtIndexPath:indexPath]; cellForRowAtIndexPath:indexPath];
switch ([self.tableViewModel itemTypeForIndexPath:indexPath]) { ItemType itemType =
(ItemType)[self.tableViewModel itemTypeForIndexPath:indexPath];
switch (itemType) {
case ItemTypeTranslateSwitch: { case ItemTypeTranslateSwitch: {
SettingsSwitchCell* switchCell = SettingsSwitchCell* switchCell =
base::mac::ObjCCastStrict<SettingsSwitchCell>(cell); base::mac::ObjCCastStrict<SettingsSwitchCell>(cell);
...@@ -287,10 +315,30 @@ typedef NS_ENUM(NSInteger, ItemType) { ...@@ -287,10 +315,30 @@ typedef NS_ENUM(NSInteger, ItemType) {
forControlEvents:UIControlEventValueChanged]; forControlEvents:UIControlEventValueChanged];
break; break;
} }
case ItemTypeHeader:
case ItemTypeLanguage:
case ItemTypeAddLanguage:
// Not handled.
break;
} }
return cell; return cell;
} }
#pragma mark - AddLanguageTableViewControllerDelegate
- (void)addLanguageTableViewController:
(AddLanguageTableViewController*)tableViewController
didSelectLanguageCode:(const std::string&)languageCode {
// Inform the command handler.
[self.commandHandler addLanguage:languageCode];
// Update the model and the table view.
[self updateLanguagesSection];
[self.navigationController popViewControllerAnimated:YES];
self.addLanguageTableViewController = nil;
}
#pragma mark - LanguageDetailsTableViewControllerDelegate #pragma mark - LanguageDetailsTableViewControllerDelegate
- (void)languageDetailsTableViewController: - (void)languageDetailsTableViewController:
...@@ -327,6 +375,9 @@ typedef NS_ENUM(NSInteger, ItemType) { ...@@ -327,6 +375,9 @@ typedef NS_ENUM(NSInteger, ItemType) {
if (self.isEditing) if (self.isEditing)
return; return;
// Inform the presented AddLanguageTableViewController to update itself.
[self.addLanguageTableViewController supportedLanguagesListChanged];
// Update the model and the table view. // Update the model and the table view.
[self updateLanguagesSection]; [self updateLanguagesSection];
} }
......
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