2020-02-22 15:38:54 +04:00

180 lines
5.7 KiB
Objective-C

#import "TGLocalization.h"
#import "TGPluralization.h"
static NSDictionary *fallbackDict(NSString *code) {
if (code == nil) {
code = @"en";
}
static NSMutableDictionary *dicts = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
dicts = [[NSMutableDictionary alloc] init];
});
NSDictionary *dict = dicts[code];
if (dict == nil) {
NSBundle *bundle = [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:code ofType:@"lproj"]];
NSString *path = [bundle pathForResource:@"Localizable" ofType:@"strings"];
dict = [NSDictionary dictionaryWithContentsOfFile:path];
if (dict == nil) {
dict = @{};
}
dicts[code] = dict;
}
return dict;
}
static NSString *fallbackString(NSString *key, NSString *code) {
NSString *value = fallbackDict(code)[key];
if (value == nil) {
value = fallbackDict(@"en")[key];
}
if (value == nil) {
return key;
} else {
return value;
}
}
@interface TGLocalization () {
NSDictionary<NSString *, NSString *> *_dict;
}
@end
@implementation TGLocalization
- (instancetype)initWithVersion:(int32_t)version code:(NSString *)code dict:(NSDictionary<NSString *, NSString *> *)dict isActive:(bool)isActive {
self = [super init];
if (self != nil) {
_version = version;
_code = code;
NSString *appTitle = [[[NSBundle mainBundle] localizedInfoDictionary] objectForKey:@"CFBundleDisplayName"];
if (appTitle == nil) {
appTitle = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleDisplayName"];
}
if (appTitle == nil) {
appTitle = @"Telegram";
}
NSString *originalTitle = @"Telegram";
if (![appTitle isEqualToString:originalTitle]) {
NSMutableDictionary *updatedDict = [[NSMutableDictionary alloc] initWithDictionary:dict];
for (NSString *key in dict.keyEnumerator) {
NSString *value = dict[key];
if ([value rangeOfString:originalTitle].location != NSNotFound) {
value = [value stringByReplacingOccurrencesOfString:originalTitle withString:appTitle];
updatedDict[key] = value;
}
}
_dict = updatedDict;
} else {
_dict = dict;
}
_isActive = isActive;
NSString *rawCode = code;
NSRange range = [rawCode rangeOfString:@"_"];
if (range.location != NSNotFound) {
rawCode = [rawCode substringToIndex:range.location];
}
range = [rawCode rangeOfString:@"-"];
if (range.location != NSNotFound) {
rawCode = [rawCode substringToIndex:range.location];
}
rawCode = [rawCode lowercaseString];
unsigned int lc = 0;
const char *s = rawCode.UTF8String;
for (; *s; s++) { lc = (lc << 8) + *s; }
_languageCodeHash = lc;
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
return [self initWithVersion:[aDecoder decodeInt32ForKey:@"version"] code:[aDecoder decodeObjectForKey:@"code"] dict:[aDecoder decodeObjectForKey:@"dict"] isActive:[aDecoder decodeBoolForKey:@"isActive"]];
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeInt32:_version forKey:@"version"];
[aCoder encodeObject:_code forKey:@"code"];
[aCoder encodeObject:_dict forKey:@"dict"];
[aCoder encodeBool:_isActive forKey:@"isActive"];
}
- (TGLocalization *)mergedWith:(NSDictionary<NSString *, NSString *> *)other version:(int32_t)version {
NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithDictionary:_dict];
[dict addEntriesFromDictionary:other];
return [[TGLocalization alloc] initWithVersion:version code:_code dict:dict isActive:_isActive];
}
- (TGLocalization *)withUpdatedIsActive:(bool)isActive {
return [[TGLocalization alloc] initWithVersion:_version code:_code dict:_dict isActive:isActive];
}
- (NSLocale *)locale
{
NSString *suffix = @"";
NSString *identifier = [[NSLocale currentLocale] localeIdentifier];
NSRange range = [identifier rangeOfString:@"_"];
if (range.location != NSNotFound)
suffix = [identifier substringFromIndex:range.location];
identifier = [_code stringByAppendingString:suffix];
return [NSLocale localeWithLocaleIdentifier:identifier];
}
- (NSString *)get:(NSString *)key {
if (key == nil) {
return nil;
}
NSString *value = _dict[key];
if (value != nil && value.length != 0) {
return value;
} else {
return fallbackString(key, _code);
}
}
- (NSString *)getPluralized:(NSString *)key count:(int32_t)count {
NSString *suffix = nil;
switch (TGPluralForm(_languageCodeHash, count)) {
case TGPluralFormZero:
suffix = @"_0";
break;
case TGPluralFormOne:
suffix = @"_1";
break;
case TGPluralFormTwo:
suffix = @"_2";
break;
case TGPluralFormFew:
suffix = @"_3_10";
break;
case TGPluralFormMany:
suffix = @"_many";
break;
case TGPluralFormOther:
suffix = @"_any";
break;
}
NSString *finalKey = [key stringByAppendingString:suffix];
if (_dict[finalKey] == nil) {
finalKey = [key stringByAppendingString:@"_any"];
}
return [[NSString alloc] initWithFormat:[self get:finalKey], [NSString stringWithFormat:@"%d", count]];
}
- (bool)contains:(NSString *)key {
return _dict[key] != nil;
}
- (NSDictionary<NSString *, NSString *> *)dict {
return _dict;
}
@end