New desktop
This commit is contained in:
51
src/App/App.php
Normal file
51
src/App/App.php
Normal file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App;
|
||||
|
||||
use Desktop\AppRegistry;
|
||||
use Desktop\DesktopState;
|
||||
use Desktop\SkinResolver;
|
||||
use Desktop\WindowManager;
|
||||
|
||||
final class App
|
||||
{
|
||||
public function __construct(
|
||||
private readonly string $projectRoot,
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function desktopPayload(): array
|
||||
{
|
||||
$registry = new AppRegistry($this->projectRoot . '/config/apps.php');
|
||||
$skins = SkinResolver::all();
|
||||
$activeSkin = SkinResolver::resolve($_GET['skin'] ?? null);
|
||||
$windows = (new WindowManager($registry))->defaultWindows();
|
||||
|
||||
return [
|
||||
'meta' => [
|
||||
'title' => 'Kusche.Berlin Desktop UI',
|
||||
'active_skin' => $activeSkin,
|
||||
'available_skins' => $skins,
|
||||
],
|
||||
'desktop' => [
|
||||
'greeting' => 'Neue Desktop-Shell fuer Kusche.Berlin',
|
||||
'wallpaper' => SkinResolver::wallpaper($activeSkin),
|
||||
'workspace' => DesktopState::defaultWorkspace(),
|
||||
'login' => [
|
||||
'authenticated' => false,
|
||||
'mode' => 'public-home',
|
||||
'keycloak_theme_handoff' => '/docs/keycloak-theme-handoff.md',
|
||||
],
|
||||
],
|
||||
'apps' => $registry->all(),
|
||||
'windows' => $windows,
|
||||
'widgets' => DesktopState::defaultWidgets(),
|
||||
'tray' => DesktopState::trayItems(),
|
||||
];
|
||||
}
|
||||
}
|
||||
23
src/App/bootstrap.php
Normal file
23
src/App/bootstrap.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
spl_autoload_register(static function (string $class): void {
|
||||
$prefixes = [
|
||||
'App\\' => __DIR__ . '/',
|
||||
'Desktop\\' => dirname(__DIR__) . '/Desktop/',
|
||||
];
|
||||
|
||||
foreach ($prefixes as $prefix => $baseDir) {
|
||||
if (!str_starts_with($class, $prefix)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$relative = substr($class, strlen($prefix));
|
||||
$path = $baseDir . str_replace('\\', '/', $relative) . '.php';
|
||||
|
||||
if (is_file($path)) {
|
||||
require_once $path;
|
||||
}
|
||||
}
|
||||
});
|
||||
40
src/Desktop/AppRegistry.php
Normal file
40
src/Desktop/AppRegistry.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Desktop;
|
||||
|
||||
final class AppRegistry
|
||||
{
|
||||
/** @var array<int, array<string, mixed>> */
|
||||
private array $apps;
|
||||
|
||||
public function __construct(string $configPath)
|
||||
{
|
||||
/** @var array<int, array<string, mixed>> $apps */
|
||||
$apps = require $configPath;
|
||||
$this->apps = $apps;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<int, array<string, mixed>>
|
||||
*/
|
||||
public function all(): array
|
||||
{
|
||||
return $this->apps;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>|null
|
||||
*/
|
||||
public function find(string $appId): ?array
|
||||
{
|
||||
foreach ($this->apps as $app) {
|
||||
if (($app['app_id'] ?? null) === $appId) {
|
||||
return $app;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
52
src/Desktop/DesktopState.php
Normal file
52
src/Desktop/DesktopState.php
Normal file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Desktop;
|
||||
|
||||
final class DesktopState
|
||||
{
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public static function defaultWorkspace(): array
|
||||
{
|
||||
return [
|
||||
'workspace_id' => 'default',
|
||||
'title' => 'Persoenlicher Desktop',
|
||||
'supports_public_home' => true,
|
||||
'supports_multi_workspace' => true,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<int, array<string, string>>
|
||||
*/
|
||||
public static function defaultWidgets(): array
|
||||
{
|
||||
return [
|
||||
[
|
||||
'widget_id' => 'public-home',
|
||||
'title' => 'Public Home',
|
||||
'content' => 'Oeffentliches Dashboard als Startzustand fuer nicht eingeloggte Nutzer.',
|
||||
],
|
||||
[
|
||||
'widget_id' => 'personal-links',
|
||||
'title' => 'Persoenliche Links',
|
||||
'content' => 'Platzhalter fuer spaetere user-spezifische Linklisten und Dashboards.',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<int, array<string, string>>
|
||||
*/
|
||||
public static function trayItems(): array
|
||||
{
|
||||
return [
|
||||
['id' => 'network', 'label' => 'Netzwerk'],
|
||||
['id' => 'widgets', 'label' => 'Widgets'],
|
||||
['id' => 'account', 'label' => 'Gast'],
|
||||
];
|
||||
}
|
||||
}
|
||||
32
src/Desktop/SkinResolver.php
Normal file
32
src/Desktop/SkinResolver.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Desktop;
|
||||
|
||||
final class SkinResolver
|
||||
{
|
||||
/**
|
||||
* @return array<int, string>
|
||||
*/
|
||||
public static function all(): array
|
||||
{
|
||||
return ['windows', 'apple', 'linux'];
|
||||
}
|
||||
|
||||
public static function resolve(?string $requestedSkin): string
|
||||
{
|
||||
$skin = strtolower((string) $requestedSkin);
|
||||
|
||||
return in_array($skin, self::all(), true) ? $skin : 'windows';
|
||||
}
|
||||
|
||||
public static function wallpaper(string $skin): string
|
||||
{
|
||||
return match ($skin) {
|
||||
'apple' => 'radial-gradient(circle at top, #ffe7ba 0%, #ff9a62 38%, #531b53 100%)',
|
||||
'linux' => 'linear-gradient(140deg, #111827 0%, #1f2937 40%, #ea580c 100%)',
|
||||
default => 'linear-gradient(160deg, #1d4ed8 0%, #0f172a 100%)',
|
||||
};
|
||||
}
|
||||
}
|
||||
44
src/Desktop/WindowManager.php
Normal file
44
src/Desktop/WindowManager.php
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Desktop;
|
||||
|
||||
final class WindowManager
|
||||
{
|
||||
public function __construct(
|
||||
private readonly AppRegistry $registry,
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<int, array<string, mixed>>
|
||||
*/
|
||||
public function defaultWindows(): array
|
||||
{
|
||||
$defaults = ['welcome-center', 'public-dashboard'];
|
||||
$windows = [];
|
||||
|
||||
foreach ($defaults as $index => $appId) {
|
||||
$app = $this->registry->find($appId);
|
||||
|
||||
if ($app === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$windows[] = [
|
||||
'window_id' => 'window-' . $appId,
|
||||
'app_id' => $appId,
|
||||
'title' => $app['title'],
|
||||
'state' => $index === 0 ? 'focused' : 'open',
|
||||
'x' => 72 + ($index * 48),
|
||||
'y' => 84 + ($index * 36),
|
||||
'width' => $app['default_width'] ?? 640,
|
||||
'height' => $app['default_height'] ?? 420,
|
||||
'content' => $app['summary'] ?? '',
|
||||
];
|
||||
}
|
||||
|
||||
return $windows;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user