Files
Leon.Schmidt 30559048fd FIX - complete LB custom app compatibility (#11)
* FIX - preserve LB custom app lifecycle

* FIX - reset LB export aliases before startup

* FIX - report competing custom app providers

* FIX - identify LB app frames as live NUI

* FIX - complete LB custom app compatibility

* FIX - provide LB PicChat runtime exports

* FIX - route LB PicChat through Sky Phone

* FIX - return cached LB equipped phone number

* FIX - harden PicChat compatibility migration

* ENH - complete modular phone provider and Creator APIs

* DOC - document the Sky Phone Creator API

---------

Co-authored-by: DerEchteAlec <bycraky@gmail.com>
Co-authored-by: DerEchteAlec <alec.schitzkat@luwan.io>
2026-08-20 18:19:16 +02:00

99 lines
4.0 KiB
Lua

local event_handlers = {}
local nui_callbacks = {}
local nui_messages = {}
local phone_open = false
function AddEventHandler(event_name, handler)
event_handlers[event_name] = handler
end
function GetCurrentResourceName()
return "sky_phone"
end
function RegisterNUICallback(callback_name, handler)
nui_callbacks[callback_name] = handler
end
function SendNUIMessage(message)
nui_messages[#nui_messages + 1] = message
end
SkyPhoneApps = {
ValidateAppId = function(app_id)
return type(app_id) == "string" and app_id:match("^[a-z0-9][a-z0-9._-]+$") ~= nil
end,
}
SkyPhoneClient = {
GetState = function()
return { open = phone_open }
end,
}
dofile("sky_phone/source/client/navigation.lua")
local callback_result
nui_callbacks["navigation:state"]({
currentApp = "messages",
installedApps = { "messages", "camera", "custom-app" },
}, function(result)
callback_result = result
end)
assert(callback_result.success, "valid navigation state must be accepted")
assert(SkyPhoneNavigation.IsDataLoaded(), "accepted renderer state must mark navigation data loaded")
local closed_success, closed_error = SkyPhoneNavigation.Open("messages")
assert(not closed_success and closed_error == "phone_closed", "closed phones must reject navigation")
phone_open = true
assert(SkyPhoneNavigation.IsInstalled("messages"), "installed app lookup must use renderer state")
assert(not SkyPhoneNavigation.IsInstalled("mail"), "missing apps must not report installed")
assert(SkyPhoneNavigation.GetCurrent() == "messages", "current app lookup must preserve the renderer route")
assert(SkyPhoneNavigation.GetCurrent("messages"), "current app predicate must match")
assert(not SkyPhoneNavigation.GetCurrent("camera"), "current app predicate must reject another app")
local missing_success, missing_error = SkyPhoneNavigation.Open("mail")
assert(not missing_success and missing_error == "app_not_installed", "uninstalled apps must be rejected")
local open_success, open_error = SkyPhoneNavigation.Open("camera")
assert(open_success and open_error == nil, "installed apps must open")
assert(nui_messages[1].type == "navigation:open-app", "open must use the neutral NUI route")
assert(nui_messages[1].data.appId == "camera", "open must preserve the app id")
local wrong_close_success, wrong_close_error = SkyPhoneNavigation.Close("messages")
assert(not wrong_close_success and wrong_close_error == "app_not_active", "targeted close must match the active app")
local close_success, close_error = SkyPhoneNavigation.Close("camera")
assert(close_success and close_error == nil, "the active app must close")
assert(nui_messages[2].type == "navigation:close-app", "close must use the neutral NUI route")
assert(nui_messages[2].data.appId == "camera", "close must guard against stale router commands")
nui_callbacks["navigation:state"]({
currentApp = nil,
installedApps = { "messages" },
}, function(result)
callback_result = result
end)
assert(callback_result.success, "home navigation state must be accepted")
assert(SkyPhoneNavigation.GetCurrent() == "home", "an open phone without an app must report home")
phone_open = false
event_handlers["sky_phone:client:phoneToggled"](false)
local reset_state = SkyPhoneNavigation.GetState()
assert(reset_state.currentApp == nil and reset_state.installedApps.messages,
"phone close must preserve the loaded device app catalog")
assert(reset_state.dataLoaded and SkyPhoneNavigation.IsDataLoaded(),
"closing the UI must not make durable app data unavailable")
assert(SkyPhoneNavigation.GetCurrent() == nil, "a closed phone must not report a current app")
assert(not SkyPhoneNavigation.GetCurrent("messages"), "a closed phone must fail current app predicates")
nui_callbacks["navigation:state"]({
currentApp = false,
installedApps = { "messages" },
}, function(result)
callback_result = result
end)
assert(not callback_result.success and callback_result.error == "invalid_current_app", "invalid state must be rejected")
print("Client navigation tests passed")