UI Apps Manager
Core manager for UI app discovery, layout loading/saving, and layout versioning.
Core manager for UI app discovery, layout loading/saving, and layout versioning.
Overview
ui_apps scans the virtual filesystem for app.json descriptors, manages UI app layouts (save/load/delete/version), and keeps the UI informed of changes via guihooks.
Extension path: lua/ge/extensions/ui/apps.lua
App directory: /ui/modules/apps/
Layout paths: /settings/ui_apps/layouts/, /settings/ui_apps/originalLayouts/
Exports (M)
| Function | Signature | Description |
|---|---|---|
getUIAppsData | () → {availableLayouts, availableApps} | Returns all available apps and layouts. |
requestUIAppsData | () | Triggers onUIAppsData guihook with current data. |
getAvailableLayouts | () → layout[] | Returns all layouts (user + original), with version migration applied. |
saveLayout | (data) | Saves a layout to its filename, updating version metadata. |
deleteLayout | (filename) | Deletes a user layout (refuses official content). |
isAppOnLayout | (appDirective, layout) → bool | Checks if an app directive exists on a layout. |
onFilesChanged | (files) | Re-sends UI data when files in /ui/modules/apps/ or /mods/ change. |
Internals
App Discovery
getAvailableAppList() scans for app.json files recursively under /ui/modules/apps/. Each app gets:
official-isOfficialContentVPath()checkpreviews- Up to 3 preview images (app.png,app2.png,app3.png)typesTranslated- Translated category labelstypesLookup/typesTranslatedLookup- Lookup dicts for fast filtering
Apps missing domElement, directive, or appName are logged as errors and skipped.
Layout Versioning
Layouts support two migration strategies:
- Whole-layout version - If
origLayout.version > userLayout.version, the entire user layout is replaced - Per-app version - Individual apps with
appVersionare updated/added/removed independently
-- Per-app update logic
for _, originalApp in ipairs(origLayout.apps) do
if originalApp.appVersion then
local userAppIndex = getAppIndexByName(userLayout, originalApp.appName)
if userAppIndex then
if userApp.appVersion < originalApp.appVersion then
userLayout.apps[userAppIndex] = originalApp -- update
end
else
table.insert(userLayout.apps, originalApp) -- add new
end
end
endRemoved apps are tracked in layout.removedApps to prevent re-adding.
Save Flow
When saving, updateData() synchronizes appVersion from the original layout and tracks removed apps, then writes to JSON:
local function saveLayout(data)
updateData(data)
jsonWriteFile(filename, data, true)
requestUIAppsData() -- notify UI
endHow It Works
- On load,
getAvailableAppList()scans VFS for allapp.jsonfiles getAvailableLayouts()merges original + user layouts, migrating versions- UI requests data →
requestUIAppsData()triggersonUIAppsDataguihook - User edits layout →
saveLayout()persists changes and refreshes UI - Filesystem changes in
/ui/modules/apps/auto-trigger data refresh
Additional Exports
The following exports are available but not yet documented in detail:
M.deleteLayoutM.getAvailableLayoutsM.getUIAppsDataM.isAppOnLayoutM.onFilesChangedM.requestUIAppsDataM.saveLayout