Files
MosisService/base-apps/com.mosis.home/home.lua
omigamedev 1f91d7508e add base-apps with manifests, layout system, and testing documentation
- Rename test-apps to base-apps with proper manifest.json for each app
- Add is_system_app flag to app discovery and Lua API
- Fix icon path resolution for /system/icons/ paths
- Add layout.lua and layout.rcss for reusable UI components
- Update home screen to dynamically load all apps from manifests
- Update all app RML files to use layout components
- Comprehensive testing framework documentation with JSON action format
- Add tests/ directory structure for automated UI testing
2026-01-20 09:14:05 +01:00

201 lines
7.1 KiB
Lua

-- home.lua - Home screen dynamic app rendering
-- Handles system apps and discovered third-party apps
-- System apps with their navigation keys and colors
local system_apps = {
-- Row 1
{name = "Phone", icon = "phone", color = "#4CAF50", nav = "dialer"},
{name = "Messages", icon = "message", color = "#2196F3", nav = "messages"},
{name = "Contacts", icon = "contacts", color = "#FF9800", nav = "contacts"},
{name = "Browser", icon = "browser", color = "#F44336", nav = "browser"},
-- Row 2
{name = "Gallery", icon = "gallery", color = "#9C27B0", nav = nil},
{name = "Camera", icon = "camera", color = "#00BCD4", nav = "camera"},
{name = "Settings", icon = "settings", color = "#607D8B", nav = "settings"},
{name = "Music", icon = "music", color = "#E91E63", nav = "music"},
-- Row 3
{name = "Calendar", icon = "calendar", color = "#3F51B5", nav = nil},
{name = "Clock", icon = "clock", color = "#009688", nav = nil},
{name = "Notes", icon = "notes", color = "#795548", nav = nil},
{name = "Maps", icon = "maps", color = "#FF5722", nav = nil},
-- Row 4
{name = "Store", icon = "store", color = "#8BC34A", nav = "store"},
{name = "Files", icon = "files", color = "#CDDC39", nav = nil},
{name = "Calculator", icon = "calculator", color = "#FFC107", nav = nil},
{name = "Weather", icon = "weather", color = "#673AB7", nav = nil},
}
-- State
local installed_apps = {}
local home_document = nil -- Store document reference
-- Initialize on load (receives document from onload event)
function initHome(doc)
print("[Home] Initializing home screen...")
home_document = doc
-- Get installed third-party apps
if mosis and mosis.apps then
installed_apps = mosis.apps.getInstalled() or {}
print("[Home] Found " .. #installed_apps .. " installed apps")
-- Filter to only third-party (non-system) apps
local third_party = {}
for _, app in ipairs(installed_apps) do
if not app.is_system_app then
table.insert(third_party, app)
print("[Home] Third-party app: " .. app.name .. " (" .. app.package_id .. ")")
end
end
installed_apps = third_party
else
print("[Home] Warning: mosis.apps API not available")
installed_apps = {}
end
-- Render dynamic apps
renderThirdPartyApps()
end
-- Generate a color based on package_id
function getAppColor(package_id)
local colors = {
"#BB86FC", "#03DAC6", "#FF9800", "#2196F3",
"#4CAF50", "#F44336", "#E91E63", "#3F51B5",
"#009688", "#795548", "#FF5722", "#673AB7"
}
-- Simple hash of package_id to pick a color
local hash = 0
for i = 1, #package_id do
hash = hash + package_id:byte(i)
end
return colors[(hash % #colors) + 1]
end
-- Get first letter for placeholder icon
function getAppInitial(name)
return name:sub(1, 1):upper()
end
-- Render third-party apps into the grid
function renderThirdPartyApps()
-- Use stored document reference
if not home_document then
print("[Home] Could not get document reference")
return
end
local grid = home_document:GetElementById("third-party-apps")
if not grid then
print("[Home] third-party-apps container not found")
return
end
-- Clear existing content
grid.inner_rml = ""
if #installed_apps == 0 then
print("[Home] No third-party apps to display")
return
end
-- Build HTML for each app
local html = ""
for _, app in ipairs(installed_apps) do
local color = getAppColor(app.package_id)
local initial = getAppInitial(app.name)
local icon_html
-- Check if app has an icon
if app.icon and app.icon ~= "" then
local icon_path
-- Check if icon is already a full path (starts with / or contains :/)
if app.icon:sub(1, 1) == "/" or app.icon:find(":/") then
-- Already a full path
icon_path = app.icon
elseif app.install_path and app.install_path ~= "" then
-- Relative filename - construct full path from install_path
icon_path = app.install_path .. "/" .. app.icon
else
icon_path = app.icon
end
-- Use file:// prefix for absolute paths to prevent RmlUi URL resolution
local src_path = icon_path
if icon_path:sub(1, 1) == "/" then
src_path = "file://" .. icon_path
end
-- Use img tag for actual icon
icon_html = '<img src="' .. src_path .. '" style="width: 48px; height: 48px;"/>'
print("[Home] Loading icon: " .. src_path)
else
-- Fallback to initial letter
icon_html = '<span style="font-size: 28px; color: #000000;">' .. initial .. '</span>'
end
html = html .. [[
<div class="app-icon">
<div class="app-icon-image" style="background-color: ]] .. color .. [[;"
onclick="launchThirdPartyApp(']] .. app.package_id .. [[')">
]] .. icon_html .. [[
</div>
<span class="app-icon-label">]] .. app.name .. [[</span>
</div>
]]
end
grid.inner_rml = html
print("[Home] Rendered " .. #installed_apps .. " third-party apps")
end
-- Get app info by package_id
function getAppInfo(package_id)
for _, app in ipairs(installed_apps) do
if app.package_id == package_id then
return app
end
end
return nil
end
-- Launch a third-party app
function launchThirdPartyApp(package_id)
print("[Home] Launching app: " .. package_id)
if mosis and mosis.apps then
local success = mosis.apps.launch(package_id)
if success then
print("[Home] App sandbox started: " .. package_id)
-- Get app info for sandbox switching and UI loading
local app_info = getAppInfo(package_id)
if app_info and app_info.install_path and app_info.entry_point then
-- Switch sandbox context to this app (registers timer, fs, json, crypto APIs)
if switchAppSandbox then
switchAppSandbox(package_id, app_info.install_path)
print("[Home] Sandbox context switched to: " .. package_id)
end
-- Now load the app's UI document
local entry_path = app_info.install_path .. "/" .. app_info.entry_point
print("[Home] Loading app screen: " .. entry_path)
local loaded = loadScreen(entry_path)
if loaded then
print("[Home] App UI loaded: " .. package_id)
else
print("[Home] Failed to load app UI: " .. entry_path)
end
else
print("[Home] App info missing entry point: " .. package_id)
end
else
print("[Home] Failed to launch app: " .. package_id)
end
else
print("[Home] Cannot launch app: mosis.apps not available")
end
end
-- initHome() is called via onload in home.rml