212 lines
7.2 KiB
PHP
Executable File
212 lines
7.2 KiB
PHP
Executable File
<?php
|
|
|
|
namespace App\Http\Controllers\Api;
|
|
|
|
use Illuminate\Http\JsonResponse;
|
|
use Symfony\Component\HttpFoundation\Response;
|
|
|
|
class UiController extends BaseApiController
|
|
{
|
|
protected string $defaultUserTimezone = 'America/New_York';
|
|
|
|
protected function styleConfig(): array
|
|
{
|
|
$styleCfg = config('Style');
|
|
if (is_object($styleCfg)) {
|
|
return [
|
|
'stylePalettes' => $styleCfg->stylePalettes ?? [],
|
|
'menuPalettes' => $styleCfg->menuPalettes ?? [],
|
|
];
|
|
}
|
|
return [
|
|
'stylePalettes' => $styleCfg['stylePalettes'] ?? [],
|
|
'menuPalettes' => $styleCfg['menuPalettes'] ?? [],
|
|
];
|
|
}
|
|
|
|
/**
|
|
* GET /api/v1/ui/style
|
|
* Get current UI style preferences
|
|
*/
|
|
public function getStyle()
|
|
{
|
|
$user = $this->getCurrentUser();
|
|
if (!$user) {
|
|
return $this->respondError('Authentication required', Response::HTTP_UNAUTHORIZED);
|
|
}
|
|
|
|
try {
|
|
$session = session();
|
|
$cfg = $this->styleConfig();
|
|
|
|
return $this->success([
|
|
'style_color' => $session->get('style_color'),
|
|
'menu_color' => $session->get('menu_color'),
|
|
'menu_custom_bg' => $session->get('menu_custom_bg'),
|
|
'menu_custom_text' => $session->get('menu_custom_text'),
|
|
'menu_custom_mode' => $session->get('menu_custom_mode'),
|
|
'available_palettes' => $cfg['stylePalettes'] ?? [],
|
|
'available_menus' => $cfg['menuPalettes'] ?? [],
|
|
], 'UI style preferences retrieved successfully');
|
|
} catch (\Throwable $e) {
|
|
log_message('error', 'UI style error: ' . $e->getMessage());
|
|
return $this->respondError('Failed to retrieve UI style', Response::HTTP_INTERNAL_SERVER_ERROR);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* POST /api/v1/ui/style
|
|
* Update UI style preferences via POST body
|
|
*/
|
|
public function updateStyle()
|
|
{
|
|
$user = $this->getCurrentUser();
|
|
if (!$user) {
|
|
return $this->respondError('Authentication required', Response::HTTP_UNAUTHORIZED);
|
|
}
|
|
|
|
$data = $this->payloadData();
|
|
if (empty($data)) {
|
|
return $this->respondError('Invalid request data', Response::HTTP_BAD_REQUEST);
|
|
}
|
|
|
|
return $this->processStyleUpdate($data);
|
|
}
|
|
|
|
/**
|
|
* GET /api/v1/ui/style (with query parameters)
|
|
* Update UI style preferences via GET parameters (for backward compatibility)
|
|
*/
|
|
public function style()
|
|
{
|
|
$user = $this->getCurrentUser();
|
|
if (!$user) {
|
|
return $this->respondError('Authentication required', Response::HTTP_UNAUTHORIZED);
|
|
}
|
|
|
|
// Get parameters from query string
|
|
$accent = (string) $this->request->getGet('accent');
|
|
$menu = (string) $this->request->getGet('menu');
|
|
$menuBg = (string) $this->request->getGet('menu_bg');
|
|
$menuTx = (string) $this->request->getGet('menu_text');
|
|
$menuMd = (string) $this->request->getGet('menu_mode');
|
|
|
|
$data = [];
|
|
if ($accent !== '') {
|
|
$data['accent'] = $accent;
|
|
}
|
|
if ($menu !== '') {
|
|
$data['menu'] = $menu;
|
|
}
|
|
if ($menuBg !== '') {
|
|
$data['menu_bg'] = $menuBg;
|
|
}
|
|
if ($menuTx !== '') {
|
|
$data['menu_text'] = $menuTx;
|
|
}
|
|
if ($menuMd !== '') {
|
|
$data['menu_mode'] = $menuMd;
|
|
}
|
|
|
|
if (empty($data)) {
|
|
// No parameters provided, return current style
|
|
return $this->getStyle();
|
|
}
|
|
|
|
return $this->processStyleUpdate($data);
|
|
}
|
|
|
|
/**
|
|
* Process style update from either GET or POST
|
|
*/
|
|
private function processStyleUpdate(array $data): JsonResponse
|
|
{
|
|
try {
|
|
$session = session();
|
|
$cfg = $this->styleConfig();
|
|
|
|
if (isset($data['accent']) && $data['accent'] !== '' && isset(($cfg['stylePalettes'] ?? [])[$data['accent']])) {
|
|
$session->put('style_color', $data['accent']);
|
|
}
|
|
|
|
if (isset($data['menu']) && $data['menu'] !== '') {
|
|
if (isset(($cfg['menuPalettes'] ?? [])[$data['menu']])) {
|
|
$session->put('menu_color', $data['menu']);
|
|
} elseif (strtolower($data['menu']) === 'custom' || (isset($data['menu_bg']) && $data['menu_bg'] !== '') || (isset($data['menu_text']) && $data['menu_text'] !== '')) {
|
|
// Allow custom menu colors
|
|
$bg = $this->normalizeHex($data['menu_bg'] ?? '');
|
|
$tx = $this->normalizeHex($data['menu_text'] ?? '');
|
|
|
|
if ($bg === '' && $tx === '') {
|
|
// no valid values; ignore
|
|
} else {
|
|
if ($bg === '') {
|
|
$bg = '#0f172a';
|
|
}
|
|
if ($tx === '') {
|
|
$tx = '#ffffff';
|
|
}
|
|
|
|
// Determine mode if requested auto or missing
|
|
$mode = isset($data['menu_mode']) && in_array($data['menu_mode'], ['light', 'dark'], true)
|
|
? $data['menu_mode']
|
|
: $this->autoModeForBg($bg);
|
|
|
|
$session->put('menu_color', 'custom');
|
|
$session->put('menu_custom_bg', $bg);
|
|
$session->put('menu_custom_text', $tx);
|
|
$session->put('menu_custom_mode', $mode);
|
|
}
|
|
}
|
|
}
|
|
|
|
return $this->success([
|
|
'style_color' => $session->get('style_color'),
|
|
'menu_color' => $session->get('menu_color'),
|
|
'menu_custom_bg' => $session->get('menu_custom_bg'),
|
|
'menu_custom_text' => $session->get('menu_custom_text'),
|
|
'menu_custom_mode' => $session->get('menu_custom_mode'),
|
|
], 'UI style updated successfully');
|
|
} catch (\Throwable $e) {
|
|
log_message('error', 'UI style update error: ' . $e->getMessage());
|
|
return $this->respondError('Failed to update UI style', Response::HTTP_INTERNAL_SERVER_ERROR);
|
|
}
|
|
}
|
|
|
|
private function normalizeHex(string $hex): string
|
|
{
|
|
$h = trim($hex);
|
|
if ($h === '') {
|
|
return '';
|
|
}
|
|
if ($h[0] !== '#') {
|
|
$h = '#' . $h;
|
|
}
|
|
if (preg_match('/^#([0-9a-fA-F]{3})$/', $h, $m)) {
|
|
$r = $m[1][0];
|
|
$g = $m[1][1];
|
|
$b = $m[1][2];
|
|
return '#' . $r . $r . $g . $g . $b . $b;
|
|
}
|
|
if (preg_match('/^#([0-9a-fA-F]{6})$/', $h)) {
|
|
return strtoupper($h);
|
|
}
|
|
return '';
|
|
}
|
|
|
|
private function autoModeForBg(string $hexBg): string
|
|
{
|
|
$hex = ltrim($hexBg, '#');
|
|
if (strlen($hex) !== 6) {
|
|
return 'dark';
|
|
}
|
|
|
|
$r = hexdec(substr($hex, 0, 2));
|
|
$g = hexdec(substr($hex, 2, 2));
|
|
$b = hexdec(substr($hex, 4, 2));
|
|
|
|
$lum = (0.2126 * $r + 0.7152 * $g + 0.0722 * $b) / 255;
|
|
return $lum < 0.5 ? 'dark' : 'light';
|
|
}
|
|
}
|