adsdad
All checks were successful
Deploy / deploy-staging (push) Successful in 24s
Deploy / deploy-production (push) Has been skipped

This commit is contained in:
2026-06-25 00:36:14 +02:00
parent ac2d95fc56
commit 487f592ca3
12 changed files with 188 additions and 17 deletions

View File

@@ -8,6 +8,7 @@ use Desktop\AppRegistry;
use Desktop\AppIconResolver;
use Desktop\AppVisibility;
use Desktop\DesktopState;
use Desktop\ShellAppRegistry;
use Desktop\SkinResolver;
use Desktop\WidgetRegistry;
use Desktop\WindowManager;
@@ -30,6 +31,7 @@ final class App
$moduleRegistry = new ModuleRegistry(AppPaths::customAppsRoot($this->projectRoot));
$registry = new AppRegistry($this->projectRoot . '/config/apps.php', $moduleRegistry->desktopApps());
$widgetRegistry = new WidgetRegistry($this->projectRoot . '/config/widgets.php', $moduleRegistry->widgets());
$shellRegistry = new ShellAppRegistry(AppPaths::systemShellRoot($this->projectRoot));
$skins = SkinResolver::all();
$isAuthenticated = isset($_SESSION['desktop_auth']) && is_array($_SESSION['desktop_auth']);
$authUser = $isAuthenticated && is_array($_SESSION['desktop_auth']['user'] ?? null)
@@ -113,6 +115,10 @@ final class App
'active_ids' => $activeWidgetIds,
],
'tray' => $trayItems,
'shell' => [
'apps' => $shellRegistry->all(),
'debug_app' => $shellRegistry->find('desktop-debug'),
],
'session' => [
'display_name' => $displayName,
'authenticated' => $isAuthenticated,

View File

@@ -25,4 +25,14 @@ final class AppPaths
{
return self::systemAppsRoot($projectRoot) . '/' . trim($appName, '/');
}
public static function systemShellRoot(string $projectRoot): string
{
return rtrim($projectRoot, '/') . '/system/shell';
}
public static function systemShellPath(string $projectRoot, string $shellName): string
{
return self::systemShellRoot($projectRoot) . '/' . trim($shellName, '/');
}
}

View File

@@ -0,0 +1,82 @@
<?php
declare(strict_types=1);
namespace Desktop;
final class ShellAppRegistry
{
/**
* @var array<int, array<string, mixed>>|null
*/
private ?array $apps = null;
public function __construct(
private readonly string $shellRoot,
) {
}
/**
* @return array<int, array<string, mixed>>
*/
public function all(): array
{
if ($this->apps !== null) {
return $this->apps;
}
if (!is_dir($this->shellRoot)) {
return $this->apps = [];
}
$apps = [];
foreach (glob($this->shellRoot . '/*/definition.php') ?: [] as $definitionPath) {
$app = require $definitionPath;
if (!is_array($app)) {
continue;
}
$appId = trim((string) ($app['app_id'] ?? ''));
if ($appId === '') {
continue;
}
$apps[] = [
'app_id' => $appId,
'title' => (string) ($app['title'] ?? $appId),
'label' => (string) ($app['label'] ?? $appId),
'content_mode' => (string) ($app['content_mode'] ?? 'shell'),
'admin_only' => (bool) ($app['admin_only'] ?? false),
'entry_route' => (string) ($app['entry_route'] ?? ''),
'content' => (string) ($app['content'] ?? ''),
'window' => is_array($app['window'] ?? null) ? $app['window'] : [],
'ui' => is_array($app['ui'] ?? null) ? $app['ui'] : [],
];
}
usort(
$apps,
static fn (array $left, array $right): int => strcmp(
(string) ($left['title'] ?? $left['app_id'] ?? ''),
(string) ($right['title'] ?? $right['app_id'] ?? '')
)
);
return $this->apps = array_values($apps);
}
/**
* @return array<string, mixed>|null
*/
public function find(string $appId): ?array
{
foreach ($this->all() as $app) {
if ((string) ($app['app_id'] ?? '') === $appId) {
return $app;
}
}
return null;
}
}