From 315fbac2617570fa9f0b723f48aee75fcad62ef9 Mon Sep 17 00:00:00 2001 From: Benjamin Nussbaum Date: Wed, 29 Oct 2025 22:26:28 +0100 Subject: [PATCH 1/3] chore: update dependencies --- composer.lock | 68 +++++++++++++++++++++++++-------------------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/composer.lock b/composer.lock index 8ac79b1..e1f0d77 100644 --- a/composer.lock +++ b/composer.lock @@ -62,16 +62,16 @@ }, { "name": "aws/aws-sdk-php", - "version": "3.359.0", + "version": "3.359.1", "source": { "type": "git", "url": "https://github.com/aws/aws-sdk-php.git", - "reference": "7231e7c309d6262855289511d6ee124fafbe664f" + "reference": "40543e3993fc5094094ac9f9bdc4434bf81cca2d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/7231e7c309d6262855289511d6ee124fafbe664f", - "reference": "7231e7c309d6262855289511d6ee124fafbe664f", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/40543e3993fc5094094ac9f9bdc4434bf81cca2d", + "reference": "40543e3993fc5094094ac9f9bdc4434bf81cca2d", "shasum": "" }, "require": { @@ -153,9 +153,9 @@ "support": { "forum": "https://github.com/aws/aws-sdk-php/discussions", "issues": "https://github.com/aws/aws-sdk-php/issues", - "source": "https://github.com/aws/aws-sdk-php/tree/3.359.0" + "source": "https://github.com/aws/aws-sdk-php/tree/3.359.1" }, - "time": "2025-10-29T00:06:16+00:00" + "time": "2025-10-29T20:13:06+00:00" }, { "name": "bnussbau/laravel-trmnl-blade", @@ -1618,16 +1618,16 @@ }, { "name": "laravel/framework", - "version": "v12.36.0", + "version": "v12.36.1", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "5247c8f4139e5266cd42bbe13de131604becd7e1" + "reference": "cad110d7685fbab990a6bb8184d0cfd847d7c4d8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/5247c8f4139e5266cd42bbe13de131604becd7e1", - "reference": "5247c8f4139e5266cd42bbe13de131604becd7e1", + "url": "https://api.github.com/repos/laravel/framework/zipball/cad110d7685fbab990a6bb8184d0cfd847d7c4d8", + "reference": "cad110d7685fbab990a6bb8184d0cfd847d7c4d8", "shasum": "" }, "require": { @@ -1833,7 +1833,7 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2025-10-28T15:13:16+00:00" + "time": "2025-10-29T14:20:57+00:00" }, { "name": "laravel/prompts", @@ -2984,21 +2984,21 @@ }, { "name": "livewire/volt", - "version": "v1.7.2", + "version": "v1.8.0", "source": { "type": "git", "url": "https://github.com/livewire/volt.git", - "reference": "91ba934e72bbd162442840862959ade24dbe728a" + "reference": "2d9783a340d612d32f4ffd38070780ca7d7e9205" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/livewire/volt/zipball/91ba934e72bbd162442840862959ade24dbe728a", - "reference": "91ba934e72bbd162442840862959ade24dbe728a", + "url": "https://api.github.com/repos/livewire/volt/zipball/2d9783a340d612d32f4ffd38070780ca7d7e9205", + "reference": "2d9783a340d612d32f4ffd38070780ca7d7e9205", "shasum": "" }, "require": { "laravel/framework": "^10.38.2|^11.0|^12.0", - "livewire/livewire": "^3.6.1", + "livewire/livewire": "^3.6.1|^4.0", "php": "^8.1" }, "require-dev": { @@ -3052,7 +3052,7 @@ "issues": "https://github.com/livewire/volt/issues", "source": "https://github.com/livewire/volt" }, - "time": "2025-08-06T15:40:50+00:00" + "time": "2025-10-29T15:52:35+00:00" }, { "name": "maennchen/zipstream-php", @@ -7734,16 +7734,16 @@ }, { "name": "webmozart/assert", - "version": "1.12.0", + "version": "1.12.1", "source": { "type": "git", "url": "https://github.com/webmozarts/assert.git", - "reference": "541057574806f942c94662b817a50f63f7345360" + "reference": "9be6926d8b485f55b9229203f962b51ed377ba68" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozarts/assert/zipball/541057574806f942c94662b817a50f63f7345360", - "reference": "541057574806f942c94662b817a50f63f7345360", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/9be6926d8b485f55b9229203f962b51ed377ba68", + "reference": "9be6926d8b485f55b9229203f962b51ed377ba68", "shasum": "" }, "require": { @@ -7786,9 +7786,9 @@ ], "support": { "issues": "https://github.com/webmozarts/assert/issues", - "source": "https://github.com/webmozarts/assert/tree/1.12.0" + "source": "https://github.com/webmozarts/assert/tree/1.12.1" }, - "time": "2025-10-20T12:43:39+00:00" + "time": "2025-10-29T15:56:20+00:00" }, { "name": "wnx/sidecar-browsershot", @@ -8523,16 +8523,16 @@ }, { "name": "laravel/mcp", - "version": "v0.3.1", + "version": "v0.3.2", "source": { "type": "git", "url": "https://github.com/laravel/mcp.git", - "reference": "13f80d68bb409a0952142a2433f14d536a7940e3" + "reference": "dc722a4c388f172365dec70461f0413ac366f360" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/mcp/zipball/13f80d68bb409a0952142a2433f14d536a7940e3", - "reference": "13f80d68bb409a0952142a2433f14d536a7940e3", + "url": "https://api.github.com/repos/laravel/mcp/zipball/dc722a4c388f172365dec70461f0413ac366f360", + "reference": "dc722a4c388f172365dec70461f0413ac366f360", "shasum": "" }, "require": { @@ -8592,7 +8592,7 @@ "issues": "https://github.com/laravel/mcp/issues", "source": "https://github.com/laravel/mcp" }, - "time": "2025-10-24T15:36:29+00:00" + "time": "2025-10-29T14:26:01+00:00" }, { "name": "laravel/pail", @@ -10470,16 +10470,16 @@ }, { "name": "rector/rector", - "version": "2.2.6", + "version": "2.2.7", "source": { "type": "git", "url": "https://github.com/rectorphp/rector.git", - "reference": "5c5bbc956b9a056a26cb593379253104b7ed9c2d" + "reference": "022038537838bc8a4e526af86c2d6e38eaeff7ef" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/rectorphp/rector/zipball/5c5bbc956b9a056a26cb593379253104b7ed9c2d", - "reference": "5c5bbc956b9a056a26cb593379253104b7ed9c2d", + "url": "https://api.github.com/repos/rectorphp/rector/zipball/022038537838bc8a4e526af86c2d6e38eaeff7ef", + "reference": "022038537838bc8a4e526af86c2d6e38eaeff7ef", "shasum": "" }, "require": { @@ -10518,7 +10518,7 @@ ], "support": { "issues": "https://github.com/rectorphp/rector/issues", - "source": "https://github.com/rectorphp/rector/tree/2.2.6" + "source": "https://github.com/rectorphp/rector/tree/2.2.7" }, "funding": [ { @@ -10526,7 +10526,7 @@ "type": "github" } ], - "time": "2025-10-27T11:35:56+00:00" + "time": "2025-10-29T15:46:12+00:00" }, { "name": "sebastian/cli-parser", From 38e1b6f2a6711c4fda64a3153a63f731c2432eb9 Mon Sep 17 00:00:00 2001 From: Benjamin Nussbaum Date: Wed, 29 Oct 2025 22:35:16 +0100 Subject: [PATCH 2/3] fix(#103): apply dithering if requested by markup --- app/Services/ImageGenerationService.php | 31 +++++++++++++++++++++++++ composer.json | 2 +- composer.lock | 14 +++++------ 3 files changed, 39 insertions(+), 8 deletions(-) diff --git a/app/Services/ImageGenerationService.php b/app/Services/ImageGenerationService.php index f513e05..76be3bb 100644 --- a/app/Services/ImageGenerationService.php +++ b/app/Services/ImageGenerationService.php @@ -72,6 +72,12 @@ class ImageGenerationService ->offsetY($imageSettings['offset_y']) ->outputPath($outputPath); + // Apply dithering if requested by markup + $shouldDither = self::markupContainsDitherImage($markup); + if ($shouldDither) { + $imageStage->dither(); + } + (new TrmnlPipeline())->pipe($browserStage) ->pipe($imageStage) ->process(); @@ -209,6 +215,31 @@ class ImageGenerationService }; } + /** + * Detect whether the provided HTML markup contains an tag with class "image-dither". + */ + private static function markupContainsDitherImage(string $markup): bool + { + if (mb_trim($markup) === '') { + return false; + } + + // Find (or with single quotes) and inspect class tokens + $imgWithClassPattern = '/]*\bclass\s*=\s*(["\'])(.*?)\1[^>]*>/i'; + if (! preg_match_all($imgWithClassPattern, $markup, $matches)) { + return false; + } + + foreach ($matches[2] as $classValue) { + // Look for class token 'image-dither' or 'image--dither' + if (preg_match('/(?:^|\s)image--?dither(?:\s|$)/', $classValue)) { + return true; + } + } + + return false; + } + public static function cleanupFolder(): void { $activeDeviceImageUuids = Device::pluck('current_screen_image')->filter()->toArray(); diff --git a/composer.json b/composer.json index 0d3fc42..79306ce 100644 --- a/composer.json +++ b/composer.json @@ -15,7 +15,7 @@ "ext-simplexml": "*", "ext-zip": "*", "bnussbau/laravel-trmnl-blade": "2.0.*", - "bnussbau/trmnl-pipeline-php": "^0.3.0", + "bnussbau/trmnl-pipeline-php": "^0.4.0", "keepsuit/laravel-liquid": "^0.5.2", "laravel/framework": "^12.1", "laravel/sanctum": "^4.0", diff --git a/composer.lock b/composer.lock index e1f0d77..2f54904 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "d6d201899ecc5b1243e9a481c22c5732", + "content-hash": "3d743ce4dc2742c59ed6f9cc8ed36e04", "packages": [ { "name": "aws/aws-crt-php", @@ -243,16 +243,16 @@ }, { "name": "bnussbau/trmnl-pipeline-php", - "version": "0.3.2", + "version": "0.4.0", "source": { "type": "git", "url": "https://github.com/bnussbau/trmnl-pipeline-php.git", - "reference": "ead26a45ac919e3f2a5f4a448508a919cd3258d3" + "reference": "b58b937f36e55aa7cbd4859cbe7a902bf1050bf8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/bnussbau/trmnl-pipeline-php/zipball/ead26a45ac919e3f2a5f4a448508a919cd3258d3", - "reference": "ead26a45ac919e3f2a5f4a448508a919cd3258d3", + "url": "https://api.github.com/repos/bnussbau/trmnl-pipeline-php/zipball/b58b937f36e55aa7cbd4859cbe7a902bf1050bf8", + "reference": "b58b937f36e55aa7cbd4859cbe7a902bf1050bf8", "shasum": "" }, "require": { @@ -294,7 +294,7 @@ ], "support": { "issues": "https://github.com/bnussbau/trmnl-pipeline-php/issues", - "source": "https://github.com/bnussbau/trmnl-pipeline-php/tree/0.3.2" + "source": "https://github.com/bnussbau/trmnl-pipeline-php/tree/0.4.0" }, "funding": [ { @@ -310,7 +310,7 @@ "type": "github" } ], - "time": "2025-10-17T12:12:40+00:00" + "time": "2025-10-30T11:52:17+00:00" }, { "name": "brick/math", From 80e2e8058a3b3a00aad10ae309eb2d8b4c9818dd Mon Sep 17 00:00:00 2001 From: Benjamin Nussbaum Date: Thu, 30 Oct 2025 15:13:50 +0100 Subject: [PATCH 3/3] fix(#103): add recipe options to remove bleed margin and enable dark mode --- app/Models/Plugin.php | 11 +++++-- ...o_bleed_and_dark_mode_to_plugins_table.php | 32 +++++++++++++++++++ .../views/livewire/plugins/recipe.blade.php | 24 ++++++++++++++ .../views/trmnl-layouts/single.blade.php | 2 +- 4 files changed, 66 insertions(+), 3 deletions(-) create mode 100644 database/migrations/2025_10_30_144500_add_no_bleed_and_dark_mode_to_plugins_table.php diff --git a/app/Models/Plugin.php b/app/Models/Plugin.php index dfeb757..3c279d7 100644 --- a/app/Models/Plugin.php +++ b/app/Models/Plugin.php @@ -38,6 +38,8 @@ class Plugin extends Model 'markup_language' => 'string', 'configuration' => 'json', 'configuration_template' => 'json', + 'no_bleed' => 'boolean', + 'dark_mode' => 'boolean', ]; protected static function boot() @@ -407,8 +409,8 @@ class Plugin extends Model 'plugin_settings' => [ 'instance_name' => $this->name, 'strategy' => $this->data_strategy, - 'dark_mode' => 'no', - 'no_screen_padding' => 'no', + 'dark_mode' => $this->dark_mode ? 'yes' : 'no', + 'no_screen_padding' => $this->no_bleed ? 'yes' : 'no', 'polling_headers' => $this->polling_header, 'polling_url' => $this->polling_url, 'custom_fields_values' => [ @@ -432,6 +434,8 @@ class Plugin extends Model return view('trmnl-layouts.single', [ 'colorDepth' => $device?->colorDepth(), 'deviceVariant' => $device?->deviceVariant() ?? 'og', + 'noBleed' => $this->no_bleed, + 'darkMode' => $this->dark_mode, 'scaleLevel' => $device?->scaleLevel(), 'slot' => $renderedContent, ])->render(); @@ -441,6 +445,7 @@ class Plugin extends Model 'mashupLayout' => $this->getPreviewMashupLayoutForSize($size), 'colorDepth' => $device?->colorDepth(), 'deviceVariant' => $device?->deviceVariant() ?? 'og', + 'darkMode' => $this->dark_mode, 'scaleLevel' => $device?->scaleLevel(), 'slot' => $renderedContent, ])->render(); @@ -455,6 +460,8 @@ class Plugin extends Model return view('trmnl-layouts.single', [ 'colorDepth' => $device?->colorDepth(), 'deviceVariant' => $device?->deviceVariant() ?? 'og', + 'noBleed' => $this->no_bleed, + 'darkMode' => $this->dark_mode, 'scaleLevel' => $device?->scaleLevel(), 'slot' => view($this->render_markup_view, [ 'size' => $size, diff --git a/database/migrations/2025_10_30_144500_add_no_bleed_and_dark_mode_to_plugins_table.php b/database/migrations/2025_10_30_144500_add_no_bleed_and_dark_mode_to_plugins_table.php new file mode 100644 index 0000000..f7329c8 --- /dev/null +++ b/database/migrations/2025_10_30_144500_add_no_bleed_and_dark_mode_to_plugins_table.php @@ -0,0 +1,32 @@ +boolean('no_bleed')->default(false)->after('configuration_template'); + } + if (! Schema::hasColumn('plugins', 'dark_mode')) { + $table->boolean('dark_mode')->default(false)->after('no_bleed'); + } + }); + } + + public function down(): void + { + Schema::table('plugins', function (Blueprint $table): void { + if (Schema::hasColumn('plugins', 'dark_mode')) { + $table->dropColumn('dark_mode'); + } + if (Schema::hasColumn('plugins', 'no_bleed')) { + $table->dropColumn('no_bleed'); + } + }); + } +}; diff --git a/resources/views/livewire/plugins/recipe.blade.php b/resources/views/livewire/plugins/recipe.blade.php index 832124f..c8907cf 100644 --- a/resources/views/livewire/plugins/recipe.blade.php +++ b/resources/views/livewire/plugins/recipe.blade.php @@ -15,6 +15,8 @@ new class extends Component { public string|null $markup_language; public string $name; + public bool $no_bleed = false; + public bool $dark_mode = false; public int $data_stale_minutes; public string $data_strategy; public string|null $polling_url; @@ -66,6 +68,10 @@ new class extends Component { $this->markup_language = $this->plugin->markup_language ?? 'blade'; } + // Initialize screen settings from the model + $this->no_bleed = (bool) ($this->plugin->no_bleed ?? false); + $this->dark_mode = (bool) ($this->plugin->dark_mode ?? false); + $this->fillformFields(); $this->data_payload_updated_at = $this->plugin->data_payload_updated_at; } @@ -109,6 +115,8 @@ new class extends Component { 'device_weekdays' => 'array', 'device_active_from' => 'array', 'device_active_until' => 'array', + 'no_bleed' => 'boolean', + 'dark_mode' => 'boolean', ]; public function editSettings() @@ -1024,6 +1032,22 @@ HTML; Enter static JSON data in the Data Payload field. @endif +
+ Screen Settings +
+ + +
+
+
Save diff --git a/resources/views/trmnl-layouts/single.blade.php b/resources/views/trmnl-layouts/single.blade.php index 17ffe43..c6d6499 100644 --- a/resources/views/trmnl-layouts/single.blade.php +++ b/resources/views/trmnl-layouts/single.blade.php @@ -14,7 +14,7 @@ {!! $slot !!} @else - + {!! $slot !!} @endif