mirror of
https://github.com/pelican-dev/panel.git
synced 2025-05-19 21:04:44 +02:00
Allow changing of the console font (#1277)
* Custom Fonts * Update app/Filament/Pages/Auth/EditProfile.php Co-authored-by: MartinOscar <40749467+rmartinoscar@users.noreply.github.com> * wip * wip * Update app/Filament/Pages/Auth/EditProfile.php Co-authored-by: Lance Pioch <git@lance.sh> * Update app/helpers.php Co-authored-by: MartinOscar <40749467+rmartinoscar@users.noreply.github.com> * update * add fonts folder for docker * Add default font * Update server console to preload the font * Update settings/trans --------- Co-authored-by: MartinOscar <40749467+rmartinoscar@users.noreply.github.com> Co-authored-by: Lance Pioch <git@lance.sh>
This commit is contained in:
parent
e354bc9be7
commit
3effd98013
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,7 +1,6 @@
|
|||||||
/.phpunit.cache
|
/.phpunit.cache
|
||||||
/node_modules
|
/node_modules
|
||||||
/public/build
|
/public/build
|
||||||
/public/hot
|
|
||||||
/public/storage
|
/public/storage
|
||||||
/storage/*.key
|
/storage/*.key
|
||||||
/storage/pail
|
/storage/pail
|
||||||
|
@ -82,6 +82,7 @@ RUN chown root:www-data ./ \
|
|||||||
&& ln -s /pelican-data/database/database.sqlite ./database/database.sqlite \
|
&& ln -s /pelican-data/database/database.sqlite ./database/database.sqlite \
|
||||||
&& ln -sf /var/www/html/storage/app/public /var/www/html/public/storage \
|
&& ln -sf /var/www/html/storage/app/public /var/www/html/public/storage \
|
||||||
&& ln -s /pelican-data/storage/avatars /var/www/html/storage/app/public/avatars \
|
&& ln -s /pelican-data/storage/avatars /var/www/html/storage/app/public/avatars \
|
||||||
|
&& ln -s /pelican-data/storage/fonts /var/www/html/storage/app/public/fonts \
|
||||||
# Allow www-data write permissions where necessary
|
# Allow www-data write permissions where necessary
|
||||||
&& chown -R www-data:www-data /pelican-data ./storage ./bootstrap/cache /var/run/supervisord /var/www/html/public/storage \
|
&& chown -R www-data:www-data /pelican-data ./storage ./bootstrap/cache /var/run/supervisord /var/www/html/public/storage \
|
||||||
&& chmod -R u+rwX,g+rwX,o-rwx /pelican-data ./storage ./bootstrap/cache /var/run/supervisord
|
&& chmod -R u+rwX,g+rwX,o-rwx /pelican-data ./storage ./bootstrap/cache /var/run/supervisord
|
||||||
|
@ -13,6 +13,7 @@ use Filament\Actions\Action;
|
|||||||
use Filament\Forms\Components\Actions;
|
use Filament\Forms\Components\Actions;
|
||||||
use Filament\Forms\Components\Actions\Action as FormAction;
|
use Filament\Forms\Components\Actions\Action as FormAction;
|
||||||
use Filament\Forms\Components\Component;
|
use Filament\Forms\Components\Component;
|
||||||
|
use Filament\Forms\Components\FileUpload;
|
||||||
use Filament\Forms\Components\Group;
|
use Filament\Forms\Components\Group;
|
||||||
use Filament\Forms\Components\Hidden;
|
use Filament\Forms\Components\Hidden;
|
||||||
use Filament\Forms\Components\Section;
|
use Filament\Forms\Components\Section;
|
||||||
@ -724,10 +725,17 @@ class Settings extends Page implements HasForms
|
|||||||
->onColor('success')
|
->onColor('success')
|
||||||
->offColor('danger')
|
->offColor('danger')
|
||||||
->live()
|
->live()
|
||||||
->columnSpanFull()
|
->columnSpan(1)
|
||||||
->formatStateUsing(fn ($state): bool => (bool) $state)
|
->formatStateUsing(fn ($state): bool => (bool) $state)
|
||||||
->afterStateUpdated(fn ($state, Set $set) => $set('PANEL_EDITABLE_SERVER_DESCRIPTIONS', (bool) $state))
|
->afterStateUpdated(fn ($state, Set $set) => $set('PANEL_EDITABLE_SERVER_DESCRIPTIONS', (bool) $state))
|
||||||
->default(env('PANEL_EDITABLE_SERVER_DESCRIPTIONS', config('panel.editable_server_descriptions'))),
|
->default(env('PANEL_EDITABLE_SERVER_DESCRIPTIONS', config('panel.editable_server_descriptions'))),
|
||||||
|
FileUpload::make('ConsoleFonts')
|
||||||
|
->hint(trans('admin/setting.misc.server.console_font_hint'))
|
||||||
|
->label(trans('admin/setting.misc.server.console_font_upload'))
|
||||||
|
->directory('fonts')
|
||||||
|
->columnSpan(1)
|
||||||
|
->maxFiles(1)
|
||||||
|
->preserveFilenames(),
|
||||||
]),
|
]),
|
||||||
Section::make(trans('admin/setting.misc.webhook.title'))
|
Section::make(trans('admin/setting.misc.webhook.title'))
|
||||||
->description(trans('admin/setting.misc.webhook.helper'))
|
->description(trans('admin/setting.misc.webhook.helper'))
|
||||||
@ -756,6 +764,7 @@ class Settings extends Page implements HasForms
|
|||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$data = $this->form->getState();
|
$data = $this->form->getState();
|
||||||
|
unset($data['ConsoleFonts']);
|
||||||
|
|
||||||
// Convert bools to a string, so they are correctly written to the .env file
|
// Convert bools to a string, so they are correctly written to the .env file
|
||||||
$data = array_map(fn ($value) => is_bool($value) ? ($value ? 'true' : 'false') : $value, $data);
|
$data = array_map(fn ($value) => is_bool($value) ? ($value ? 'true' : 'false') : $value, $data);
|
||||||
|
@ -373,10 +373,35 @@ class EditProfile extends BaseEditProfile
|
|||||||
->required()
|
->required()
|
||||||
->columnSpan(1)
|
->columnSpan(1)
|
||||||
->default(30),
|
->default(30),
|
||||||
// Select::make('console_font')
|
Select::make('console_font')
|
||||||
// ->label(trans('profile.font'))
|
->label(trans('profile.font'))
|
||||||
// ->hidden() //TODO
|
->options(fn () => get_fonts(storage_path('app\public\fonts')))
|
||||||
// ->columnSpan(1),
|
->reactive()
|
||||||
|
->afterStateUpdated(fn ($state, callable $set) => $set('font_preview', $state)),
|
||||||
|
Placeholder::make('font_preview')
|
||||||
|
->label('Preview')
|
||||||
|
->content(function (Get $get) {
|
||||||
|
$fontName = $get('console_font') ?? 'No font selected.';
|
||||||
|
|
||||||
|
$fontUrl = asset("fonts/{$fontName}.ttf");
|
||||||
|
$fontSize = $get('console_font_size') . 'px';
|
||||||
|
|
||||||
|
return new HtmlString(<<<HTML
|
||||||
|
<style>
|
||||||
|
@font-face {
|
||||||
|
font-family: "CustomPreviewFont";
|
||||||
|
src: url("$fontUrl");
|
||||||
|
}
|
||||||
|
.preview-text {
|
||||||
|
font-family: "CustomPreviewFont";
|
||||||
|
font-size: $fontSize;
|
||||||
|
margin-top: 10px;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<span class="preview-text">The quick blue pelican jumps over the lazy pterodactyl. :)</span>
|
||||||
|
HTML);
|
||||||
|
}),
|
||||||
TextInput::make('console_font_size')
|
TextInput::make('console_font_size')
|
||||||
->label(trans('profile.font_size'))
|
->label(trans('profile.font_size'))
|
||||||
->columnSpan(1)
|
->columnSpan(1)
|
||||||
@ -446,12 +471,13 @@ class EditProfile extends BaseEditProfile
|
|||||||
protected function mutateFormDataBeforeSave(array $data): array
|
protected function mutateFormDataBeforeSave(array $data): array
|
||||||
{
|
{
|
||||||
$moarbetterdata = [
|
$moarbetterdata = [
|
||||||
|
'console_font' => $data['console_font'],
|
||||||
'console_font_size' => $data['console_font_size'],
|
'console_font_size' => $data['console_font_size'],
|
||||||
'console_rows' => $data['console_rows'],
|
'console_rows' => $data['console_rows'],
|
||||||
'dashboard_layout' => $data['dashboard_layout'],
|
'dashboard_layout' => $data['dashboard_layout'],
|
||||||
];
|
];
|
||||||
|
|
||||||
unset($data['dashboard_layout'], $data['console_font_size'], $data['console_rows']);
|
unset($data['console_font'],$data['console_font_size'], $data['console_rows'], $data['dashboard_layout']);
|
||||||
$data['customization'] = json_encode($moarbetterdata);
|
$data['customization'] = json_encode($moarbetterdata);
|
||||||
|
|
||||||
return $data;
|
return $data;
|
||||||
@ -461,6 +487,7 @@ class EditProfile extends BaseEditProfile
|
|||||||
{
|
{
|
||||||
$moarbetterdata = json_decode($data['customization'], true);
|
$moarbetterdata = json_decode($data['customization'], true);
|
||||||
|
|
||||||
|
$data['console_font'] = $moarbetterdata['console_font'] ?? 'ComicMono';
|
||||||
$data['console_font_size'] = $moarbetterdata['console_font_size'] ?? 14;
|
$data['console_font_size'] = $moarbetterdata['console_font_size'] ?? 14;
|
||||||
$data['console_rows'] = $moarbetterdata['console_rows'] ?? 30;
|
$data['console_rows'] = $moarbetterdata['console_rows'] ?? 30;
|
||||||
$data['dashboard_layout'] = $moarbetterdata['dashboard_layout'] ?? 'grid';
|
$data['dashboard_layout'] = $moarbetterdata['dashboard_layout'] ?? 'grid';
|
||||||
|
@ -67,3 +67,17 @@ if (!function_exists('resolve_path')) {
|
|||||||
return implode('/', $absolutes);
|
return implode('/', $absolutes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!function_exists('get_fonts')) {
|
||||||
|
/**
|
||||||
|
* @return array<string, string>
|
||||||
|
*/
|
||||||
|
function get_fonts(?string $directory = null): array
|
||||||
|
{
|
||||||
|
$directory ??= public_path('fonts');
|
||||||
|
|
||||||
|
return collect(glob($directory . '/*.ttf', GLOB_BRACE) ?: [])
|
||||||
|
->mapWithKeys(fn ($file) => [$name = pathinfo($file, PATHINFO_FILENAME) => $name])
|
||||||
|
->all();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -23,7 +23,7 @@ else
|
|||||||
echo -e "APP_INSTALLED=false" >> /pelican-data/.env
|
echo -e "APP_INSTALLED=false" >> /pelican-data/.env
|
||||||
fi
|
fi
|
||||||
|
|
||||||
mkdir -p /pelican-data/database /pelican-data/storage/avatars /var/www/html/storage/logs/supervisord 2>/dev/null
|
mkdir -p /pelican-data/database /pelican-data/storage/avatars /pelican-data/storage/fonts /var/www/html/storage/logs/supervisord 2>/dev/null
|
||||||
|
|
||||||
if ! grep -q "APP_KEY=" .env || grep -q "APP_KEY=$" .env; then
|
if ! grep -q "APP_KEY=" .env || grep -q "APP_KEY=$" .env; then
|
||||||
echo "Generating APP_KEY..."
|
echo "Generating APP_KEY..."
|
||||||
|
@ -137,6 +137,8 @@ return [
|
|||||||
'title' => 'Servers',
|
'title' => 'Servers',
|
||||||
'helper' => 'Settings for Servers',
|
'helper' => 'Settings for Servers',
|
||||||
'edit_server_desc' => 'Allow Users to edit Descriptions?',
|
'edit_server_desc' => 'Allow Users to edit Descriptions?',
|
||||||
|
'console_font_upload' => 'Console Font Upload',
|
||||||
|
'console_font_hint' => 'Only *.ttf fonts are supported. Mono fonts strongly recommended!',
|
||||||
],
|
],
|
||||||
'webhook' => [
|
'webhook' => [
|
||||||
'title' => 'Webhooks',
|
'title' => 'Webhooks',
|
||||||
|
@ -48,15 +48,3 @@
|
|||||||
::-webkit-scrollbar-corner {
|
::-webkit-scrollbar-corner {
|
||||||
background: transparent;
|
background: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: Comic Mono;
|
|
||||||
font-weight: normal;
|
|
||||||
src: url('/fonts/ComicMono.ttf');
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: Comic Mono;
|
|
||||||
font-weight: bold;
|
|
||||||
src: url('/fonts/ComicMono-bold.ttf');
|
|
||||||
}
|
|
||||||
|
Binary file not shown.
@ -1,12 +1,25 @@
|
|||||||
<x-filament::widget>
|
<x-filament::widget>
|
||||||
@assets
|
@assets
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@xterm/xterm/css/xterm.min.css">
|
@php
|
||||||
|
$userFont = auth()->user()->getCustomization()['console_font'] ?? 'ComicMono';
|
||||||
|
$userFontSize = auth()->user()->getCustomization()['console_font_size'] ?? 14;
|
||||||
|
$userRows = auth()->user()->getCustomization()['console_rows'] ?? 30;
|
||||||
|
@endphp
|
||||||
<script src="https://cdn.jsdelivr.net/npm/@xterm/xterm/lib/xterm.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/@xterm/xterm/lib/xterm.min.js"></script>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/@xterm/addon-fit/lib/addon-fit.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/@xterm/addon-fit/lib/addon-fit.min.js"></script>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/@xterm/addon-web-links/lib/addon-web-links.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/@xterm/addon-web-links/lib/addon-web-links.min.js"></script>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/@xterm/addon-search/lib/addon-search.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/@xterm/addon-search/lib/addon-search.min.js"></script>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/xterm-addon-search-bar/lib/xterm-addon-search-bar.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/xterm-addon-search-bar/lib/xterm-addon-search-bar.min.js"></script>
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@xterm/xterm/css/xterm.min.css">
|
||||||
<link rel="stylesheet" href="{{ asset('/css/filament/server/console.css') }}">
|
<link rel="stylesheet" href="{{ asset('/css/filament/server/console.css') }}">
|
||||||
|
<link rel="preload" href="{{ asset("storage/fonts/{$userFont}.ttf") }}" as="font" crossorigin>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
@font-face {
|
||||||
|
font-family: '{{ $userFont }}';
|
||||||
|
src: url('{{ asset("storage/fonts/{$userFont}.ttf") }}');
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@endassets
|
@endassets
|
||||||
|
|
||||||
<div id="terminal" wire:ignore></div>
|
<div id="terminal" wire:ignore></div>
|
||||||
@ -57,14 +70,14 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
let options = {
|
let options = {
|
||||||
fontSize: {{ auth()->user()->getCustomization()['console_font_size'] ?? 14 }},
|
fontSize: {{ $userFontSize }},
|
||||||
fontFamily: 'Comic Mono, monospace',
|
fontFamily: '{{ $userFont }}',
|
||||||
lineHeight: 1.2,
|
lineHeight: 1.2,
|
||||||
disableStdin: true,
|
disableStdin: true,
|
||||||
cursorStyle: 'underline',
|
cursorStyle: 'underline',
|
||||||
cursorInactiveStyle: 'underline',
|
cursorInactiveStyle: 'underline',
|
||||||
allowTransparency: true,
|
allowTransparency: true,
|
||||||
rows: {{ auth()->user()->getCustomization()['console_rows'] ?? 30 }},
|
rows: {{ $userRows }},
|
||||||
theme: theme
|
theme: theme
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user