301 lines
9.2 KiB
Objective-C
301 lines
9.2 KiB
Objective-C
/*
|
|
Copyright 2024 New Vector Ltd.
|
|
Copyright 2017 Vector Creations Ltd
|
|
|
|
SPDX-License-Identifier: AGPL-3.0-only
|
|
Please see LICENSE in the repository root for full details.
|
|
*/
|
|
|
|
#import "MXKLanguagePickerViewController.h"
|
|
|
|
@import libPhoneNumber_iOS;
|
|
|
|
#import "NSBundle+MatrixKit.h"
|
|
#import "MXKSwiftHeader.h"
|
|
|
|
NSString* const kMXKLanguagePickerViewControllerCellId = @"kMXKLanguagePickerViewControllerCellId";
|
|
|
|
NSString* const kMXKLanguagePickerCellDataKeyText = @"text";
|
|
NSString* const kMXKLanguagePickerCellDataKeyDetailText = @"detailText";
|
|
NSString* const kMXKLanguagePickerCellDataKeyLanguage = @"language";
|
|
|
|
@interface MXKLanguagePickerViewController ()
|
|
{
|
|
NSMutableArray<NSDictionary*> *cellDataArray;
|
|
NSMutableArray<NSDictionary*> *filteredCellDataArray;
|
|
|
|
NSString *previousSearchPattern;
|
|
}
|
|
|
|
@end
|
|
|
|
@implementation MXKLanguagePickerViewController
|
|
|
|
#pragma mark - Class methods
|
|
|
|
+ (UINib *)nib
|
|
{
|
|
return [UINib nibWithNibName:NSStringFromClass([MXKLanguagePickerViewController class])
|
|
bundle:[NSBundle bundleForClass:[MXKLanguagePickerViewController class]]];
|
|
}
|
|
|
|
+ (instancetype)languagePickerViewController
|
|
{
|
|
return [[[self class] alloc] initWithNibName:NSStringFromClass([MXKLanguagePickerViewController class])
|
|
bundle:[NSBundle bundleForClass:[MXKLanguagePickerViewController class]]];
|
|
}
|
|
|
|
+ (NSString *)languageDescription:(NSString *)language
|
|
{
|
|
NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:language];
|
|
|
|
return [locale displayNameForKey:NSLocaleIdentifier value:language];
|
|
}
|
|
|
|
+ (NSString *)languageLocalisedDescription:(NSString *)language
|
|
{
|
|
NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:[NSBundle mainBundle].preferredLocalizations.firstObject];
|
|
|
|
return [locale displayNameForKey:NSLocaleIdentifier value:language];
|
|
}
|
|
|
|
+ (NSString *)defaultLanguage
|
|
{
|
|
return [NSBundle mainBundle].preferredLocalizations.firstObject;
|
|
}
|
|
|
|
- (void)finalizeInit
|
|
{
|
|
[super finalizeInit];
|
|
|
|
cellDataArray = [NSMutableArray array];
|
|
filteredCellDataArray = nil;
|
|
|
|
previousSearchPattern = nil;
|
|
|
|
// Populate cellDataArray
|
|
// Start by the default language chosen by the OS
|
|
NSString *defaultLanguage = [MXKLanguagePickerViewController defaultLanguage];
|
|
NSString *languageDescription = [VectorL10n languagePickerDefaultLanguage:[MXKLanguagePickerViewController languageDescription:defaultLanguage]];
|
|
|
|
[cellDataArray addObject:@{
|
|
kMXKLanguagePickerCellDataKeyText:languageDescription
|
|
}];
|
|
|
|
// Then, add languages available in the app bundle
|
|
NSArray<NSString *> *localizations = [[NSBundle mainBundle] localizations];
|
|
for (NSString *language in localizations)
|
|
{
|
|
// Do not duplicate the default lang
|
|
if (![language isEqualToString:defaultLanguage])
|
|
{
|
|
languageDescription = [MXKLanguagePickerViewController languageDescription:language];
|
|
NSString *localisedLanguageDescription = [MXKLanguagePickerViewController languageLocalisedDescription:language];
|
|
|
|
// Capitalise the description in the language locale
|
|
NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:language];
|
|
languageDescription = [languageDescription capitalizedStringWithLocale:locale];
|
|
localisedLanguageDescription = [localisedLanguageDescription capitalizedStringWithLocale:locale];
|
|
|
|
if (languageDescription)
|
|
{
|
|
[cellDataArray addObject:@{
|
|
kMXKLanguagePickerCellDataKeyText: languageDescription,
|
|
kMXKLanguagePickerCellDataKeyDetailText: localisedLanguageDescription,
|
|
kMXKLanguagePickerCellDataKeyLanguage: language
|
|
}];
|
|
}
|
|
}
|
|
}
|
|
|
|
// Default to "" in order to differentiate it from nil
|
|
_selectedLanguage = @"";
|
|
}
|
|
|
|
- (void)destroy
|
|
{
|
|
[super destroy];
|
|
|
|
cellDataArray = nil;
|
|
filteredCellDataArray = nil;
|
|
|
|
previousSearchPattern = nil;
|
|
}
|
|
|
|
- (void)viewDidLoad
|
|
{
|
|
[super viewDidLoad];
|
|
|
|
// Check whether the view controller has been pushed via storyboard
|
|
if (!self.tableView)
|
|
{
|
|
// Instantiate view controller objects
|
|
[[[self class] nib] instantiateWithOwner:self options:nil];
|
|
}
|
|
|
|
[self setupSearchController];
|
|
|
|
self.navigationItem.title = [VectorL10n languagePickerTitle];
|
|
|
|
}
|
|
|
|
- (void)viewDidAppear:(BOOL)animated
|
|
{
|
|
[super viewDidAppear:animated];
|
|
|
|
self.navigationItem.hidesSearchBarWhenScrolling = YES;
|
|
}
|
|
|
|
#pragma mark - Private
|
|
|
|
- (void)setupSearchController
|
|
{
|
|
UISearchController *searchController = [[UISearchController alloc]
|
|
initWithSearchResultsController:nil];
|
|
searchController.obscuresBackgroundDuringPresentation = NO;
|
|
searchController.hidesNavigationBarDuringPresentation = NO;
|
|
searchController.searchResultsUpdater = self;
|
|
|
|
// Search bar is hidden for the moment, uncomment following line to enable it.
|
|
// TODO: Enable it once we have enough translations to fill pages and pages
|
|
// self.navigationItem.searchController = searchController;
|
|
// Make the search bar visible on first view appearance
|
|
self.navigationItem.hidesSearchBarWhenScrolling = NO;
|
|
|
|
self.definesPresentationContext = YES;
|
|
|
|
self.searchController = searchController;
|
|
}
|
|
|
|
#pragma mark - UITableView dataSource
|
|
|
|
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
|
|
{
|
|
if (filteredCellDataArray)
|
|
{
|
|
return filteredCellDataArray.count;
|
|
}
|
|
return cellDataArray.count;
|
|
}
|
|
|
|
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
|
|
{
|
|
UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:kMXKLanguagePickerViewControllerCellId];
|
|
if (!cell)
|
|
{
|
|
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:kMXKLanguagePickerViewControllerCellId];
|
|
}
|
|
|
|
NSInteger index = indexPath.row;
|
|
NSDictionary *itemCellData;
|
|
|
|
if (filteredCellDataArray)
|
|
{
|
|
if (index < filteredCellDataArray.count)
|
|
{
|
|
itemCellData = filteredCellDataArray[index];
|
|
}
|
|
}
|
|
else if (index < cellDataArray.count)
|
|
{
|
|
itemCellData = cellDataArray[index];
|
|
}
|
|
|
|
if (itemCellData)
|
|
{
|
|
cell.textLabel.text = itemCellData[kMXKLanguagePickerCellDataKeyText];
|
|
cell.detailTextLabel.text = itemCellData[kMXKLanguagePickerCellDataKeyDetailText];
|
|
|
|
// Mark the cell with the selected language
|
|
if (_selectedLanguage == itemCellData[kMXKLanguagePickerCellDataKeyLanguage] || [_selectedLanguage isEqualToString:itemCellData[kMXKLanguagePickerCellDataKeyLanguage]])
|
|
{
|
|
cell.accessoryType = UITableViewCellAccessoryCheckmark;
|
|
}
|
|
else
|
|
{
|
|
cell.accessoryType = UITableViewCellAccessoryNone;
|
|
}
|
|
}
|
|
|
|
return cell;
|
|
}
|
|
|
|
#pragma mark - UITableView delegate
|
|
|
|
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
|
|
{
|
|
[tableView deselectRowAtIndexPath:indexPath animated:YES];
|
|
|
|
if (self.delegate)
|
|
{
|
|
NSInteger index = indexPath.row;
|
|
NSString *language;
|
|
|
|
if (filteredCellDataArray)
|
|
{
|
|
if (index < filteredCellDataArray.count)
|
|
{
|
|
language = filteredCellDataArray[index][kMXKLanguagePickerCellDataKeyLanguage];
|
|
}
|
|
}
|
|
else if (index < cellDataArray.count)
|
|
{
|
|
language = cellDataArray[index][kMXKLanguagePickerCellDataKeyLanguage];
|
|
}
|
|
|
|
[self.delegate languagePickerViewController:self didSelectLangugage:language];
|
|
}
|
|
}
|
|
|
|
#pragma mark - UISearchResultsUpdating
|
|
|
|
- (void)updateSearchResultsForSearchController:(UISearchController *)searchController
|
|
{
|
|
NSString *searchText = searchController.searchBar.text;
|
|
|
|
if (searchText.length)
|
|
{
|
|
searchText = [searchText lowercaseString];
|
|
|
|
if (previousSearchPattern && [searchText hasPrefix:previousSearchPattern])
|
|
{
|
|
for (NSUInteger index = 0; index < filteredCellDataArray.count;)
|
|
{
|
|
NSString *text = [filteredCellDataArray[index][kMXKLanguagePickerCellDataKeyText] lowercaseString];
|
|
|
|
if ([text hasPrefix:searchText] == NO)
|
|
{
|
|
[filteredCellDataArray removeObjectAtIndex:index];
|
|
}
|
|
else
|
|
{
|
|
index++;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
filteredCellDataArray = [NSMutableArray array];
|
|
|
|
for (NSUInteger index = 0; index < cellDataArray.count; index++)
|
|
{
|
|
NSString *text = [cellDataArray[index][kMXKLanguagePickerCellDataKeyText] lowercaseString];
|
|
|
|
if ([text hasPrefix:searchText])
|
|
{
|
|
[filteredCellDataArray addObject:cellDataArray[index]];
|
|
}
|
|
}
|
|
}
|
|
|
|
previousSearchPattern = searchText;
|
|
}
|
|
else
|
|
{
|
|
previousSearchPattern = nil;
|
|
filteredCellDataArray = nil;
|
|
}
|
|
}
|
|
|
|
@end
|