Compare commits

...

3 commits

Author SHA1 Message Date
Benjamin Nussbaum
5eb442d9d6 chore: phpstan fixes
Some checks failed
tests / ci (push) Has been cancelled
2026-02-20 20:16:40 +01:00
Benjamin Nussbaum
c7abc14e26 chore: generate screens for new models 2026-02-20 20:00:57 +01:00
Benjamin Nussbaum
0797f17ebb feat: inject device dimensions into framework 2026-02-20 20:00:23 +01:00
24 changed files with 137 additions and 2 deletions

View file

@ -156,7 +156,7 @@ class CheckVersionUpdateJob
private function extractLatestVersion(array $response, bool $enablePrereleases): array
{
if (! $enablePrereleases || ! is_array($response) || ! isset($response[0])) {
if (! $enablePrereleases || ! isset($response[0])) {
return [
Arr::get($response, 'tag_name'),
$response,

View file

@ -4,11 +4,13 @@ declare(strict_types=1);
namespace App\Models;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
/**
* @property-read array<string, string> $css_variables
* @property-read DevicePalette|null $palette
*/
final class DeviceModel extends Model
@ -76,4 +78,37 @@ final class DeviceModel extends Model
{
return $this->belongsTo(DevicePalette::class, 'palette_id');
}
/**
* Returns css_variables with --screen-w and --screen-h filled from width/height
* when puppeteer_window_size_strategy is v2 and they are not set.
*
* @return Attribute<array<string, string>, array<string, string>>
*/
protected function cssVariables(): Attribute
{
/** @var Attribute<array<string, string>, array<string, string>> */
return Attribute::get(
/** @return array<string, string> */
function (mixed $value, array $attributes): array {
$vars = is_array($value) ? $value : (is_string($value) ? (json_decode($value, true) ?? []) : []);
if (config('app.puppeteer_window_size_strategy') !== 'v2') {
return $vars;
}
$width = $attributes['width'] ?? null;
$height = $attributes['height'] ?? null;
if (empty($vars['--screen-w']) && $width !== null && $width !== '') {
$vars['--screen-w'] = is_numeric($width) ? (int) $width.'px' : (string) $width;
}
if (empty($vars['--screen-h']) && $height !== null && $height !== '') {
$vars['--screen-h'] = is_numeric($height) ? (int) $height.'px' : (string) $height;
}
/** @var array<string, string> $vars */
return $vars;
});
}
}

View file

@ -528,7 +528,7 @@ class ImageGenerationService
'deviceOrientation' => $deviceOrientation,
'colorDepth' => $colorDepth,
'scaleLevel' => $scaleLevel,
'cssVariables' => $device->deviceModel?->css_variables,
'cssVariables' => $device->deviceModel?->css_variables ?? [],
];
// Add plugin name for error screens

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 686 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 901 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2 KiB

View file

@ -0,0 +1,100 @@
<?php
use App\Models\Device;
use App\Models\DeviceModel;
use Illuminate\Support\Facades\Config;
beforeEach(function (): void {
Config::set('app.puppeteer_window_size_strategy', 'v2');
});
test('screen component outputs :root with --screen-w and --screen-h when cssVariables are passed', function (): void {
$html = view('trmnl-layouts.single', [
'slot' => '<div>test</div>',
'cssVariables' => [
'--screen-w' => '800px',
'--screen-h' => '480px',
],
])->render();
expect($html)->toContain(':root');
expect($html)->toContain('--screen-w: 800px');
expect($html)->toContain('--screen-h: 480px');
});
test('DeviceModel css_variables attribute merges --screen-w and --screen-h from dimensions when not set', function (): void {
$deviceModel = DeviceModel::factory()->create([
'width' => 800,
'height' => 480,
'css_variables' => null,
]);
$vars = $deviceModel->css_variables;
expect($vars)->toHaveKey('--screen-w', '800px');
expect($vars)->toHaveKey('--screen-h', '480px');
});
test('DeviceModel css_variables attribute does not override --screen-w and --screen-h when already set', function (): void {
$deviceModel = DeviceModel::factory()->create([
'width' => 800,
'height' => 480,
'css_variables' => [
'--screen-w' => '1200px',
'--screen-h' => '900px',
],
]);
$vars = $deviceModel->css_variables;
expect($vars['--screen-w'])->toBe('1200px');
expect($vars['--screen-h'])->toBe('900px');
});
test('DeviceModel css_variables attribute fills only missing --screen-w or --screen-h from dimensions', function (): void {
$deviceModel = DeviceModel::factory()->create([
'width' => 800,
'height' => 480,
'css_variables' => [
'--screen-w' => '640px',
],
]);
$vars = $deviceModel->css_variables;
expect($vars['--screen-w'])->toBe('640px');
expect($vars['--screen-h'])->toBe('480px');
});
test('DeviceModel css_variables attribute returns raw vars when strategy is not v2', function (): void {
Config::set('app.puppeteer_window_size_strategy', 'v1');
$deviceModel = DeviceModel::factory()->create([
'width' => 800,
'height' => 480,
'css_variables' => ['--custom' => 'value'],
]);
$vars = $deviceModel->css_variables;
expect($vars)->toBe(['--custom' => 'value']);
});
test('device model css_variables are available via device relationship for rendering', function (): void {
Config::set('app.puppeteer_window_size_strategy', 'v2');
$deviceModel = DeviceModel::factory()->create([
'width' => 800,
'height' => 480,
'css_variables' => null,
]);
$device = Device::factory()->create([
'device_model_id' => $deviceModel->id,
]);
$device->load('deviceModel');
$vars = $device->deviceModel?->css_variables ?? [];
expect($vars)->toHaveKey('--screen-w', '800px');
expect($vars)->toHaveKey('--screen-h', '480px');
});