import Foundation #if os(macOS) import PostboxMac import SwiftSignalKitMac #else import Postbox import SwiftSignalKit #endif public func currentlySuggestedLocalization(network: Network, extractKeys: [String]) -> Signal { return network.request(Api.functions.help.getConfig()) |> retryRequest |> mapToSignal { result -> Signal in switch result { case let .config(flags, date, expires, testMode, thisDc, dcOptions, chatSizeMax, megagroupSizeMax, forwardedCountMax, onlineUpdatePeriodMs, offlineBlurTimeoutMs, offlineIdleTimeoutMs, onlineCloudTimeoutMs, notifyCloudDelayMs, notifyDefaultDelayMs, chatBigSize, pushChatPeriodMs, pushChatLimit, savedGifsLimit, editTimeLimit, ratingEDecay, stickersRecentLimit, tmpSessions, pinnedDialogsCountMax, callReceiveTimeoutMs, callRingTimeoutMs, callConnectTimeoutMs, callPacketTimeoutMs, meUrlPrefix, suggestedLangCode, _, disabledFeatures): if let suggestedLangCode = suggestedLangCode { return suggestedLocalizationInfo(network: network, languageCode: suggestedLangCode, extractKeys: extractKeys) |> map { Optional($0) } } else { return .single(nil) } } } } public func suggestedLocalizationInfo(network: Network, languageCode: String, extractKeys: [String]) -> Signal { return combineLatest(network.request(Api.functions.langpack.getLanguages()), network.request(Api.functions.langpack.getStrings(langCode: languageCode, keys: extractKeys))) |> retryRequest |> map { languages, strings -> SuggestedLocalizationInfo in var entries: [LocalizationEntry] = [] for string in strings { switch string { case let .langPackString(key, value): entries.append(.string(key: key, value: value)) case let .langPackStringPluralized(_, key, zeroValue, oneValue, twoValue, fewValue, manyValue, otherValue): entries.append(.pluralizedString(key: key, zero: zeroValue, one: oneValue, two: twoValue, few: fewValue, many: manyValue, other: otherValue)) case let .langPackStringDeleted(key): entries.append(.string(key: key, value: "")) } } var infos: [LocalizationInfo] = [] for language in languages { switch language { case let .langPackLanguage(name, nativeName, langCode): infos.append(LocalizationInfo(languageCode: langCode, title: name, localizedTitle: nativeName)) } } return SuggestedLocalizationInfo(languageCode: languageCode, extractedEntries: entries, availableLocalizations: infos) } } public func availableLocalizations(network: Network) -> Signal<[LocalizationInfo], NoError> { return network.request(Api.functions.langpack.getLanguages()) |> retryRequest |> map { languages -> [LocalizationInfo] in var infos: [LocalizationInfo] = [] for language in languages { switch language { case let .langPackLanguage(name, nativeName, langCode): infos.append(LocalizationInfo(languageCode: langCode, title: name, localizedTitle: nativeName)) } } return infos } } public func downloadLocalization(network: Network, languageCode: String) -> Signal { return network.request(Api.functions.langpack.getLangPack(langCode: languageCode)) |> retryRequest |> map { result -> Localization in let version: Int32 var entries: [LocalizationEntry] = [] switch result { case let .langPackDifference(_, _, versionValue, strings): version = versionValue for string in strings { switch string { case let .langPackString(key, value): entries.append(.string(key: key, value: value)) case let .langPackStringPluralized(_, key, zeroValue, oneValue, twoValue, fewValue, manyValue, otherValue): entries.append(.pluralizedString(key: key, zero: zeroValue, one: oneValue, two: twoValue, few: fewValue, many: manyValue, other: otherValue)) case let .langPackStringDeleted(key): entries.append(.string(key: key, value: "")) } } } return Localization(version: version, entries: entries) } } public func downoadAndApplyLocalization(postbox: Postbox, network: Network, languageCode: String) -> Signal { return downloadLocalization(network: network, languageCode: languageCode) |> mapToSignal { language -> Signal in return postbox.modify { modifier -> Void in modifier.updatePreferencesEntry(key: PreferencesKeys.localizationSettings, { _ in return LocalizationSettings(languageCode: languageCode, localization: language) }) network.context.updateApiEnvironment { current in return current?.withUpdatedLangPackCode(languageCode) } } } }