FIX - complete phone locale fallback

Resolve configured and regional locales through a centralized English fallback for Lua and NUI consumers. Complete the German and English app translation keys, localize remaining picker and attachment copy, and add contract tests that detect missing locale entries.
This commit is contained in:
Leon.Schmidt
2026-08-17 15:01:57 +02:00
parent 9adc5a755f
commit e58f1b6c18
15 changed files with 438 additions and 75 deletions
+44
View File
@@ -1,3 +1,47 @@
Config = Config or {}
Locales = Locales or {}
SkyPhoneLocales = SkyPhoneLocales or {}
local resolved_locales = {}
local function clone_locale(value)
if type(value) ~= "table" then
return value
end
local copied = {}
for key, nested in pairs(value) do
copied[key] = clone_locale(nested)
end
return copied
end
local function merge_locale(target, values)
for key, value in pairs(values) do
if type(value) == "table" and type(target[key]) == "table" then
merge_locale(target[key], value)
else
target[key] = clone_locale(value)
end
end
end
function SkyPhoneLocales.Resolve(requested_locale)
local normalized = type(requested_locale) == "string" and requested_locale:lower():gsub("_", "-") or "en"
local base = normalized:match("^([^-]+)") or "en"
local locale_name = Locales[normalized] and normalized or (Locales[base] and base or "en")
local selected = Locales[locale_name] or Locales.en or {}
local english = Locales.en or {}
if selected == english then
return english, "en"
end
if not resolved_locales[locale_name] then
resolved_locales[locale_name] = clone_locale(english)
merge_locale(resolved_locales[locale_name], selected)
end
return resolved_locales[locale_name], locale_name
end
+38
View File
@@ -187,6 +187,44 @@ local translations = {
["No data available"] = "Keine Daten verfügbar",
["Required"] = "Erforderlich",
["Optional"] = "Optional",
["Return to Call"] = "Zurück zum Anruf",
["This item is not available for EasyShare."] = "Dieses Element kann nicht über EasyShare geteilt werden.",
["The configured GIPHY API key is invalid."] = "Der konfigurierte GIPHY-API-Schlüssel ist ungültig.",
["GIPHY is busy. Try again in a moment."] = "GIPHY ist ausgelastet. Versuche es gleich erneut.",
["Search Calls"] = "Anrufe suchen",
["Contact Details"] = "Kontaktdetails",
["Unknown Caller"] = "Unbekannter Anrufer",
["Call History"] = "Anrufverlauf",
["No calls with this number yet."] = "Noch keine Anrufe mit dieser Nummer.",
["My Card"] = "Meine Karte",
["My Number"] = "Meine Nummer",
["Device"] = "Gerät",
["Contact Index"] = "Kontaktindex",
["The call could not be started."] = "Der Anruf konnte nicht gestartet werden.",
["Los Santos marketplace"] = "Marktplatz von Los Santos",
["Choose up to six photos from Photos or take new ones. Photos are optional and the first becomes the cover."] = "Wähle bis zu sechs Fotos aus Fotos oder nimm neue auf. Fotos sind optional; das erste wird zum Titelbild.",
["Use photos saved on this phone."] = "Verwende Fotos, die auf diesem Handy gespeichert sind.",
["Take photos"] = "Fotos aufnehmen",
["Take several new photos for this listing."] = "Nimm mehrere neue Fotos für dieses Angebot auf.",
["Selected photos"] = "Ausgewählte Fotos",
["Take as many photos as you need. Each shot is added to the listing automatically."] = "Nimm so viele Fotos auf, wie du benötigst. Jede Aufnahme wird automatisch zum Angebot hinzugefügt.",
["No photo available"] = "Kein Foto verfügbar",
["The seller did not add a photo to this listing."] = "Der Verkäufer hat diesem Angebot kein Foto hinzugefügt.",
["You can publish without a photo or add one from the gallery or camera."] = "Du kannst ohne Foto veröffentlichen oder eines aus der Galerie beziehungsweise Kamera hinzufügen.",
["Previous photo"] = "Vorheriges Foto",
["Next photo"] = "Nächstes Foto",
["Remove photo {number}"] = "Foto {number} entfernen",
["You can add up to six photos."] = "Du kannst bis zu sechs Fotos hinzufügen.",
["{current} / {maximum} characters"] = "{current} / {maximum} Zeichen",
["min. {minimum}"] = "mind. {minimum}",
["Emoji picker"] = "Emoji-Auswahl",
["Emoji categories"] = "Emoji-Kategorien",
["Skin tone {number}"] = "Hautton {number}",
["Celebrate!"] = "Feiern!",
["Love it"] = "Gefällt mir",
["Party time"] = "Partyzeit",
["Perfect"] = "Perfekt",
["WOW"] = "WOW",
}
local function translate_shared(value)
+21 -10
View File
@@ -608,7 +608,7 @@ Locales["en"] = {
voiceMessage = "Voice message", sending = "Sending", failed = "Not delivered", delivered = "Delivered", read = "Read", replying = "Replying to",
messageDeleted = "Message deleted", securityUpdate = "Security settings updated", timerChanged = "Disappearing messages: {timer}",
timerOff = "Off", timerAfterRead = "After reading", timerMinute = "1 minute", timerFiveMinutes = "5 minutes", timerHour = "1 hour", timerDay = "24 hours", timerWeek = "7 days",
copied = "Copied", reply = "Reply", copy = "Copy", deleteForMe = "Delete for me", deleteForBoth = "Delete for both", report = "Report",
copied = "Copied", reply = "Reply", copy = "Copy", deleteForMe = "Delete for me", deleteForBoth = "Delete for both", report = "Report", returnToCall = "Return to Call",
contactSecurity = "Contact & Security", chatSince = "Private chat since {date}", notifications = "Notifications", readReceipts = "Read receipts", disappearing = "Disappearing messages", contactAlias = "Contact alias", saveContact = "Save Contact", addContact = "Add Contact", contactSaved = "Contact saved", removeContact = "Remove Contact", block = "Block User", unblock = "Unblock User", clearChat = "Clear Chat", chatCleared = "Chat cleared",
myIdentity = "My Dark Identity", alias = "Alias", notificationPrivacy = "Notification privacy", notificationFull = "Full · alias and message", notificationPrivate = "Private · generic message", notificationHidden = "Invisible · badge only", shareActivity = "Share activity status", inviteCode = "Private invitation code", copyInvite = "Copy Invite", shareInvite = "Share Invite", privacyDisclaimer = "DarkChat stores messages on the server and does not claim end-to-end encryption.",
messageActions = "Message actions", chatSettings = "Chat Settings", contactActions = "Contact Actions", privacySettings = "Privacy Settings",
@@ -629,7 +629,7 @@ Locales["en"] = {
photo = "Photo", gif = "GIF", video = "Video", contact = "Contact", attachPhoto = "Attach Photo", takePhoto = "Take Photo",
attachGif = "Attach GIF", attachVideo = "Attach Video", photos = "Photos", gifs = "GIFs", videos = "Videos",
contacts = "Contacts", shareContact = "Share Contact", noContactsToShare = "Save a contact first to share it here.", contactSaved = "Contact Saved",
noPhotos = "Take a photo first to attach it here.", noVideos = "Record a video in Camera first.", searchGifs = "Search GIPHY", loadMore = "Load More",
noPhotos = "Take a photo first to attach it here.", noVideos = "Record a video in Camera first.", searchGifs = "Search GIPHY", loadMore = "Load More", retryGifs = "Try Again",
moreActions = "More Actions", inboxActions = "Conversation Actions", sortLabel = "Conversation Sort", sortNewest = "Newest First", sortOldest = "Oldest First", unreadConversation = "{name}, {count} unread messages",
attachmentPreview = "Selected attachments", attachmentLimit = "You can attach up to {count} photos or videos.", removeAttachment = "Remove attachment {number}",
contactDetails = "Contact Details", contactName = "Name", phoneNumber = "Phone Number", company = "Company", contactActions = "Contact Actions",
@@ -638,7 +638,9 @@ Locales["en"] = {
selectedCount = "{count} Selected", deleteSelected = "Delete",
contactSaveFailed = "The contact could not be saved.", contactDeleteFailed = "The contact could not be deleted.",
callFailed = "The call could not be started.",
emoji = "Emoji", voiceMessage = "Audio Message", recordVoice = "Record Audio",
emoji = "Emoji", emojiPicker = "Emoji picker", emojiCategories = "Emoji categories", skinTone = "Skin tone {number}",
gifLabels = { celebrate = "Celebrate!", hearts = "Love it", party = "Party time", thumbsUp = "Perfect", wow = "WOW" },
voiceMessage = "Audio Message", recordVoice = "Record Audio",
playAudio = "Play Audio", pauseAudio = "Pause Audio", seekAudio = "Seek Audio",
recording = "Recording", stopAndSend = "Stop and Send", cancelRecording = "Cancel Recording",
sending = "Sending...", delivered = "Delivered", notDelivered = "Not Delivered",
@@ -654,7 +656,8 @@ Locales["en"] = {
capture_provider_unavailable = "The screenshot resource is unavailable.", capture_failed = "The photo could not be captured.",
video_provider_unavailable = "Video capture requires the screencapture resource.", video_capture_failed = "The video could not be recorded.",
recording_in_progress = "A video is already being recorded.", recording_not_found = "No active video recording was found.",
gif_provider_unconfigured = "GIF search is not configured.", gif_provider_failed = "GIF search is temporarily unavailable.",
gif_provider_unconfigured = "GIF search is not configured.", gif_provider_unauthorized = "The configured GIPHY API key is invalid.",
gif_provider_rate_limited = "GIPHY is busy. Try again in a moment.", gif_provider_failed = "GIF search is temporarily unavailable.",
self_message = "You cannot message your own number.", recipient_not_found = "That number is unavailable.", blocked = "This contact has blocked calls and messages from your SIM.",
messaging_unavailable = "This company contact does not accept messages.",
no_sim = "This phone has no SIM card.", rate_limited = "Too many messages. Try again in a minute.",
@@ -971,7 +974,10 @@ Locales["en"] = {
phone = {
name = "Phone", recents = "Recents", contacts = "Contacts", keypad = "Keypad",
noSim = "No SIM", noSimBody = "Insert a SIM card in Settings to make calls.",
noRecents = "No Recent Calls", noContacts = "No Contacts", searchContacts = "Search Contacts", favorites = "Favorites",
noRecents = "No Recent Calls", allCalls = "All", missedCalls = "Missed", searchRecents = "Search Calls",
contactDetails = "Contact Details", unknownCaller = "Unknown Caller", callHistory = "Call History",
noCallHistory = "No calls with this number yet.", noContacts = "No Contacts", searchContacts = "Search Contacts", favorites = "Favorites",
myCard = "My Card", myNumber = "My Number", device = "Device", contactIndex = "Contact Index",
addContact = "New Contact", newContact = "New", editContact = "Edit Contact", contactName = "Name", firstName = "First Name", lastName = "Last Name", companyOrGroup = "Company or Group", phoneNumber = "Phone Number",
officialContact = "Official company contact",
choosePhoto = "Choose Contact Photo", chooseGallery = "Photos", takePhoto = "Camera", removePhoto = "Remove Photo",
@@ -982,7 +988,7 @@ Locales["en"] = {
block = "Block", blockCaller = "Block Caller", blockCallerTitle = "Block this caller?",
blockCallerBody = "{number} will no longer be able to call this SIM.",
faceTime = "FaceTime", hideKeypad = "Hide Keypad", more = "More", mute = "Mute", speaker = "Speaker", viewContact = "View Contact",
call = "Call", calling = "calling...", incoming = "Incoming Call", incomingDirection = "Incoming", outgoingDirection = "Outgoing", connected = "Connected",
call = "Call", callFailed = "The call could not be started.", calling = "calling...", incoming = "Incoming Call", incomingDirection = "Incoming", outgoingDirection = "Outgoing", connected = "Connected",
missed = "Missed", declined = "Declined", busy = "Busy", unavailable = "Unavailable",
noAnswer = "No Answer", cancelled = "Cancelled", disconnected = "Disconnected", sim_removed = "SIM Removed", completed = "Call Ended",
answer = "Answer", decline = "Decline", hangup = "End", addToContacts = "Add to Contacts",
@@ -1501,7 +1507,7 @@ Locales["en"] = {
},
},
citymarkt = {
name = "CityMarkt",
name = "CityMarkt", eyebrow = "Los Santos marketplace",
tabs = { discover = "Discover", search = "Search", sell = "Sell", inbox = "Inbox", profile = "Me" },
categories = {
vehicles = "Vehicles", property = "Property", electronics = "Electronics", clothing = "Clothing",
@@ -1544,8 +1550,13 @@ Locales["en"] = {
signInToMessage = "Sign in to your Sky Cloud account to send a message.",
edit = "Edit", makeActive = "Make active", markSold = "Mark sold", remove = "Remove",
createListing = "Create listing", editListing = "Edit listing", save = "Save", step = "Step {current} of {total}", next = "Next", previous = "Back", publish = "Publish",
addPhotos = "Add photos", addPhotosBody = "Choose up to six photos. The first becomes the cover.",
addPhotos = "Add photos", addPhotosBody = "Choose up to six photos from Photos or take new ones. Photos are optional and the first becomes the cover.",
chooseGalleryBody = "Use photos saved on this phone.", takePhotos = "Take photos", takePhotosBody = "Take several new photos for this listing.",
selectedPhotos = "Selected photos", gallery = "Photos", camera = "Camera", cameraHint = "Take as many photos as you need. Each shot is added to the listing automatically.",
noPhoto = "No photo available", noPhotoBody = "The seller did not add a photo to this listing.", noPhotoOptional = "You can publish without a photo or add one from the gallery or camera.",
previousPhoto = "Previous photo", nextPhoto = "Next photo", photo = "Photo", removePhoto = "Remove photo {number}", photoLimit = "You can add up to six photos.",
describeOffer = "Describe your offer", title = "Title", description = "Description", category = "Category", condition = "Condition",
characterCount = "{current} / {maximum} characters", minimumCharacters = "min. {minimum}",
priceAndPlace = "Price and location", priceType = "Price type", price = "Price", district = "District",
showPhone = "Show my current phone number", preview = "Preview", published = "Your listing is live.",
writeMessage = "Write a message", reserveForBuyer = "Reserve for this buyer", statusChanged = "Listing updated.",
@@ -1741,7 +1752,7 @@ Locales["en"] = {
easyShare = {
name = "EasyShare", incoming = "Incoming Share", recentChats = "Contacts and Chats",
destinations = "Share destinations", newMessage = "New Message", sentToChat = "Sent to chat.",
shareProfile = "Share Profile", chooseConversation = "Choose a conversation",
shareProfile = "Share Profile", share = "Share", chooseConversation = "Choose a conversation",
kinds = {
contact = "Contact", document = "Document", link = "Link", location = "Location", media = "Media",
note = "Note", photo = "Photo", playlist = "Playlist", post = "Post",
@@ -1761,7 +1772,7 @@ Locales["en"] = {
disabled = "EasyShare is disabled.", invalid_payload = "This item cannot be shared.",
invalid_target = "Choose a valid recipient.", target_unavailable = "That player is no longer available.",
transfer_not_found = "That transfer is no longer available.", too_far = "The recipient is too far away.",
not_owned = "This item no longer belongs to this phone.", payload_too_large = "This item is too large to share.",
not_owned = "This item no longer belongs to this phone.", unsupported_payload = "This item is not available for EasyShare.", payload_too_large = "This item is too large to share.",
location_unavailable = "Your location is unavailable.", rate_limited = "Too many share requests. Try again shortly.",
copy_failed = "Could not copy this item.", request_failed = "EasyShare is temporarily unavailable.",
},
+4 -6
View File
@@ -45,10 +45,8 @@ local vehicle_mods = {
modLivery = 48,
}
local function garage_locale()
local locale = Locales[Config.Bridge.Locale] or Locales["en"]
return locale.Nui.Apps.garage
end
local phone_locale = SkyPhoneLocales.Resolve(Config.Bridge.Locale)
local garage_locale = phone_locale.Nui.Apps.garage
local function normalized_plate(value)
return tostring(value or ""):match("^%s*(.-)%s*$")
@@ -233,7 +231,7 @@ local function fail_valet(error_code, server_cancel)
current_valet.can_cancel = false
current_valet.error = error_code
send_valet_state()
local locale = garage_locale()
local locale = garage_locale
Bridge.Framework.Notify(locale.name, locale.errors[error_code] or locale.errors.default, "error", 5000)
SetTimeout(8000, function()
if current_valet and current_valet.order_id == order_id then
@@ -429,7 +427,7 @@ local function run_valet_delivery(order)
current_valet.status = "delivered"
current_valet.can_cancel = false
send_valet_state()
local locale = garage_locale()
local locale = garage_locale
Bridge.Framework.Notify(locale.name, locale.valetDelivered, "success", 5000)
local completed_order_id = current_valet.order_id
SetTimeout(12000, function()
+22 -23
View File
@@ -297,9 +297,7 @@ local server_callbacks = {
"media:import:url",
}
local function get_locale()
return Locales[Config.Bridge.Locale] or Locales["en"]
end
local locale, locale_name = SkyPhoneLocales.Resolve(Config.Bridge.Locale)
local function update_nui_focus()
local focus = SkyPhoneFocus.Resolve({
@@ -375,8 +373,9 @@ local function send_open_message()
end
local payload = device_payload
payload.lang = Config.Bridge.Locale
payload.locales = get_locale().Nui
payload.lang = locale_name
payload.locales = locale.Nui
payload.fallbackLocales = Locales.en.Nui
SkyPhoneApps.SendCatalog()
SendNUIMessage({
type = "app:open",
@@ -445,8 +444,8 @@ if Config.Phone.DevelopmentCommand then
end
RegisterNetEvent("sky_phone:testdata:feedback", function(success, detail)
local locale = get_locale().TestData
local message = success and locale.Success or locale.Failed
local test_data_locale = locale.TestData
local message = success and test_data_locale.Success or test_data_locale.Failed
if success and type(detail) == "string" and detail ~= "" then
message = message:gsub("{email}", detail)
end
@@ -750,7 +749,7 @@ RegisterNetEvent("sky_phone:device:error", function(error_code)
tostring(error_code),
{ always = true }
)
local message = get_locale().DeviceErrors[error_code] or get_locale().DeviceErrors.default
local message = locale.DeviceErrors[error_code] or locale.DeviceErrors.default
Bridge.Framework.Notify("iFruit", message, "error", 5000)
end)
@@ -767,7 +766,7 @@ RegisterNetEvent("sky_phone:gallery:changed", function()
end)
RegisterNetEvent("sky_phone:mail:new", function(data)
local mail_locale = get_locale().Nui.Apps.mail
local mail_locale = locale.Nui.Apps.mail
data.title = mail_locale.name
data.text = mail_locale.newMessage:gsub("{sender}", tostring(data.sender))
SendNUIMessage({ type = "mail:new", data = data })
@@ -782,7 +781,7 @@ RegisterNetEvent("sky_phone:companies:changed", function(data)
end)
RegisterNetEvent("sky_phone:companies:notification", function(data)
local companies_locale = get_locale().Nui.Apps.companies
local companies_locale = locale.Nui.Apps.companies
data.title = companies_locale.name
data.text = companies_locale.notifications[data.kind]
or companies_locale.notifications.requestUpdated
@@ -798,7 +797,7 @@ RegisterNetEvent("sky_phone:fliptok:verification-changed", function(data)
end)
RegisterNetEvent("sky_phone:fliptok:new", function(data)
local fliptok_locale = get_locale().Nui.Apps.fliptok
local fliptok_locale = locale.Nui.Apps.fliptok
local notification_text = fliptok_locale.notifications[data.kind] or fliptok_locale.notifications.default
data.title = fliptok_locale.name
data.text = notification_text:gsub("{actor}", tostring(data.actor or ""))
@@ -814,7 +813,7 @@ RegisterNetEvent("sky_phone:picstagram:verification-changed", function(data)
end)
RegisterNetEvent("sky_phone:picstagram:new", function(data)
local picstagram_locale = get_locale().Nui.Apps.picstagram
local picstagram_locale = locale.Nui.Apps.picstagram
local notification_text = picstagram_locale.notifications[data.kind] or picstagram_locale.notifications.default
data.title = picstagram_locale.name
data.text = notification_text:gsub("{actor}", tostring(data.actor or ""))
@@ -822,7 +821,7 @@ RegisterNetEvent("sky_phone:picstagram:new", function(data)
end)
RegisterNetEvent("sky_phone:feather:new", function(data)
local feather_locale = get_locale().Nui.Apps.feather
local feather_locale = locale.Nui.Apps.feather
local notification_text = feather_locale.notifications[data.kind] or feather_locale.notifications.default
data.title = feather_locale.name
data.text = notification_text:gsub("{actor}", tostring(data.actor or ""))
@@ -830,7 +829,7 @@ RegisterNetEvent("sky_phone:feather:new", function(data)
end)
RegisterNetEvent("sky_phone:marketplace:new-message", function(data)
local marketplace_locale = get_locale().Nui.Apps.citymarkt
local marketplace_locale = locale.Nui.Apps.citymarkt
data.title = marketplace_locale.name
if data.kind == "offer" then
data.text = marketplace_locale.newOffer
@@ -851,21 +850,21 @@ RegisterNetEvent("sky_phone:marketplace:new-message", function(data)
end)
RegisterNetEvent("sky_phone:calendar:reminder", function(data)
local calendar_locale = get_locale().Nui.Apps.calendar
local calendar_locale = locale.Nui.Apps.calendar
data.title = calendar_locale.name
data.text = calendar_locale.reminder:gsub("{title}", tostring(data.eventTitle))
SendNUIMessage({ type = "calendar:reminder", data = data })
end)
RegisterNetEvent("sky_phone:flare:match", function(data)
local flare_locale = get_locale().Nui.Apps.flare
local flare_locale = locale.Nui.Apps.flare
data.title = flare_locale.name
data.text = flare_locale.newMatchNotification:gsub("{sender}", tostring(data.sender))
SendNUIMessage({ type = "flare:new-match", data = data })
end)
RegisterNetEvent("sky_phone:flare:message", function(data)
local flare_locale = get_locale().Nui.Apps.flare
local flare_locale = locale.Nui.Apps.flare
data.title = flare_locale.name
data.text = flare_locale.newMessageNotification:gsub("{sender}", tostring(data.sender))
SendNUIMessage({ type = "flare:new-message", data = data })
@@ -906,7 +905,7 @@ RegisterNetEvent("sky_phone:billing:changed", function()
end)
RegisterNetEvent("sky_phone:billing:new", function(data)
local billing_locale = get_locale().Nui.Apps.billing
local billing_locale = locale.Nui.Apps.billing
data.title = billing_locale.name
data.text = billing_locale.notifications.newInvoice
:gsub("{issuer}", tostring(data.issuer))
@@ -919,7 +918,7 @@ RegisterNetEvent("sky_phone:crewlink:changed", function(data)
end)
RegisterNetEvent("sky_phone:crewlink:notification", function(data)
local crewlink_locale = get_locale().Nui.Apps.crewlink
local crewlink_locale = locale.Nui.Apps.crewlink
local notification_text = crewlink_locale.notifications[data.kind]
or crewlink_locale.notifications.default
data.title = crewlink_locale.name
@@ -935,7 +934,7 @@ RegisterNetEvent("sky_phone:messages:changed", function(data)
end)
RegisterNetEvent("sky_phone:messages:new", function(data)
local messages_locale = get_locale().Nui.Apps.messages
local messages_locale = locale.Nui.Apps.messages
data.title = messages_locale.name
data.text = messages_locale.newMessage:gsub("{sender}", tostring(data.sender))
SendNUIMessage({ type = "messages:new", data = data })
@@ -946,7 +945,7 @@ RegisterNetEvent("sky_phone:darkchat:changed", function(data)
end)
RegisterNetEvent("sky_phone:darkchat:new", function(data)
local darkchat_locale = get_locale().Nui.Apps.darkchat
local darkchat_locale = locale.Nui.Apps.darkchat
data.title = darkchat_locale.name
if data.notificationMode == "private" then
data.sender = nil
@@ -1003,10 +1002,10 @@ end)
CreateThread(function()
if Config.Phone.DevelopmentCommand then
TriggerEvent("chat:addSuggestion", "/" .. Config.Command, get_locale().CommandDescription)
TriggerEvent("chat:addSuggestion", "/" .. Config.Command, locale.CommandDescription)
end
if Config.TestData.Enabled then
TriggerEvent("chat:addSuggestion", "/" .. Config.TestData.Command, get_locale().TestData.CommandDescription)
TriggerEvent("chat:addSuggestion", "/" .. Config.TestData.Command, locale.TestData.CommandDescription)
end
end)
+6 -8
View File
@@ -83,9 +83,7 @@ RegisterNetEvent("sky_phone:payphone:visual:stop", function(data)
restore_remote_visual(data.id)
end)
local function get_locale()
return Locales[Config.Bridge.Locale] or Locales["en"]
end
local locale = SkyPhoneLocales.Resolve(Config.Bridge.Locale)
local function load_model(model_hash)
if HasModelLoaded(model_hash) then
@@ -366,7 +364,7 @@ local function payphone_open_payload()
currency = Config.Payphones.Currency,
maxNumberLength = Config.Sim.NumberLength,
pricePerSecond = Config.Payphones.PricePerSecond,
locales = get_locale().Nui.Payphone,
locales = locale.Nui.Payphone,
}
end
@@ -400,16 +398,16 @@ local function current_call_elapsed_seconds()
end
local function call_help_message()
local locale = get_locale().Payphone
local payphone_locale = locale.Payphone
local message
if active_call_state == "connected" then
local elapsed_seconds = current_call_elapsed_seconds()
message = locale.ConnectedHelp
message = payphone_locale.ConnectedHelp
message = replace_placeholder(message, "duration", format_duration(elapsed_seconds))
message = replace_placeholder(message, "currency", Config.Payphones.Currency)
message = replace_placeholder(message, "cost", elapsed_seconds * (tonumber(Config.Payphones.PricePerSecond) or 0))
else
message = locale.RingingHelp
message = payphone_locale.RingingHelp
end
return replace_placeholder(message, "number", active_call_number or "")
end
@@ -577,7 +575,7 @@ end)
CreateThread(function()
while true do
if nearest_payphone and nearest_payphone.distance <= Config.Payphones.InteractionDistance and not IsNuiFocused() then
Bridge.Framework.ShowHelpNotification(get_locale().Payphone.Interact, "E")
Bridge.Framework.ShowHelpNotification(locale.Payphone.Interact, "E")
if IsControlJustReleased(0, 38) then
open_payphone(nearest_payphone)
end
+1 -1
View File
@@ -295,7 +295,7 @@ RegisterNetEvent("sky_phone:radio:notification", function(data)
if not radio_settings.notifications or current_primary <= 0 then
return
end
local locale = (Locales[Config.Bridge.Locale] or Locales.en).Nui.Apps.radio
local locale = SkyPhoneLocales.Resolve(Config.Bridge.Locale).Nui.Apps.radio
local template = data.joined and locale.memberJoined or locale.memberLeft
SendNUIMessage({
type = "notification:show",
+1 -1
View File
@@ -263,7 +263,7 @@ local function canonical_crewlink_invite(device, invite_code)
if not group then
return nil
end
local locale = (Locales[Config.Bridge.Locale] or Locales["en"]).Phone.Apps.crewlink
local locale = SkyPhoneLocales.Resolve(Config.Bridge.Locale).Nui.Apps.crewlink
local title = locale.shareInviteTitle:gsub("{group}", function() return group.name end)
local copy_text = locale.shareInviteBody
:gsub("{code}", function() return group.invite_code end)
+1 -1
View File
@@ -914,7 +914,7 @@ Bridge.Callbacks.Register("sky_phone:fliptok:delete", function(source, data)
end)
RegisterCommand(Config.FlipTok.VerifyCommand, function(source, arguments)
local command_locale = (Locales[Config.Bridge.Locale] or Locales["en"]).FlipTokCommand
local command_locale = SkyPhoneLocales.Resolve(Config.Bridge.Locale).FlipTokCommand
local function command_message(template, values)
return template:gsub("{(%w+)}", function(key) return values[key] or "" end)
end
+1 -1
View File
@@ -1435,7 +1435,7 @@ Bridge.Callbacks.Register("sky_phone:picstagram:admin-resolve-report", function(
end)
RegisterCommand(Config.Picstagram.VerifyCommand, function(source, args)
local command_locale = (Locales[Config.Bridge.Locale] or Locales["en"]).PicstagramCommand
local command_locale = SkyPhoneLocales.Resolve(Config.Bridge.Locale).PicstagramCommand
local function command_message(template, values)
return template:gsub("{(%w+)}", function(key)
return values[key] or ""