#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 *_dict; } @end @implementation TGLocalization - (instancetype)initWithVersion:(int32_t)version code:(NSString *)code dict:(NSDictionary *)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 *)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 *)dict { return _dict; } @end