SyntaxGameServer/RCCService2018/content/LuaPackages/PurchasePrompt/Localization/LocalizationService.lua

161 lines
4.4 KiB
Lua

local PurchaseError = require(script.Parent.Parent.PurchaseError)
local Symbol = require(script.Parent.Parent.Symbol)
local KeyMappings = require(script.Parent.KeyMappings)
local addGroupDelimiters = require(script.Parent.Parent.addGroupDelimiters)
local DEBUG_LOCALIZATION = false
--[[
Locale-specific group delimiters for displaying numbers. Used to
format values like 100000 to strings like "100,000". This table
does not provide any info regarding decimal separators
]]
local groupDelimiterByLocale = {
["en-us"] = ",",
["en-gb"] = ",",
["es-mx"] = ",",
["es-es"] = ".",
["fr-fr"] = " ",
["de-de"] = " ",
["pt-br"] = ".",
["zh-cn"] = ",",
["zh-tw"] = ",",
["ko-kr"] = ",",
["ja-jp"] = ",",
["it-it"] = " ",
["ru-ru"] = ".",
["id-id"] = ".",
["vi-vn"] = ".",
["th-th"] = ",",
["tr-tr"] = ".",
}
--[[
This is a marker used to indicate that a provided param needs a locale-aware
formatting pass. We need this for nested localization and number formatting
]]
local FormattedParamTag = Symbol.named("FormattedParam")
local function isFormattedParam(paramValue)
return typeof(paramValue) == "table" and paramValue[FormattedParamTag] == true
end
local function createFormattedParam(formatFunc)
return {
[FormattedParamTag] = true,
format = formatFunc,
}
end
--[[
Looks up the given key in the localization context's translation table
]]
local function getLocalizedString(localizationContext, key)
local translations = localizationContext.translations
if DEBUG_LOCALIZATION and translations[key] == nil then
warn(("Missing translation for %s in locale %s"):format(key, localizationContext.locale))
end
return translations[key]
end
local LocalizationService = {}
function LocalizationService.formatNumber(localizationContext, number)
local delimiter = groupDelimiterByLocale[localizationContext.locale]
return addGroupDelimiters(number, delimiter)
end
--[[
Generates a placeholder for a number param that needs locale-aware formatting
]]
function LocalizationService.numberParam(number)
return createFormattedParam(function(localizationContext)
return LocalizationService.formatNumber(localizationContext, number)
end)
end
--[[
Generates a placeholder for a param substitution that needs
its own localization pass
]]
function LocalizationService.nestedKeyParam(key)
return createFormattedParam(function(localizationContext)
return getLocalizedString(localizationContext, key)
end)
end
--[[
Utility function returns the localization key for a given asset id
]]
function LocalizationService.getAssetTypeKey(assetTypeId)
assert(typeof(assetTypeId) == "number" or typeof(assetTypeId) == "string",
"provided asset type must be a number or string")
local assetType = KeyMappings.AssetTypeById[tostring(assetTypeId)]
if DEBUG_LOCALIZATION and assetType == nil then
warn("Invalid Asset Type id " .. tostring(assetTypeId))
end
return assetType
end
--[[
Utility function returns the localization key for a given
builders club level
]]
function LocalizationService.getBuildersClubLevelKey(bcLevelId)
assert(typeof(bcLevelId) == "number" or typeof(bcLevelId) == "string",
"provided builders club level must be a number")
local bcLevel = KeyMappings.BuildersClubLevelById[tostring(bcLevelId)]
if DEBUG_LOCALIZATION and bcLevel == nil then
warn("Invalid Builders Club Level id " .. tostring(bcLevelId))
end
return bcLevel
end
--[[
Utility function to retrieve relevant localization key for various
types of errors that may be encountered
]]
function LocalizationService.getErrorKey(errorType)
assert(PurchaseError.isMember(errorType),
"provided value " .. tostring(errorType) .. " is not a member of PurchaseError enum")
return KeyMappings.PurchaseErrorKey[errorType]
end
--[[
The primary function of this object
Retrieves a localized string from the provided context with the
given key and performs parameter substitutions
]]
function LocalizationService.getString(localizationContext, key, params)
assert(localizationContext ~= nil, "Must provide valid localization context")
local localizedString = getLocalizedString(localizationContext, key)
if params ~= nil then
for param, value in pairs(params) do
local replacement = value
local paramPlaceholder = ("{%s}"):format(param)
if isFormattedParam(value) then
replacement = value.format(localizationContext)
end
localizedString = string.gsub(localizedString, paramPlaceholder, replacement)
end
end
return localizedString
end
return LocalizationService