mirror of
https://github.com/usetrmnl/byos_laravel.git
synced 2026-03-15 12:53:29 +00:00
Compare commits
No commits in common. "35ca55a90b8fe722173d6f558c7a14f38c90f3f1" and "06e684227e123e4b6bb34cfa52b68c689ea7ff33" have entirely different histories.
35ca55a90b
...
06e684227e
20 changed files with 174 additions and 765 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -41,4 +41,3 @@ yarn-error.log
|
||||||
/.opencode
|
/.opencode
|
||||||
/build.sh
|
/build.sh
|
||||||
/.junie
|
/.junie
|
||||||
/.agents
|
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ ENV TRMNL_LIQUID_ENABLED=1
|
||||||
# Switch to the root user so we can do root things
|
# Switch to the root user so we can do root things
|
||||||
USER root
|
USER root
|
||||||
|
|
||||||
COPY --chown=www-data:www-data --from=bnussbau/trmnl-liquid-cli:0.2.0 /usr/local/bin/trmnl-liquid-cli /usr/local/bin/
|
COPY --chown=www-data:www-data --from=bnussbau/trmnl-liquid-cli:0.1.0 /usr/local/bin/trmnl-liquid-cli /usr/local/bin/
|
||||||
|
|
||||||
# Set the working directory
|
# Set the working directory
|
||||||
WORKDIR /var/www/html
|
WORKDIR /var/www/html
|
||||||
|
|
|
||||||
|
|
@ -122,7 +122,6 @@ php artisan db:seed --class=ExampleRecipesSeeder
|
||||||
| `REGISTRATION_ENABLED` | Allow user registration via Webinterface | 1 |
|
| `REGISTRATION_ENABLED` | Allow user registration via Webinterface | 1 |
|
||||||
| `SSL_MODE` | SSL Mode, if not using a Reverse Proxy ([docs](https://serversideup.net/open-source/docker-php/docs/customizing-the-image/configuring-ssl)) | `off` |
|
| `SSL_MODE` | SSL Mode, if not using a Reverse Proxy ([docs](https://serversideup.net/open-source/docker-php/docs/customizing-the-image/configuring-ssl)) | `off` |
|
||||||
| `FORCE_HTTPS` | If your server handles SSL termination, enforce HTTPS. | 0 |
|
| `FORCE_HTTPS` | If your server handles SSL termination, enforce HTTPS. | 0 |
|
||||||
| `TRUSTED_PROXIES` | If your server handles SSL termination, allow mixed mode. e.g. `"172.0.0.0/8"` or `*` | null |
|
|
||||||
| `PHP_OPCACHE_ENABLE` | Enable PHP Opcache | 0 |
|
| `PHP_OPCACHE_ENABLE` | Enable PHP Opcache | 0 |
|
||||||
| `TRMNL_IMAGE_URL_TIMEOUT` | How long TRMNL waits for a response on the display endpoint. (sec) | 30 |
|
| `TRMNL_IMAGE_URL_TIMEOUT` | How long TRMNL waits for a response on the display endpoint. (sec) | 30 |
|
||||||
| `APP_TIMEZONE` | Default timezone, which will be used by the PHP date functions | UTC |
|
| `APP_TIMEZONE` | Default timezone, which will be used by the PHP date functions | UTC |
|
||||||
|
|
|
||||||
|
|
@ -60,14 +60,8 @@ class Plugin extends Model
|
||||||
});
|
});
|
||||||
|
|
||||||
static::updating(function ($model): void {
|
static::updating(function ($model): void {
|
||||||
// Reset image cache when any markup changes
|
// Reset image cache when markup changes
|
||||||
if ($model->isDirty([
|
if ($model->isDirty('render_markup')) {
|
||||||
'render_markup',
|
|
||||||
'render_markup_half_horizontal',
|
|
||||||
'render_markup_half_vertical',
|
|
||||||
'render_markup_quadrant',
|
|
||||||
'render_markup_shared',
|
|
||||||
])) {
|
|
||||||
$model->current_image = null;
|
$model->current_image = null;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -427,9 +421,7 @@ class Plugin extends Model
|
||||||
throw new InvalidArgumentException('Render method is only applicable for recipe plugins.');
|
throw new InvalidArgumentException('Render method is only applicable for recipe plugins.');
|
||||||
}
|
}
|
||||||
|
|
||||||
$markup = $this->getMarkupForSize($size);
|
if ($this->render_markup) {
|
||||||
|
|
||||||
if ($markup) {
|
|
||||||
$renderedContent = '';
|
$renderedContent = '';
|
||||||
|
|
||||||
if ($this->markup_language === 'liquid') {
|
if ($this->markup_language === 'liquid') {
|
||||||
|
|
@ -479,7 +471,7 @@ class Plugin extends Model
|
||||||
// Check if external renderer should be used
|
// Check if external renderer should be used
|
||||||
if ($this->preferred_renderer === 'trmnl-liquid' && config('services.trmnl.liquid_enabled')) {
|
if ($this->preferred_renderer === 'trmnl-liquid' && config('services.trmnl.liquid_enabled')) {
|
||||||
// Use external Ruby renderer - pass raw template without preprocessing
|
// Use external Ruby renderer - pass raw template without preprocessing
|
||||||
$renderedContent = $this->renderWithExternalLiquidRenderer($markup, $context);
|
$renderedContent = $this->renderWithExternalLiquidRenderer($this->render_markup, $context);
|
||||||
} else {
|
} else {
|
||||||
// Use PHP keepsuit/liquid renderer
|
// Use PHP keepsuit/liquid renderer
|
||||||
// Create a custom environment with inline templates support
|
// Create a custom environment with inline templates support
|
||||||
|
|
@ -501,14 +493,14 @@ class Plugin extends Model
|
||||||
$environment->tagRegistry->register(TemplateTag::class);
|
$environment->tagRegistry->register(TemplateTag::class);
|
||||||
|
|
||||||
// Apply Liquid replacements (including 'with' syntax conversion)
|
// Apply Liquid replacements (including 'with' syntax conversion)
|
||||||
$processedMarkup = $this->applyLiquidReplacements($markup);
|
$processedMarkup = $this->applyLiquidReplacements($this->render_markup);
|
||||||
|
|
||||||
$template = $environment->parseString($processedMarkup);
|
$template = $environment->parseString($processedMarkup);
|
||||||
$liquidContext = $environment->newRenderContext(data: $context);
|
$liquidContext = $environment->newRenderContext(data: $context);
|
||||||
$renderedContent = $template->render($liquidContext);
|
$renderedContent = $template->render($liquidContext);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$renderedContent = Blade::render($markup, [
|
$renderedContent = Blade::render($this->render_markup, [
|
||||||
'size' => $size,
|
'size' => $size,
|
||||||
'data' => $this->data_payload,
|
'data' => $this->data_payload,
|
||||||
'config' => $this->configuration ?? [],
|
'config' => $this->configuration ?? [],
|
||||||
|
|
@ -589,30 +581,6 @@ class Plugin extends Model
|
||||||
return $this->configuration[$key] ?? $default;
|
return $this->configuration[$key] ?? $default;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the appropriate markup for a given size, including shared prepending logic
|
|
||||||
*
|
|
||||||
* @param string $size The layout size (full, half_horizontal, half_vertical, quadrant)
|
|
||||||
* @return string|null The markup code for the given size, with shared prepended if available
|
|
||||||
*/
|
|
||||||
public function getMarkupForSize(string $size): ?string
|
|
||||||
{
|
|
||||||
$markup = match ($size) {
|
|
||||||
'full' => $this->render_markup,
|
|
||||||
'half_horizontal' => $this->render_markup_half_horizontal ?? $this->render_markup,
|
|
||||||
'half_vertical' => $this->render_markup_half_vertical ?? $this->render_markup,
|
|
||||||
'quadrant' => $this->render_markup_quadrant ?? $this->render_markup,
|
|
||||||
default => $this->render_markup,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Prepend shared markup if it exists
|
|
||||||
if ($markup && $this->render_markup_shared) {
|
|
||||||
$markup = $this->render_markup_shared."\n".$markup;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $markup;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getPreviewMashupLayoutForSize(string $size): string
|
public function getPreviewMashupLayoutForSize(string $size): string
|
||||||
{
|
{
|
||||||
return match ($size) {
|
return match ($size) {
|
||||||
|
|
|
||||||
|
|
@ -51,35 +51,17 @@ class PluginExportService
|
||||||
$settings = $this->generateSettingsYaml($plugin);
|
$settings = $this->generateSettingsYaml($plugin);
|
||||||
$settingsYaml = Yaml::dump($settings, 10, 2, Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK);
|
$settingsYaml = Yaml::dump($settings, 10, 2, Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK);
|
||||||
File::put($tempDir.'/settings.yml', $settingsYaml);
|
File::put($tempDir.'/settings.yml', $settingsYaml);
|
||||||
|
// Generate full template content
|
||||||
|
$fullTemplate = $this->generateFullTemplate($plugin);
|
||||||
$extension = $plugin->markup_language === 'liquid' ? 'liquid' : 'blade.php';
|
$extension = $plugin->markup_language === 'liquid' ? 'liquid' : 'blade.php';
|
||||||
|
|
||||||
// Export full template if it exists
|
|
||||||
if ($plugin->render_markup) {
|
|
||||||
$fullTemplate = $this->generateLayoutTemplate($plugin->render_markup);
|
|
||||||
File::put($tempDir.'/full.'.$extension, $fullTemplate);
|
File::put($tempDir.'/full.'.$extension, $fullTemplate);
|
||||||
|
// Generate shared.liquid if needed (for liquid templates)
|
||||||
|
if ($plugin->markup_language === 'liquid') {
|
||||||
|
$sharedTemplate = $this->generateSharedTemplate();
|
||||||
|
/** @phpstan-ignore-next-line */
|
||||||
|
if ($sharedTemplate) {
|
||||||
|
File::put($tempDir.'/shared.liquid', $sharedTemplate);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Export layout-specific templates if they exist
|
|
||||||
if ($plugin->render_markup_half_horizontal) {
|
|
||||||
$halfHorizontalTemplate = $this->generateLayoutTemplate($plugin->render_markup_half_horizontal);
|
|
||||||
File::put($tempDir.'/half_horizontal.'.$extension, $halfHorizontalTemplate);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($plugin->render_markup_half_vertical) {
|
|
||||||
$halfVerticalTemplate = $this->generateLayoutTemplate($plugin->render_markup_half_vertical);
|
|
||||||
File::put($tempDir.'/half_vertical.'.$extension, $halfVerticalTemplate);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($plugin->render_markup_quadrant) {
|
|
||||||
$quadrantTemplate = $this->generateLayoutTemplate($plugin->render_markup_quadrant);
|
|
||||||
File::put($tempDir.'/quadrant.'.$extension, $quadrantTemplate);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Export shared template if it exists
|
|
||||||
if ($plugin->render_markup_shared) {
|
|
||||||
$sharedTemplate = $this->generateLayoutTemplate($plugin->render_markup_shared);
|
|
||||||
File::put($tempDir.'/shared.'.$extension, $sharedTemplate);
|
|
||||||
}
|
}
|
||||||
// Create ZIP file
|
// Create ZIP file
|
||||||
$zipPath = $tempDir.'/plugin_'.$plugin->trmnlp_id.'.zip';
|
$zipPath = $tempDir.'/plugin_'.$plugin->trmnlp_id.'.zip';
|
||||||
|
|
@ -142,21 +124,29 @@ class PluginExportService
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate template content from markup, removing wrapper divs if present
|
* Generate the full template content
|
||||||
*/
|
*/
|
||||||
private function generateLayoutTemplate(?string $markup): string
|
private function generateFullTemplate(Plugin $plugin): string
|
||||||
{
|
{
|
||||||
if (! $markup) {
|
$markup = $plugin->render_markup;
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove the wrapper div if it exists (it will be added during import for liquid)
|
// Remove the wrapper div if it exists (it will be added during import)
|
||||||
$markup = preg_replace('/^<div class="view view--\{\{ size \}\}">\s*/', '', $markup);
|
$markup = preg_replace('/^<div class="view view--\{\{ size \}\}">\s*/', '', $markup);
|
||||||
$markup = preg_replace('/\s*<\/div>\s*$/', '', $markup);
|
$markup = preg_replace('/\s*<\/div>\s*$/', '', $markup);
|
||||||
|
|
||||||
return mb_trim($markup);
|
return mb_trim($markup);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate the shared template content (for liquid templates)
|
||||||
|
*/
|
||||||
|
private function generateSharedTemplate(): null
|
||||||
|
{
|
||||||
|
// For now, we don't have a way to store shared templates separately
|
||||||
|
// TODO - add support for shared templates
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a directory and its contents to a ZIP file
|
* Add a directory and its contents to a ZIP file
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -93,59 +93,37 @@ class PluginImportService
|
||||||
$settings = Yaml::parse($settingsYaml);
|
$settings = Yaml::parse($settingsYaml);
|
||||||
$this->validateYAML($settings);
|
$this->validateYAML($settings);
|
||||||
|
|
||||||
// Determine markup language from the first available file
|
// Determine which template file to use and read its content
|
||||||
|
$templatePath = null;
|
||||||
$markupLanguage = 'blade';
|
$markupLanguage = 'blade';
|
||||||
$firstTemplatePath = $filePaths['fullLiquidPath']
|
|
||||||
?? ($filePaths['halfHorizontalLiquidPath'] ?? null)
|
|
||||||
?? ($filePaths['halfVerticalLiquidPath'] ?? null)
|
|
||||||
?? ($filePaths['quadrantLiquidPath'] ?? null)
|
|
||||||
?? ($filePaths['sharedLiquidPath'] ?? null)
|
|
||||||
?? ($filePaths['sharedBladePath'] ?? null);
|
|
||||||
|
|
||||||
if ($firstTemplatePath && pathinfo((string) $firstTemplatePath, PATHINFO_EXTENSION) === 'liquid') {
|
if ($filePaths['fullLiquidPath']) {
|
||||||
$markupLanguage = 'liquid';
|
$templatePath = $filePaths['fullLiquidPath'];
|
||||||
|
$fullLiquid = File::get($templatePath);
|
||||||
|
|
||||||
|
// Prepend shared.liquid or shared.blade.php content if available
|
||||||
|
if ($filePaths['sharedLiquidPath'] && File::exists($filePaths['sharedLiquidPath'])) {
|
||||||
|
$sharedLiquid = File::get($filePaths['sharedLiquidPath']);
|
||||||
|
$fullLiquid = $sharedLiquid."\n".$fullLiquid;
|
||||||
|
} elseif ($filePaths['sharedBladePath'] && File::exists($filePaths['sharedBladePath'])) {
|
||||||
|
$sharedBlade = File::get($filePaths['sharedBladePath']);
|
||||||
|
$fullLiquid = $sharedBlade."\n".$fullLiquid;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read full markup (don't prepend shared - it will be prepended at render time)
|
// Check if the file ends with .liquid to set markup language
|
||||||
$fullLiquid = null;
|
if (pathinfo((string) $templatePath, PATHINFO_EXTENSION) === 'liquid') {
|
||||||
if (isset($filePaths['fullLiquidPath']) && $filePaths['fullLiquidPath']) {
|
$markupLanguage = 'liquid';
|
||||||
$fullLiquid = File::get($filePaths['fullLiquidPath']);
|
|
||||||
if ($markupLanguage === 'liquid') {
|
|
||||||
$fullLiquid = '<div class="view view--{{ size }}">'."\n".$fullLiquid."\n".'</div>';
|
$fullLiquid = '<div class="view view--{{ size }}">'."\n".$fullLiquid."\n".'</div>';
|
||||||
}
|
}
|
||||||
}
|
} elseif ($filePaths['sharedLiquidPath']) {
|
||||||
|
$templatePath = $filePaths['sharedLiquidPath'];
|
||||||
// Read shared markup separately
|
$fullLiquid = File::get($templatePath);
|
||||||
$sharedMarkup = null;
|
$markupLanguage = 'liquid';
|
||||||
if (isset($filePaths['sharedLiquidPath']) && $filePaths['sharedLiquidPath'] && File::exists($filePaths['sharedLiquidPath'])) {
|
$fullLiquid = '<div class="view view--{{ size }}">'."\n".$fullLiquid."\n".'</div>';
|
||||||
$sharedMarkup = File::get($filePaths['sharedLiquidPath']);
|
} elseif ($filePaths['sharedBladePath']) {
|
||||||
} elseif (isset($filePaths['sharedBladePath']) && $filePaths['sharedBladePath'] && File::exists($filePaths['sharedBladePath'])) {
|
$templatePath = $filePaths['sharedBladePath'];
|
||||||
$sharedMarkup = File::get($filePaths['sharedBladePath']);
|
$fullLiquid = File::get($templatePath);
|
||||||
}
|
$markupLanguage = 'blade';
|
||||||
|
|
||||||
// Read layout-specific markups
|
|
||||||
$halfHorizontalMarkup = null;
|
|
||||||
if (isset($filePaths['halfHorizontalLiquidPath']) && $filePaths['halfHorizontalLiquidPath'] && File::exists($filePaths['halfHorizontalLiquidPath'])) {
|
|
||||||
$halfHorizontalMarkup = File::get($filePaths['halfHorizontalLiquidPath']);
|
|
||||||
if ($markupLanguage === 'liquid') {
|
|
||||||
$halfHorizontalMarkup = '<div class="view view--{{ size }}">'."\n".$halfHorizontalMarkup."\n".'</div>';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$halfVerticalMarkup = null;
|
|
||||||
if (isset($filePaths['halfVerticalLiquidPath']) && $filePaths['halfVerticalLiquidPath'] && File::exists($filePaths['halfVerticalLiquidPath'])) {
|
|
||||||
$halfVerticalMarkup = File::get($filePaths['halfVerticalLiquidPath']);
|
|
||||||
if ($markupLanguage === 'liquid') {
|
|
||||||
$halfVerticalMarkup = '<div class="view view--{{ size }}">'."\n".$halfVerticalMarkup."\n".'</div>';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$quadrantMarkup = null;
|
|
||||||
if (isset($filePaths['quadrantLiquidPath']) && $filePaths['quadrantLiquidPath'] && File::exists($filePaths['quadrantLiquidPath'])) {
|
|
||||||
$quadrantMarkup = File::get($filePaths['quadrantLiquidPath']);
|
|
||||||
if ($markupLanguage === 'liquid') {
|
|
||||||
$quadrantMarkup = '<div class="view view--{{ size }}">'."\n".$quadrantMarkup."\n".'</div>';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure custom_fields is properly formatted
|
// Ensure custom_fields is properly formatted
|
||||||
|
|
@ -182,10 +160,6 @@ class PluginImportService
|
||||||
'polling_body' => $settings['polling_body'] ?? null,
|
'polling_body' => $settings['polling_body'] ?? null,
|
||||||
'markup_language' => $markupLanguage,
|
'markup_language' => $markupLanguage,
|
||||||
'render_markup' => $fullLiquid ?? null,
|
'render_markup' => $fullLiquid ?? null,
|
||||||
'render_markup_half_horizontal' => $halfHorizontalMarkup,
|
|
||||||
'render_markup_half_vertical' => $halfVerticalMarkup,
|
|
||||||
'render_markup_quadrant' => $quadrantMarkup,
|
|
||||||
'render_markup_shared' => $sharedMarkup,
|
|
||||||
'configuration_template' => $configurationTemplate,
|
'configuration_template' => $configurationTemplate,
|
||||||
'data_payload' => json_decode($settings['static_data'] ?? '{}', true),
|
'data_payload' => json_decode($settings['static_data'] ?? '{}', true),
|
||||||
]);
|
]);
|
||||||
|
|
@ -272,59 +246,37 @@ class PluginImportService
|
||||||
$settings = Yaml::parse($settingsYaml);
|
$settings = Yaml::parse($settingsYaml);
|
||||||
$this->validateYAML($settings);
|
$this->validateYAML($settings);
|
||||||
|
|
||||||
// Determine markup language from the first available file
|
// Determine which template file to use and read its content
|
||||||
|
$templatePath = null;
|
||||||
$markupLanguage = 'blade';
|
$markupLanguage = 'blade';
|
||||||
$firstTemplatePath = $filePaths['fullLiquidPath']
|
|
||||||
?? ($filePaths['halfHorizontalLiquidPath'] ?? null)
|
|
||||||
?? ($filePaths['halfVerticalLiquidPath'] ?? null)
|
|
||||||
?? ($filePaths['quadrantLiquidPath'] ?? null)
|
|
||||||
?? ($filePaths['sharedLiquidPath'] ?? null)
|
|
||||||
?? ($filePaths['sharedBladePath'] ?? null);
|
|
||||||
|
|
||||||
if ($firstTemplatePath && pathinfo((string) $firstTemplatePath, PATHINFO_EXTENSION) === 'liquid') {
|
if ($filePaths['fullLiquidPath']) {
|
||||||
$markupLanguage = 'liquid';
|
$templatePath = $filePaths['fullLiquidPath'];
|
||||||
|
$fullLiquid = File::get($templatePath);
|
||||||
|
|
||||||
|
// Prepend shared.liquid or shared.blade.php content if available
|
||||||
|
if ($filePaths['sharedLiquidPath'] && File::exists($filePaths['sharedLiquidPath'])) {
|
||||||
|
$sharedLiquid = File::get($filePaths['sharedLiquidPath']);
|
||||||
|
$fullLiquid = $sharedLiquid."\n".$fullLiquid;
|
||||||
|
} elseif ($filePaths['sharedBladePath'] && File::exists($filePaths['sharedBladePath'])) {
|
||||||
|
$sharedBlade = File::get($filePaths['sharedBladePath']);
|
||||||
|
$fullLiquid = $sharedBlade."\n".$fullLiquid;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read full markup (don't prepend shared - it will be prepended at render time)
|
// Check if the file ends with .liquid to set markup language
|
||||||
$fullLiquid = null;
|
if (pathinfo((string) $templatePath, PATHINFO_EXTENSION) === 'liquid') {
|
||||||
if (isset($filePaths['fullLiquidPath']) && $filePaths['fullLiquidPath']) {
|
$markupLanguage = 'liquid';
|
||||||
$fullLiquid = File::get($filePaths['fullLiquidPath']);
|
|
||||||
if ($markupLanguage === 'liquid') {
|
|
||||||
$fullLiquid = '<div class="view view--{{ size }}">'."\n".$fullLiquid."\n".'</div>';
|
$fullLiquid = '<div class="view view--{{ size }}">'."\n".$fullLiquid."\n".'</div>';
|
||||||
}
|
}
|
||||||
}
|
} elseif ($filePaths['sharedLiquidPath']) {
|
||||||
|
$templatePath = $filePaths['sharedLiquidPath'];
|
||||||
// Read shared markup separately
|
$fullLiquid = File::get($templatePath);
|
||||||
$sharedMarkup = null;
|
$markupLanguage = 'liquid';
|
||||||
if (isset($filePaths['sharedLiquidPath']) && $filePaths['sharedLiquidPath'] && File::exists($filePaths['sharedLiquidPath'])) {
|
$fullLiquid = '<div class="view view--{{ size }}">'."\n".$fullLiquid."\n".'</div>';
|
||||||
$sharedMarkup = File::get($filePaths['sharedLiquidPath']);
|
} elseif ($filePaths['sharedBladePath']) {
|
||||||
} elseif (isset($filePaths['sharedBladePath']) && $filePaths['sharedBladePath'] && File::exists($filePaths['sharedBladePath'])) {
|
$templatePath = $filePaths['sharedBladePath'];
|
||||||
$sharedMarkup = File::get($filePaths['sharedBladePath']);
|
$fullLiquid = File::get($templatePath);
|
||||||
}
|
$markupLanguage = 'blade';
|
||||||
|
|
||||||
// Read layout-specific markups
|
|
||||||
$halfHorizontalMarkup = null;
|
|
||||||
if (isset($filePaths['halfHorizontalLiquidPath']) && $filePaths['halfHorizontalLiquidPath'] && File::exists($filePaths['halfHorizontalLiquidPath'])) {
|
|
||||||
$halfHorizontalMarkup = File::get($filePaths['halfHorizontalLiquidPath']);
|
|
||||||
if ($markupLanguage === 'liquid') {
|
|
||||||
$halfHorizontalMarkup = '<div class="view view--{{ size }}">'."\n".$halfHorizontalMarkup."\n".'</div>';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$halfVerticalMarkup = null;
|
|
||||||
if (isset($filePaths['halfVerticalLiquidPath']) && $filePaths['halfVerticalLiquidPath'] && File::exists($filePaths['halfVerticalLiquidPath'])) {
|
|
||||||
$halfVerticalMarkup = File::get($filePaths['halfVerticalLiquidPath']);
|
|
||||||
if ($markupLanguage === 'liquid') {
|
|
||||||
$halfVerticalMarkup = '<div class="view view--{{ size }}">'."\n".$halfVerticalMarkup."\n".'</div>';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$quadrantMarkup = null;
|
|
||||||
if (isset($filePaths['quadrantLiquidPath']) && $filePaths['quadrantLiquidPath'] && File::exists($filePaths['quadrantLiquidPath'])) {
|
|
||||||
$quadrantMarkup = File::get($filePaths['quadrantLiquidPath']);
|
|
||||||
if ($markupLanguage === 'liquid') {
|
|
||||||
$quadrantMarkup = '<div class="view view--{{ size }}">'."\n".$quadrantMarkup."\n".'</div>';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure custom_fields is properly formatted
|
// Ensure custom_fields is properly formatted
|
||||||
|
|
@ -370,10 +322,6 @@ class PluginImportService
|
||||||
'polling_body' => $settings['polling_body'] ?? null,
|
'polling_body' => $settings['polling_body'] ?? null,
|
||||||
'markup_language' => $markupLanguage,
|
'markup_language' => $markupLanguage,
|
||||||
'render_markup' => $fullLiquid ?? null,
|
'render_markup' => $fullLiquid ?? null,
|
||||||
'render_markup_half_horizontal' => $halfHorizontalMarkup,
|
|
||||||
'render_markup_half_vertical' => $halfVerticalMarkup,
|
|
||||||
'render_markup_quadrant' => $quadrantMarkup,
|
|
||||||
'render_markup_shared' => $sharedMarkup,
|
|
||||||
'configuration_template' => $configurationTemplate,
|
'configuration_template' => $configurationTemplate,
|
||||||
'data_payload' => json_decode($settings['static_data'] ?? '{}', true),
|
'data_payload' => json_decode($settings['static_data'] ?? '{}', true),
|
||||||
'preferred_renderer' => $preferredRenderer,
|
'preferred_renderer' => $preferredRenderer,
|
||||||
|
|
@ -409,9 +357,6 @@ class PluginImportService
|
||||||
$fullLiquidPath = null;
|
$fullLiquidPath = null;
|
||||||
$sharedLiquidPath = null;
|
$sharedLiquidPath = null;
|
||||||
$sharedBladePath = null;
|
$sharedBladePath = null;
|
||||||
$halfHorizontalLiquidPath = null;
|
|
||||||
$halfVerticalLiquidPath = null;
|
|
||||||
$quadrantLiquidPath = null;
|
|
||||||
|
|
||||||
// If zipEntryPath is specified, look for files in that specific directory first
|
// If zipEntryPath is specified, look for files in that specific directory first
|
||||||
if ($zipEntryPath) {
|
if ($zipEntryPath) {
|
||||||
|
|
@ -432,25 +377,6 @@ class PluginImportService
|
||||||
} elseif (File::exists($targetDir.'/shared.blade.php')) {
|
} elseif (File::exists($targetDir.'/shared.blade.php')) {
|
||||||
$sharedBladePath = $targetDir.'/shared.blade.php';
|
$sharedBladePath = $targetDir.'/shared.blade.php';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for layout-specific files
|
|
||||||
if (File::exists($targetDir.'/half_horizontal.liquid')) {
|
|
||||||
$halfHorizontalLiquidPath = $targetDir.'/half_horizontal.liquid';
|
|
||||||
} elseif (File::exists($targetDir.'/half_horizontal.blade.php')) {
|
|
||||||
$halfHorizontalLiquidPath = $targetDir.'/half_horizontal.blade.php';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (File::exists($targetDir.'/half_vertical.liquid')) {
|
|
||||||
$halfVerticalLiquidPath = $targetDir.'/half_vertical.liquid';
|
|
||||||
} elseif (File::exists($targetDir.'/half_vertical.blade.php')) {
|
|
||||||
$halfVerticalLiquidPath = $targetDir.'/half_vertical.blade.php';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (File::exists($targetDir.'/quadrant.liquid')) {
|
|
||||||
$quadrantLiquidPath = $targetDir.'/quadrant.liquid';
|
|
||||||
} elseif (File::exists($targetDir.'/quadrant.blade.php')) {
|
|
||||||
$quadrantLiquidPath = $targetDir.'/quadrant.blade.php';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if files are in src subdirectory of target directory
|
// Check if files are in src subdirectory of target directory
|
||||||
|
|
@ -468,25 +394,6 @@ class PluginImportService
|
||||||
} elseif (File::exists($targetDir.'/src/shared.blade.php')) {
|
} elseif (File::exists($targetDir.'/src/shared.blade.php')) {
|
||||||
$sharedBladePath = $targetDir.'/src/shared.blade.php';
|
$sharedBladePath = $targetDir.'/src/shared.blade.php';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for layout-specific files in src
|
|
||||||
if (File::exists($targetDir.'/src/half_horizontal.liquid')) {
|
|
||||||
$halfHorizontalLiquidPath = $targetDir.'/src/half_horizontal.liquid';
|
|
||||||
} elseif (File::exists($targetDir.'/src/half_horizontal.blade.php')) {
|
|
||||||
$halfHorizontalLiquidPath = $targetDir.'/src/half_horizontal.blade.php';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (File::exists($targetDir.'/src/half_vertical.liquid')) {
|
|
||||||
$halfVerticalLiquidPath = $targetDir.'/src/half_vertical.liquid';
|
|
||||||
} elseif (File::exists($targetDir.'/src/half_vertical.blade.php')) {
|
|
||||||
$halfVerticalLiquidPath = $targetDir.'/src/half_vertical.blade.php';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (File::exists($targetDir.'/src/quadrant.liquid')) {
|
|
||||||
$quadrantLiquidPath = $targetDir.'/src/quadrant.liquid';
|
|
||||||
} elseif (File::exists($targetDir.'/src/quadrant.blade.php')) {
|
|
||||||
$quadrantLiquidPath = $targetDir.'/src/quadrant.blade.php';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we found the required files in the target directory, return them
|
// If we found the required files in the target directory, return them
|
||||||
|
|
@ -518,25 +425,6 @@ class PluginImportService
|
||||||
} elseif (File::exists($tempDir.'/src/shared.blade.php')) {
|
} elseif (File::exists($tempDir.'/src/shared.blade.php')) {
|
||||||
$sharedBladePath = $tempDir.'/src/shared.blade.php';
|
$sharedBladePath = $tempDir.'/src/shared.blade.php';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for layout-specific files
|
|
||||||
if (File::exists($tempDir.'/src/half_horizontal.liquid')) {
|
|
||||||
$halfHorizontalLiquidPath = $tempDir.'/src/half_horizontal.liquid';
|
|
||||||
} elseif (File::exists($tempDir.'/src/half_horizontal.blade.php')) {
|
|
||||||
$halfHorizontalLiquidPath = $tempDir.'/src/half_horizontal.blade.php';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (File::exists($tempDir.'/src/half_vertical.liquid')) {
|
|
||||||
$halfVerticalLiquidPath = $tempDir.'/src/half_vertical.liquid';
|
|
||||||
} elseif (File::exists($tempDir.'/src/half_vertical.blade.php')) {
|
|
||||||
$halfVerticalLiquidPath = $tempDir.'/src/half_vertical.blade.php';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (File::exists($tempDir.'/src/quadrant.liquid')) {
|
|
||||||
$quadrantLiquidPath = $tempDir.'/src/quadrant.liquid';
|
|
||||||
} elseif (File::exists($tempDir.'/src/quadrant.blade.php')) {
|
|
||||||
$quadrantLiquidPath = $tempDir.'/src/quadrant.blade.php';
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// Search for the files in the extracted directory structure
|
// Search for the files in the extracted directory structure
|
||||||
$directories = new RecursiveDirectoryIterator($tempDir, RecursiveDirectoryIterator::SKIP_DOTS);
|
$directories = new RecursiveDirectoryIterator($tempDir, RecursiveDirectoryIterator::SKIP_DOTS);
|
||||||
|
|
@ -554,12 +442,6 @@ class PluginImportService
|
||||||
$sharedLiquidPath = $filepath;
|
$sharedLiquidPath = $filepath;
|
||||||
} elseif ($filename === 'shared.blade.php') {
|
} elseif ($filename === 'shared.blade.php') {
|
||||||
$sharedBladePath = $filepath;
|
$sharedBladePath = $filepath;
|
||||||
} elseif ($filename === 'half_horizontal.liquid' || $filename === 'half_horizontal.blade.php') {
|
|
||||||
$halfHorizontalLiquidPath = $filepath;
|
|
||||||
} elseif ($filename === 'half_vertical.liquid' || $filename === 'half_vertical.blade.php') {
|
|
||||||
$halfVerticalLiquidPath = $filepath;
|
|
||||||
} elseif ($filename === 'quadrant.liquid' || $filename === 'quadrant.blade.php') {
|
|
||||||
$quadrantLiquidPath = $filepath;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -603,25 +485,6 @@ class PluginImportService
|
||||||
$sharedBladePath = $newSrcDir.'/shared.blade.php';
|
$sharedBladePath = $newSrcDir.'/shared.blade.php';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy layout-specific files if they exist
|
|
||||||
if ($halfHorizontalLiquidPath) {
|
|
||||||
$extension = pathinfo((string) $halfHorizontalLiquidPath, PATHINFO_EXTENSION);
|
|
||||||
File::copy($halfHorizontalLiquidPath, $newSrcDir.'/half_horizontal.'.$extension);
|
|
||||||
$halfHorizontalLiquidPath = $newSrcDir.'/half_horizontal.'.$extension;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($halfVerticalLiquidPath) {
|
|
||||||
$extension = pathinfo((string) $halfVerticalLiquidPath, PATHINFO_EXTENSION);
|
|
||||||
File::copy($halfVerticalLiquidPath, $newSrcDir.'/half_vertical.'.$extension);
|
|
||||||
$halfVerticalLiquidPath = $newSrcDir.'/half_vertical.'.$extension;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($quadrantLiquidPath) {
|
|
||||||
$extension = pathinfo((string) $quadrantLiquidPath, PATHINFO_EXTENSION);
|
|
||||||
File::copy($quadrantLiquidPath, $newSrcDir.'/quadrant.'.$extension);
|
|
||||||
$quadrantLiquidPath = $newSrcDir.'/quadrant.'.$extension;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update the paths
|
// Update the paths
|
||||||
$settingsYamlPath = $newSrcDir.'/settings.yml';
|
$settingsYamlPath = $newSrcDir.'/settings.yml';
|
||||||
}
|
}
|
||||||
|
|
@ -633,9 +496,6 @@ class PluginImportService
|
||||||
'fullLiquidPath' => $fullLiquidPath,
|
'fullLiquidPath' => $fullLiquidPath,
|
||||||
'sharedLiquidPath' => $sharedLiquidPath,
|
'sharedLiquidPath' => $sharedLiquidPath,
|
||||||
'sharedBladePath' => $sharedBladePath,
|
'sharedBladePath' => $sharedBladePath,
|
||||||
'halfHorizontalLiquidPath' => $halfHorizontalLiquidPath,
|
|
||||||
'halfVerticalLiquidPath' => $halfVerticalLiquidPath,
|
|
||||||
'quadrantLiquidPath' => $quadrantLiquidPath,
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
"ext-imagick": "*",
|
"ext-imagick": "*",
|
||||||
"ext-simplexml": "*",
|
"ext-simplexml": "*",
|
||||||
"ext-zip": "*",
|
"ext-zip": "*",
|
||||||
"bnussbau/laravel-trmnl-blade": "2.1.1",
|
"bnussbau/laravel-trmnl-blade": "2.2.*",
|
||||||
"bnussbau/trmnl-pipeline-php": "^0.6.0",
|
"bnussbau/trmnl-pipeline-php": "^0.6.0",
|
||||||
"keepsuit/laravel-liquid": "^0.5.2",
|
"keepsuit/laravel-liquid": "^0.5.2",
|
||||||
"laravel/fortify": "^1.30",
|
"laravel/fortify": "^1.30",
|
||||||
|
|
|
||||||
74
composer.lock
generated
74
composer.lock
generated
|
|
@ -4,7 +4,7 @@
|
||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "60a7e51edd8408cffdb901e4a1c1684a",
|
"content-hash": "581bacf794841fc11c540e152c704d16",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "aws/aws-crt-php",
|
"name": "aws/aws-crt-php",
|
||||||
|
|
@ -62,16 +62,16 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "aws/aws-sdk-php",
|
"name": "aws/aws-sdk-php",
|
||||||
"version": "3.369.29",
|
"version": "3.369.27",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/aws/aws-sdk-php.git",
|
"url": "https://github.com/aws/aws-sdk-php.git",
|
||||||
"reference": "068195b2980cf5cf4ade2515850d461186db3310"
|
"reference": "f844afab2a74eb3cf881970a9c31de460510eb74"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/068195b2980cf5cf4ade2515850d461186db3310",
|
"url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/f844afab2a74eb3cf881970a9c31de460510eb74",
|
||||||
"reference": "068195b2980cf5cf4ade2515850d461186db3310",
|
"reference": "f844afab2a74eb3cf881970a9c31de460510eb74",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
|
@ -153,9 +153,9 @@
|
||||||
"support": {
|
"support": {
|
||||||
"forum": "https://github.com/aws/aws-sdk-php/discussions",
|
"forum": "https://github.com/aws/aws-sdk-php/discussions",
|
||||||
"issues": "https://github.com/aws/aws-sdk-php/issues",
|
"issues": "https://github.com/aws/aws-sdk-php/issues",
|
||||||
"source": "https://github.com/aws/aws-sdk-php/tree/3.369.29"
|
"source": "https://github.com/aws/aws-sdk-php/tree/3.369.27"
|
||||||
},
|
},
|
||||||
"time": "2026-02-06T19:08:50+00:00"
|
"time": "2026-02-04T19:07:08+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "bacon/bacon-qr-code",
|
"name": "bacon/bacon-qr-code",
|
||||||
|
|
@ -214,16 +214,16 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "bnussbau/laravel-trmnl-blade",
|
"name": "bnussbau/laravel-trmnl-blade",
|
||||||
"version": "2.1.1",
|
"version": "2.2.1",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/bnussbau/laravel-trmnl-blade.git",
|
"url": "https://github.com/bnussbau/laravel-trmnl-blade.git",
|
||||||
"reference": "6ad96eba917ebc30ebe550e6fce4a995e94f6b35"
|
"reference": "6db8a82a15ccedcaaffd3b37d0d337d276a26669"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/bnussbau/laravel-trmnl-blade/zipball/6ad96eba917ebc30ebe550e6fce4a995e94f6b35",
|
"url": "https://api.github.com/repos/bnussbau/laravel-trmnl-blade/zipball/6db8a82a15ccedcaaffd3b37d0d337d276a26669",
|
||||||
"reference": "6ad96eba917ebc30ebe550e6fce4a995e94f6b35",
|
"reference": "6db8a82a15ccedcaaffd3b37d0d337d276a26669",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
|
@ -278,7 +278,7 @@
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/bnussbau/laravel-trmnl-blade/issues",
|
"issues": "https://github.com/bnussbau/laravel-trmnl-blade/issues",
|
||||||
"source": "https://github.com/bnussbau/laravel-trmnl-blade/tree/2.1.1"
|
"source": "https://github.com/bnussbau/laravel-trmnl-blade/tree/2.2.1"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
|
|
@ -294,7 +294,7 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2026-01-29T20:40:42+00:00"
|
"time": "2026-02-05T17:57:37+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "bnussbau/trmnl-pipeline-php",
|
"name": "bnussbau/trmnl-pipeline-php",
|
||||||
|
|
@ -3194,16 +3194,16 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "livewire/livewire",
|
"name": "livewire/livewire",
|
||||||
"version": "v4.1.3",
|
"version": "v4.1.2",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/livewire/livewire.git",
|
"url": "https://github.com/livewire/livewire.git",
|
||||||
"reference": "69c871cb15fb95f10cda5acd1ee7e63cd3c494c8"
|
"reference": "8adef21f35f4ffa87fd2f3655b350236df0c39a8"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/livewire/livewire/zipball/69c871cb15fb95f10cda5acd1ee7e63cd3c494c8",
|
"url": "https://api.github.com/repos/livewire/livewire/zipball/8adef21f35f4ffa87fd2f3655b350236df0c39a8",
|
||||||
"reference": "69c871cb15fb95f10cda5acd1ee7e63cd3c494c8",
|
"reference": "8adef21f35f4ffa87fd2f3655b350236df0c39a8",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
|
@ -3258,7 +3258,7 @@
|
||||||
"description": "A front-end framework for Laravel.",
|
"description": "A front-end framework for Laravel.",
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/livewire/livewire/issues",
|
"issues": "https://github.com/livewire/livewire/issues",
|
||||||
"source": "https://github.com/livewire/livewire/tree/v4.1.3"
|
"source": "https://github.com/livewire/livewire/tree/v4.1.2"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
|
|
@ -3266,7 +3266,7 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2026-02-06T12:19:55+00:00"
|
"time": "2026-02-03T03:01:29+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "maennchen/zipstream-php",
|
"name": "maennchen/zipstream-php",
|
||||||
|
|
@ -9066,16 +9066,16 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "laravel/boost",
|
"name": "laravel/boost",
|
||||||
"version": "v2.1.1",
|
"version": "v2.0.6",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/laravel/boost.git",
|
"url": "https://github.com/laravel/boost.git",
|
||||||
"reference": "1c7d6f44c96937a961056778b9143218b1183302"
|
"reference": "1e1cb76e8e87ca3dd3c3d64deccbc97f4de38215"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/laravel/boost/zipball/1c7d6f44c96937a961056778b9143218b1183302",
|
"url": "https://api.github.com/repos/laravel/boost/zipball/1e1cb76e8e87ca3dd3c3d64deccbc97f4de38215",
|
||||||
"reference": "1c7d6f44c96937a961056778b9143218b1183302",
|
"reference": "1e1cb76e8e87ca3dd3c3d64deccbc97f4de38215",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
|
@ -9128,7 +9128,7 @@
|
||||||
"issues": "https://github.com/laravel/boost/issues",
|
"issues": "https://github.com/laravel/boost/issues",
|
||||||
"source": "https://github.com/laravel/boost"
|
"source": "https://github.com/laravel/boost"
|
||||||
},
|
},
|
||||||
"time": "2026-02-06T10:41:29+00:00"
|
"time": "2026-02-04T10:10:48+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "laravel/mcp",
|
"name": "laravel/mcp",
|
||||||
|
|
@ -10484,16 +10484,16 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "phpunit/php-code-coverage",
|
"name": "phpunit/php-code-coverage",
|
||||||
"version": "12.5.3",
|
"version": "12.5.2",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
|
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
|
||||||
"reference": "b015312f28dd75b75d3422ca37dff2cd1a565e8d"
|
"reference": "4a9739b51cbcb355f6e95659612f92e282a7077b"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/b015312f28dd75b75d3422ca37dff2cd1a565e8d",
|
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/4a9739b51cbcb355f6e95659612f92e282a7077b",
|
||||||
"reference": "b015312f28dd75b75d3422ca37dff2cd1a565e8d",
|
"reference": "4a9739b51cbcb355f6e95659612f92e282a7077b",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
|
@ -10549,7 +10549,7 @@
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
|
"issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
|
||||||
"security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy",
|
"security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy",
|
||||||
"source": "https://github.com/sebastianbergmann/php-code-coverage/tree/12.5.3"
|
"source": "https://github.com/sebastianbergmann/php-code-coverage/tree/12.5.2"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
|
|
@ -10569,7 +10569,7 @@
|
||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2026-02-06T06:01:44+00:00"
|
"time": "2025-12-24T07:03:04+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "phpunit/php-file-iterator",
|
"name": "phpunit/php-file-iterator",
|
||||||
|
|
@ -10935,21 +10935,21 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "rector/rector",
|
"name": "rector/rector",
|
||||||
"version": "2.3.6",
|
"version": "2.3.5",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/rectorphp/rector.git",
|
"url": "https://github.com/rectorphp/rector.git",
|
||||||
"reference": "ca9ebb81d280cd362ea39474dabd42679e32ca6b"
|
"reference": "9442f4037de6a5347ae157fe8e6c7cda9d909070"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/rectorphp/rector/zipball/ca9ebb81d280cd362ea39474dabd42679e32ca6b",
|
"url": "https://api.github.com/repos/rectorphp/rector/zipball/9442f4037de6a5347ae157fe8e6c7cda9d909070",
|
||||||
"reference": "ca9ebb81d280cd362ea39474dabd42679e32ca6b",
|
"reference": "9442f4037de6a5347ae157fe8e6c7cda9d909070",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"php": "^7.4|^8.0",
|
"php": "^7.4|^8.0",
|
||||||
"phpstan/phpstan": "^2.1.38"
|
"phpstan/phpstan": "^2.1.36"
|
||||||
},
|
},
|
||||||
"conflict": {
|
"conflict": {
|
||||||
"rector/rector-doctrine": "*",
|
"rector/rector-doctrine": "*",
|
||||||
|
|
@ -10983,7 +10983,7 @@
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/rectorphp/rector/issues",
|
"issues": "https://github.com/rectorphp/rector/issues",
|
||||||
"source": "https://github.com/rectorphp/rector/tree/2.3.6"
|
"source": "https://github.com/rectorphp/rector/tree/2.3.5"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
|
|
@ -10991,7 +10991,7 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2026-02-06T14:25:06+00:00"
|
"time": "2026-01-28T15:22:48+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "sebastian/cli-parser",
|
"name": "sebastian/cli-parser",
|
||||||
|
|
|
||||||
|
|
@ -1,38 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
use Illuminate\Database\Migrations\Migration;
|
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
|
||||||
use Illuminate\Support\Facades\Schema;
|
|
||||||
|
|
||||||
return new class extends Migration
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Run the migrations.
|
|
||||||
*/
|
|
||||||
public function up(): void
|
|
||||||
{
|
|
||||||
Schema::table('plugins', function (Blueprint $table) {
|
|
||||||
$table->text('render_markup_half_horizontal')->nullable()->after('render_markup');
|
|
||||||
$table->text('render_markup_half_vertical')->nullable()->after('render_markup_half_horizontal');
|
|
||||||
$table->text('render_markup_quadrant')->nullable()->after('render_markup_half_vertical');
|
|
||||||
$table->text('render_markup_shared')->nullable()->after('render_markup_quadrant');
|
|
||||||
$table->text('transform_code')->nullable()->after('render_markup_shared');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reverse the migrations.
|
|
||||||
*/
|
|
||||||
public function down(): void
|
|
||||||
{
|
|
||||||
Schema::table('plugins', function (Blueprint $table) {
|
|
||||||
$table->dropColumn([
|
|
||||||
'render_markup_half_horizontal',
|
|
||||||
'render_markup_half_vertical',
|
|
||||||
'render_markup_quadrant',
|
|
||||||
'render_markup_shared',
|
|
||||||
'transform_code',
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
use App\Jobs\FetchDeviceModelsJob;
|
|
||||||
use App\Models\DeviceModel;
|
use App\Models\DeviceModel;
|
||||||
use App\Models\DevicePalette;
|
use App\Models\DevicePalette;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
|
|
@ -67,14 +66,6 @@ new class extends Component
|
||||||
|
|
||||||
public $viewingDeviceModelId;
|
public $viewingDeviceModelId;
|
||||||
|
|
||||||
public function updateFromApi(): void
|
|
||||||
{
|
|
||||||
FetchDeviceModelsJob::dispatchSync();
|
|
||||||
$this->deviceModels = DeviceModel::all();
|
|
||||||
$this->devicePalettes = DevicePalette::all();
|
|
||||||
session()->flash('message', 'Device models updated from API.');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function openDeviceModelModal(?string $deviceModelId = null, bool $viewOnly = false): void
|
public function openDeviceModelModal(?string $deviceModelId = null, bool $viewOnly = false): void
|
||||||
{
|
{
|
||||||
if ($deviceModelId) {
|
if ($deviceModelId) {
|
||||||
|
|
@ -238,17 +229,9 @@ new class extends Component
|
||||||
</flux:menu>
|
</flux:menu>
|
||||||
</flux:dropdown>
|
</flux:dropdown>
|
||||||
</div>
|
</div>
|
||||||
<flux:button.group>
|
|
||||||
<flux:modal.trigger name="device-model-modal">
|
<flux:modal.trigger name="device-model-modal">
|
||||||
<flux:button wire:click="openDeviceModelModal()" icon="plus" variant="primary">Add Device Model</flux:button>
|
<flux:button wire:click="openDeviceModelModal()" icon="plus" variant="primary">Add Device Model</flux:button>
|
||||||
</flux:modal.trigger>
|
</flux:modal.trigger>
|
||||||
<flux:dropdown>
|
|
||||||
<flux:button icon="chevron-down" variant="primary"></flux:button>
|
|
||||||
<flux:menu>
|
|
||||||
<flux:menu.item icon="arrow-path" wire:click="updateFromApi">Update from Models API</flux:menu.item>
|
|
||||||
</flux:menu>
|
|
||||||
</flux:dropdown>
|
|
||||||
</flux:button.group>
|
|
||||||
</div>
|
</div>
|
||||||
@if (session()->has('message'))
|
@if (session()->has('message'))
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
use App\Jobs\FetchDeviceModelsJob;
|
|
||||||
use App\Models\DevicePalette;
|
use App\Models\DevicePalette;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
|
|
||||||
|
|
@ -59,13 +58,6 @@ new class extends Component
|
||||||
|
|
||||||
public $viewingDevicePaletteId;
|
public $viewingDevicePaletteId;
|
||||||
|
|
||||||
public function updateFromApi(): void
|
|
||||||
{
|
|
||||||
FetchDeviceModelsJob::dispatchSync();
|
|
||||||
$this->devicePalettes = DevicePalette::all();
|
|
||||||
session()->flash('message', 'Device palettes updated from API.');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function openDevicePaletteModal(?string $devicePaletteId = null, bool $viewOnly = false): void
|
public function openDevicePaletteModal(?string $devicePaletteId = null, bool $viewOnly = false): void
|
||||||
{
|
{
|
||||||
if ($devicePaletteId) {
|
if ($devicePaletteId) {
|
||||||
|
|
@ -210,17 +202,9 @@ new class extends Component
|
||||||
</flux:menu>
|
</flux:menu>
|
||||||
</flux:dropdown>
|
</flux:dropdown>
|
||||||
</div>
|
</div>
|
||||||
<flux:button.group>
|
|
||||||
<flux:modal.trigger name="device-palette-modal">
|
<flux:modal.trigger name="device-palette-modal">
|
||||||
<flux:button wire:click="openDevicePaletteModal()" icon="plus" variant="primary">Add Device Palette</flux:button>
|
<flux:button wire:click="openDevicePaletteModal()" icon="plus" variant="primary">Add Device Palette</flux:button>
|
||||||
</flux:modal.trigger>
|
</flux:modal.trigger>
|
||||||
<flux:dropdown>
|
|
||||||
<flux:button icon="chevron-down" variant="primary"></flux:button>
|
|
||||||
<flux:menu>
|
|
||||||
<flux:menu.item icon="arrow-path" wire:click="updateFromApi">Update from API</flux:menu.item>
|
|
||||||
</flux:menu>
|
|
||||||
</flux:dropdown>
|
|
||||||
</flux:button.group>
|
|
||||||
</div>
|
</div>
|
||||||
@if (session()->has('message'))
|
@if (session()->has('message'))
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
|
|
|
||||||
|
|
@ -31,10 +31,6 @@ new class extends Component
|
||||||
|
|
||||||
public $device_model_id;
|
public $device_model_id;
|
||||||
|
|
||||||
public $is_mirror = false;
|
|
||||||
|
|
||||||
public $mirror_device_id = null;
|
|
||||||
|
|
||||||
// Signal to device to use high compatibility approaches when redrawing content
|
// Signal to device to use high compatibility approaches when redrawing content
|
||||||
public $maximum_compatibility = false;
|
public $maximum_compatibility = false;
|
||||||
|
|
||||||
|
|
@ -102,8 +98,6 @@ new class extends Component
|
||||||
$this->sleep_mode_from = optional($device->sleep_mode_from)->format('H:i');
|
$this->sleep_mode_from = optional($device->sleep_mode_from)->format('H:i');
|
||||||
$this->sleep_mode_to = optional($device->sleep_mode_to)->format('H:i');
|
$this->sleep_mode_to = optional($device->sleep_mode_to)->format('H:i');
|
||||||
$this->special_function = $device->special_function;
|
$this->special_function = $device->special_function;
|
||||||
$this->is_mirror = $device->mirror_device_id !== null;
|
|
||||||
$this->mirror_device_id = $device->mirror_device_id;
|
|
||||||
|
|
||||||
return view('livewire.devices.configure', [
|
return view('livewire.devices.configure', [
|
||||||
'image' => ($current_image_uuid) ? url($current_image_path) : null,
|
'image' => ($current_image_uuid) ? url($current_image_path) : null,
|
||||||
|
|
@ -151,7 +145,6 @@ new class extends Component
|
||||||
'rotate' => 'required|integer|min:0|max:359',
|
'rotate' => 'required|integer|min:0|max:359',
|
||||||
'image_format' => 'required|string',
|
'image_format' => 'required|string',
|
||||||
'device_model_id' => 'nullable|exists:device_models,id',
|
'device_model_id' => 'nullable|exists:device_models,id',
|
||||||
'mirror_device_id' => 'required_if:is_mirror,true',
|
|
||||||
'maximum_compatibility' => 'boolean',
|
'maximum_compatibility' => 'boolean',
|
||||||
'sleep_mode_enabled' => 'boolean',
|
'sleep_mode_enabled' => 'boolean',
|
||||||
'sleep_mode_from' => 'nullable|date_format:H:i',
|
'sleep_mode_from' => 'nullable|date_format:H:i',
|
||||||
|
|
@ -159,13 +152,6 @@ new class extends Component
|
||||||
'special_function' => 'nullable|string',
|
'special_function' => 'nullable|string',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if ($this->is_mirror) {
|
|
||||||
$mirrorDevice = auth()->user()->devices()->find($this->mirror_device_id);
|
|
||||||
abort_unless($mirrorDevice, 403, 'Invalid mirror device selected');
|
|
||||||
abort_if($mirrorDevice->mirror_device_id !== null, 403, 'Cannot mirror a device that is already a mirror device');
|
|
||||||
abort_if((int) $this->mirror_device_id === (int) $this->device->id, 403, 'Device cannot mirror itself');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert empty string to null for custom selection
|
// Convert empty string to null for custom selection
|
||||||
$deviceModelId = empty($this->device_model_id) ? null : $this->device_model_id;
|
$deviceModelId = empty($this->device_model_id) ? null : $this->device_model_id;
|
||||||
|
|
||||||
|
|
@ -179,7 +165,6 @@ new class extends Component
|
||||||
'rotate' => $this->rotate,
|
'rotate' => $this->rotate,
|
||||||
'image_format' => $this->image_format,
|
'image_format' => $this->image_format,
|
||||||
'device_model_id' => $deviceModelId,
|
'device_model_id' => $deviceModelId,
|
||||||
'mirror_device_id' => $this->is_mirror ? $this->mirror_device_id : null,
|
|
||||||
'maximum_compatibility' => $this->maximum_compatibility,
|
'maximum_compatibility' => $this->maximum_compatibility,
|
||||||
'sleep_mode_enabled' => $this->sleep_mode_enabled,
|
'sleep_mode_enabled' => $this->sleep_mode_enabled,
|
||||||
'sleep_mode_from' => $this->sleep_mode_from,
|
'sleep_mode_from' => $this->sleep_mode_from,
|
||||||
|
|
@ -448,18 +433,6 @@ new class extends Component
|
||||||
@endforeach
|
@endforeach
|
||||||
</flux:select>
|
</flux:select>
|
||||||
|
|
||||||
<flux:checkbox wire:model.live="is_mirror" label="Mirrors Device"/>
|
|
||||||
@if($is_mirror)
|
|
||||||
<flux:select wire:model="mirror_device_id" label="Select Device to Mirror">
|
|
||||||
<flux:select.option value="">Select a device</flux:select.option>
|
|
||||||
@foreach(auth()->user()->devices->where('mirror_device_id', null)->where('id', '!=', $device->id) as $mirrorOption)
|
|
||||||
<flux:select.option value="{{ $mirrorOption->id }}">
|
|
||||||
{{ $mirrorOption->name }} ({{ $mirrorOption->friendly_id }})
|
|
||||||
</flux:select.option>
|
|
||||||
@endforeach
|
|
||||||
</flux:select>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
<flux:checkbox wire:model="maximum_compatibility" label="Maximum Compatibility" description="Resolves display issues caused by certain e-ink driver chips. Disables fast refresh. TRMNL Firmware 1.6.0+ required." />
|
<flux:checkbox wire:model="maximum_compatibility" label="Maximum Compatibility" description="Resolves display issues caused by certain e-ink driver chips. Disables fast refresh. TRMNL Firmware 1.6.0+ required." />
|
||||||
|
|
||||||
@if(empty($device_model_id))
|
@if(empty($device_model_id))
|
||||||
|
|
|
||||||
|
|
@ -258,6 +258,7 @@ new class extends Component
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
<flux:heading size="sm">Limitations</flux:heading>
|
<flux:heading size="sm">Limitations</flux:heading>
|
||||||
<ul class="list-disc pl-5 mt-2">
|
<ul class="list-disc pl-5 mt-2">
|
||||||
|
<li><flux:text>Only full view will be imported; shared markup will be prepended</flux:text></li>
|
||||||
<li><flux:text>Some Liquid filters may be not supported or behave differently</flux:text></li>
|
<li><flux:text>Some Liquid filters may be not supported or behave differently</flux:text></li>
|
||||||
<li><flux:text>API responses in formats other than JSON are not yet supported</flux:text></li>
|
<li><flux:text>API responses in formats other than JSON are not yet supported</flux:text></li>
|
||||||
{{-- <ul class="list-disc pl-5 mt-2">--}}
|
{{-- <ul class="list-disc pl-5 mt-2">--}}
|
||||||
|
|
@ -311,6 +312,7 @@ new class extends Component
|
||||||
<flux:callout class="mb-4 mt-4" color="yellow">
|
<flux:callout class="mb-4 mt-4" color="yellow">
|
||||||
<flux:heading size="sm">Limitations</flux:heading>
|
<flux:heading size="sm">Limitations</flux:heading>
|
||||||
<ul class="list-disc pl-5 mt-2">
|
<ul class="list-disc pl-5 mt-2">
|
||||||
|
<li><flux:text>Only full view will be imported; shared markup will be prepended</flux:text></li>
|
||||||
<li><flux:text>Requires <span class="font-mono">trmnl-liquid-cli</span> executable.</flux:text></li>
|
<li><flux:text>Requires <span class="font-mono">trmnl-liquid-cli</span> executable.</flux:text></li>
|
||||||
<li><flux:text>API responses in formats other than <span class="font-mono">JSON</span> are not yet fully supported.</flux:text></li>
|
<li><flux:text>API responses in formats other than <span class="font-mono">JSON</span> are not yet fully supported.</flux:text></li>
|
||||||
<li><flux:text>There are limitations in payload size (Data Payload, Template).</flux:text></li>
|
<li><flux:text>There are limitations in payload size (Data Payload, Template).</flux:text></li>
|
||||||
|
|
|
||||||
|
|
@ -65,12 +65,6 @@ new class extends Component
|
||||||
|
|
||||||
public string $preview_size = 'full';
|
public string $preview_size = 'full';
|
||||||
|
|
||||||
public array $markup_layouts = [];
|
|
||||||
|
|
||||||
public array $active_tabs = [];
|
|
||||||
|
|
||||||
public string $active_tab = 'full';
|
|
||||||
|
|
||||||
public function mount(): void
|
public function mount(): void
|
||||||
{
|
{
|
||||||
abort_unless(auth()->user()->plugins->contains($this->plugin), 403);
|
abort_unless(auth()->user()->plugins->contains($this->plugin), 403);
|
||||||
|
|
@ -97,24 +91,7 @@ new class extends Component
|
||||||
$this->view_content = null;
|
$this->view_content = null;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Initialize layout markups from plugin columns
|
$this->markup_code = $this->plugin->render_markup;
|
||||||
$this->markup_layouts = [
|
|
||||||
'full' => $this->plugin->render_markup ?? '',
|
|
||||||
'half_horizontal' => $this->plugin->render_markup_half_horizontal ?? '',
|
|
||||||
'half_vertical' => $this->plugin->render_markup_half_vertical ?? '',
|
|
||||||
'quadrant' => $this->plugin->render_markup_quadrant ?? '',
|
|
||||||
'shared' => $this->plugin->render_markup_shared ?? '',
|
|
||||||
];
|
|
||||||
|
|
||||||
// Set active tabs based on which layouts have content
|
|
||||||
$this->active_tabs = ['full']; // Full is always active
|
|
||||||
foreach (['half_horizontal', 'half_vertical', 'quadrant', 'shared'] as $layout) {
|
|
||||||
if (! empty($this->markup_layouts[$layout])) {
|
|
||||||
$this->active_tabs[] = $layout;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->markup_code = $this->markup_layouts['full'];
|
|
||||||
$this->markup_language = $this->plugin->markup_language ?? 'blade';
|
$this->markup_language = $this->plugin->markup_language ?? 'blade';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -148,108 +125,12 @@ new class extends Component
|
||||||
{
|
{
|
||||||
abort_unless(auth()->user()->plugins->contains($this->plugin), 403);
|
abort_unless(auth()->user()->plugins->contains($this->plugin), 403);
|
||||||
$this->validate();
|
$this->validate();
|
||||||
|
|
||||||
// Update markup_code for the active tab
|
|
||||||
if (isset($this->markup_layouts[$this->active_tab])) {
|
|
||||||
$this->markup_layouts[$this->active_tab] = $this->markup_code ?? '';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save all layout markups to respective columns
|
|
||||||
$this->plugin->update([
|
$this->plugin->update([
|
||||||
'render_markup' => $this->markup_layouts['full'] ?? null,
|
'render_markup' => $this->markup_code ?? null,
|
||||||
'render_markup_half_horizontal' => ! empty($this->markup_layouts['half_horizontal']) ? $this->markup_layouts['half_horizontal'] : null,
|
|
||||||
'render_markup_half_vertical' => ! empty($this->markup_layouts['half_vertical']) ? $this->markup_layouts['half_vertical'] : null,
|
|
||||||
'render_markup_quadrant' => ! empty($this->markup_layouts['quadrant']) ? $this->markup_layouts['quadrant'] : null,
|
|
||||||
'render_markup_shared' => ! empty($this->markup_layouts['shared']) ? $this->markup_layouts['shared'] : null,
|
|
||||||
'markup_language' => $this->markup_language ?? null,
|
'markup_language' => $this->markup_language ?? null,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function addLayoutTab(string $layout): void
|
|
||||||
{
|
|
||||||
if (! in_array($layout, $this->active_tabs, true)) {
|
|
||||||
$this->active_tabs[] = $layout;
|
|
||||||
if (! isset($this->markup_layouts[$layout])) {
|
|
||||||
$this->markup_layouts[$layout] = '';
|
|
||||||
}
|
|
||||||
$this->switchTab($layout);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function removeLayoutTab(string $layout): void
|
|
||||||
{
|
|
||||||
if ($layout !== 'full') {
|
|
||||||
$this->active_tabs = array_values(array_filter($this->active_tabs, fn ($tab) => $tab !== $layout));
|
|
||||||
if (isset($this->markup_layouts[$layout])) {
|
|
||||||
$this->markup_layouts[$layout] = '';
|
|
||||||
}
|
|
||||||
if ($this->active_tab === $layout) {
|
|
||||||
$this->active_tab = 'full';
|
|
||||||
$this->markup_code = $this->markup_layouts['full'] ?? '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function switchTab(string $layout): void
|
|
||||||
{
|
|
||||||
if (in_array($layout, $this->active_tabs, true)) {
|
|
||||||
// Save current tab's content before switching
|
|
||||||
if (isset($this->markup_layouts[$this->active_tab])) {
|
|
||||||
$this->markup_layouts[$this->active_tab] = $this->markup_code ?? '';
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->active_tab = $layout;
|
|
||||||
$this->markup_code = $this->markup_layouts[$layout] ?? '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function toggleLayoutTab(string $layout): void
|
|
||||||
{
|
|
||||||
if ($layout === 'full') {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (in_array($layout, $this->active_tabs, true)) {
|
|
||||||
$this->removeLayoutTab($layout);
|
|
||||||
} else {
|
|
||||||
$this->addLayoutTab($layout);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getAvailableLayouts(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'half_horizontal' => 'Half Horizontal',
|
|
||||||
'half_vertical' => 'Half Vertical',
|
|
||||||
'quadrant' => 'Quadrant',
|
|
||||||
'shared' => 'Shared',
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getLayoutLabel(string $layout): string
|
|
||||||
{
|
|
||||||
return match ($layout) {
|
|
||||||
'full' => $this->getFullTabLabel(),
|
|
||||||
'half_horizontal' => 'Half Horizontal',
|
|
||||||
'half_vertical' => 'Half Vertical',
|
|
||||||
'quadrant' => 'Quadrant',
|
|
||||||
'shared' => 'Shared',
|
|
||||||
default => ucfirst($layout),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getFullTabLabel(): string
|
|
||||||
{
|
|
||||||
// Return "Full" if any layout-specific markup exists, otherwise "Responsive"
|
|
||||||
if (! empty($this->markup_layouts['half_horizontal'])
|
|
||||||
|| ! empty($this->markup_layouts['half_vertical'])
|
|
||||||
|| ! empty($this->markup_layouts['quadrant'])) {
|
|
||||||
return 'Full';
|
|
||||||
}
|
|
||||||
|
|
||||||
return 'Responsive';
|
|
||||||
}
|
|
||||||
|
|
||||||
protected array $rules = [
|
protected array $rules = [
|
||||||
'name' => 'required|string|max:255',
|
'name' => 'required|string|max:255',
|
||||||
'data_stale_minutes' => 'required|integer|min:1',
|
'data_stale_minutes' => 'required|integer|min:1',
|
||||||
|
|
@ -1137,42 +1018,9 @@ HTML;
|
||||||
@if(!$plugin->render_markup_view)
|
@if(!$plugin->render_markup_view)
|
||||||
<form wire:submit="saveMarkup">
|
<form wire:submit="saveMarkup">
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
<div>
|
|
||||||
<div class="flex items-end">
|
|
||||||
@foreach($active_tabs as $tab)
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
wire:click="switchTab('{{ $tab }}')"
|
|
||||||
class="tab-button {{ $active_tab === $tab ? 'is-active' : '' }}"
|
|
||||||
wire:key="tab-{{ $tab }}"
|
|
||||||
>
|
|
||||||
{{ $this->getLayoutLabel($tab) }}
|
|
||||||
</button>
|
|
||||||
@endforeach
|
|
||||||
|
|
||||||
<flux:dropdown>
|
|
||||||
<flux:button icon="plus" variant="ghost" size="sm" class="m-0.5"></flux:button>
|
|
||||||
<flux:menu>
|
|
||||||
@foreach($this->getAvailableLayouts() as $layout => $label)
|
|
||||||
<flux:menu.item wire:click="toggleLayoutTab('{{ $layout }}')">
|
|
||||||
<div class="flex items-center gap-2">
|
|
||||||
@if(in_array($layout, $active_tabs, true))
|
|
||||||
<flux:icon.check class="size-4" />
|
|
||||||
@else
|
|
||||||
<span class="inline-block w-4 h-4"></span>
|
|
||||||
@endif
|
|
||||||
<span>{{ $label }}</span>
|
|
||||||
</div>
|
|
||||||
</flux:menu.item>
|
|
||||||
@endforeach
|
|
||||||
</flux:menu>
|
|
||||||
</flux:dropdown>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="flex-col p-4 bg-transparent rounded-tl-none styled-container">
|
|
||||||
<flux:field>
|
<flux:field>
|
||||||
@php
|
@php
|
||||||
$textareaId = 'code-' . $plugin->id;
|
$textareaId = 'code-' . uniqid();
|
||||||
@endphp
|
@endphp
|
||||||
<flux:label>{{ $markup_language === 'liquid' ? 'Liquid Code' : 'Blade Code' }}</flux:label>
|
<flux:label>{{ $markup_language === 'liquid' ? 'Liquid Code' : 'Blade Code' }}</flux:label>
|
||||||
<flux:textarea
|
<flux:textarea
|
||||||
|
|
@ -1185,7 +1033,7 @@ HTML;
|
||||||
<div
|
<div
|
||||||
x-data="codeEditorFormComponent({
|
x-data="codeEditorFormComponent({
|
||||||
isDisabled: false,
|
isDisabled: false,
|
||||||
language: @js($markup_language === 'liquid' ? 'liquid' : 'html'),
|
language: 'liquid',
|
||||||
state: $wire.entangle('markup_code'),
|
state: $wire.entangle('markup_code'),
|
||||||
textareaId: @js($textareaId)
|
textareaId: @js($textareaId)
|
||||||
})"
|
})"
|
||||||
|
|
@ -1204,8 +1052,7 @@ HTML;
|
||||||
<div x-show="!isLoading" x-ref="editor" class="h-full"></div>
|
<div x-show="!isLoading" x-ref="editor" class="h-full"></div>
|
||||||
</div>
|
</div>
|
||||||
</flux:field>
|
</flux:field>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,6 @@ new class extends Component
|
||||||
|
|
||||||
public bool $alias = false;
|
public bool $alias = false;
|
||||||
|
|
||||||
public bool $use_trmnl_liquid_renderer = false;
|
|
||||||
|
|
||||||
public int $resetIndex = 0;
|
public int $resetIndex = 0;
|
||||||
|
|
||||||
public function mount(): void
|
public function mount(): void
|
||||||
|
|
@ -29,7 +27,6 @@ new class extends Component
|
||||||
$this->trmnlp_id = $this->plugin->trmnlp_id;
|
$this->trmnlp_id = $this->plugin->trmnlp_id;
|
||||||
$this->uuid = $this->plugin->uuid;
|
$this->uuid = $this->plugin->uuid;
|
||||||
$this->alias = $this->plugin->alias ?? false;
|
$this->alias = $this->plugin->alias ?? false;
|
||||||
$this->use_trmnl_liquid_renderer = $this->plugin->preferred_renderer === 'trmnl-liquid';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function saveTrmnlpId(): void
|
public function saveTrmnlpId(): void
|
||||||
|
|
@ -46,13 +43,11 @@ new class extends Component
|
||||||
->ignore($this->plugin->id),
|
->ignore($this->plugin->id),
|
||||||
],
|
],
|
||||||
'alias' => 'boolean',
|
'alias' => 'boolean',
|
||||||
'use_trmnl_liquid_renderer' => 'boolean',
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->plugin->update([
|
$this->plugin->update([
|
||||||
'trmnlp_id' => empty($this->trmnlp_id) ? null : $this->trmnlp_id,
|
'trmnlp_id' => empty($this->trmnlp_id) ? null : $this->trmnlp_id,
|
||||||
'alias' => $this->alias,
|
'alias' => $this->alias,
|
||||||
'preferred_renderer' => $this->use_trmnl_liquid_renderer ? 'trmnl-liquid' : null,
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
Flux::modal('trmnlp-settings')->close();
|
Flux::modal('trmnlp-settings')->close();
|
||||||
|
|
@ -88,16 +83,6 @@ new class extends Component
|
||||||
<flux:description>Enable an Alias URL for this recipe. Your server does not need to be exposed to the internet, but your device must be able to reach the URL. <a href="https://help.usetrmnl.com/en/articles/10701448-alias-plugin">Docs</a></flux:description>
|
<flux:description>Enable an Alias URL for this recipe. Your server does not need to be exposed to the internet, but your device must be able to reach the URL. <a href="https://help.usetrmnl.com/en/articles/10701448-alias-plugin">Docs</a></flux:description>
|
||||||
</flux:field>
|
</flux:field>
|
||||||
|
|
||||||
@if(config('services.trmnl.liquid_enabled') && $plugin->markup_language === 'liquid')
|
|
||||||
<flux:field>
|
|
||||||
<flux:checkbox
|
|
||||||
wire:model.live="use_trmnl_liquid_renderer"
|
|
||||||
label="Use trmnl-liquid renderer"
|
|
||||||
/>
|
|
||||||
<flux:description>trmnl-liquid is a Ruby-based renderer that matches the Core service’s Liquid behavior for better compatibility.</flux:description>
|
|
||||||
</flux:field>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
@if($alias)
|
@if($alias)
|
||||||
<flux:field>
|
<flux:field>
|
||||||
<flux:label>Alias URL</flux:label>
|
<flux:label>Alias URL</flux:label>
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,6 @@ declare(strict_types=1);
|
||||||
|
|
||||||
use App\Models\DeviceModel;
|
use App\Models\DeviceModel;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use Illuminate\Support\Facades\Http;
|
|
||||||
use Livewire\Livewire;
|
|
||||||
|
|
||||||
it('allows a user to view the device models page', function (): void {
|
it('allows a user to view the device models page', function (): void {
|
||||||
$user = User::factory()->create();
|
$user = User::factory()->create();
|
||||||
|
|
@ -89,38 +87,3 @@ it('redirects unauthenticated users from the device models page', function (): v
|
||||||
|
|
||||||
$response->assertRedirect('/login');
|
$response->assertRedirect('/login');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('update from API runs job and refreshes device models', function (): void {
|
|
||||||
$user = User::factory()->create();
|
|
||||||
$this->actingAs($user);
|
|
||||||
|
|
||||||
Http::fake([
|
|
||||||
'usetrmnl.com/api/palettes' => Http::response(['data' => []], 200),
|
|
||||||
config('services.trmnl.base_url').'/api/models' => Http::response([
|
|
||||||
'data' => [
|
|
||||||
[
|
|
||||||
'name' => 'api-model',
|
|
||||||
'label' => 'API Model',
|
|
||||||
'description' => 'From API',
|
|
||||||
'width' => 800,
|
|
||||||
'height' => 480,
|
|
||||||
'colors' => 4,
|
|
||||||
'bit_depth' => 2,
|
|
||||||
'scale_factor' => 1.0,
|
|
||||||
'rotation' => 0,
|
|
||||||
'mime_type' => 'image/png',
|
|
||||||
'offset_x' => 0,
|
|
||||||
'offset_y' => 0,
|
|
||||||
'kind' => 'trmnl',
|
|
||||||
'published_at' => '2023-01-01T00:00:00Z',
|
|
||||||
],
|
|
||||||
],
|
|
||||||
], 200),
|
|
||||||
]);
|
|
||||||
|
|
||||||
$component = Livewire::test('device-models.index')
|
|
||||||
->call('updateFromApi');
|
|
||||||
|
|
||||||
$deviceModels = $component->get('deviceModels');
|
|
||||||
expect($deviceModels->pluck('name')->toArray())->toContain('api-model');
|
|
||||||
});
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ namespace Tests\Feature;
|
||||||
use App\Models\Device;
|
use App\Models\Device;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||||
use Livewire\Livewire;
|
|
||||||
|
|
||||||
use function Pest\Laravel\actingAs;
|
use function Pest\Laravel\actingAs;
|
||||||
|
|
||||||
|
|
@ -24,35 +23,3 @@ test('configure view displays last_refreshed_at timestamp', function (): void {
|
||||||
$response->assertOk()
|
$response->assertOk()
|
||||||
->assertSee('5 minutes ago');
|
->assertSee('5 minutes ago');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('configure edit modal shows mirror checkbox and allows unchecking mirror', function (): void {
|
|
||||||
$user = User::factory()->create();
|
|
||||||
actingAs($user);
|
|
||||||
|
|
||||||
$deviceAttributes = [
|
|
||||||
'user_id' => $user->id,
|
|
||||||
'width' => 800,
|
|
||||||
'height' => 480,
|
|
||||||
'rotate' => 0,
|
|
||||||
'image_format' => 'png',
|
|
||||||
'maximum_compatibility' => false,
|
|
||||||
];
|
|
||||||
$sourceDevice = Device::factory()->create($deviceAttributes);
|
|
||||||
$mirrorDevice = Device::factory()->create([
|
|
||||||
...$deviceAttributes,
|
|
||||||
'mirror_device_id' => $sourceDevice->id,
|
|
||||||
]);
|
|
||||||
|
|
||||||
$response = $this->get(route('devices.configure', $mirrorDevice));
|
|
||||||
$response->assertOk()
|
|
||||||
->assertSee('Mirrors Device')
|
|
||||||
->assertSee('Select Device to Mirror');
|
|
||||||
|
|
||||||
Livewire::test('devices.configure', ['device' => $mirrorDevice])
|
|
||||||
->set('is_mirror', false)
|
|
||||||
->call('updateDevice')
|
|
||||||
->assertHasNoErrors();
|
|
||||||
|
|
||||||
$mirrorDevice->refresh();
|
|
||||||
expect($mirrorDevice->mirror_device_id)->toBeNull();
|
|
||||||
});
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ declare(strict_types=1);
|
||||||
|
|
||||||
use App\Models\DevicePalette;
|
use App\Models\DevicePalette;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use Illuminate\Support\Facades\Http;
|
|
||||||
|
|
||||||
uses(Illuminate\Foundation\Testing\RefreshDatabase::class);
|
uses(Illuminate\Foundation\Testing\RefreshDatabase::class);
|
||||||
|
|
||||||
|
|
@ -571,29 +570,3 @@ test('component refreshes palette list after deleting', function (): void {
|
||||||
expect($palettes)->toHaveCount($initialCount + 1);
|
expect($palettes)->toHaveCount($initialCount + 1);
|
||||||
expect(DevicePalette::count())->toBe($initialCount + 1);
|
expect(DevicePalette::count())->toBe($initialCount + 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('update from API runs job and refreshes device palettes', function (): void {
|
|
||||||
$user = User::factory()->create();
|
|
||||||
$this->actingAs($user);
|
|
||||||
|
|
||||||
Http::fake([
|
|
||||||
'usetrmnl.com/api/palettes' => Http::response([
|
|
||||||
'data' => [
|
|
||||||
[
|
|
||||||
'id' => 'api-palette',
|
|
||||||
'name' => 'API Palette',
|
|
||||||
'grays' => 4,
|
|
||||||
'colors' => null,
|
|
||||||
'framework_class' => '',
|
|
||||||
],
|
|
||||||
],
|
|
||||||
], 200),
|
|
||||||
config('services.trmnl.base_url').'/api/models' => Http::response(['data' => []], 200),
|
|
||||||
]);
|
|
||||||
|
|
||||||
$component = Livewire::test('device-palettes.index')
|
|
||||||
->call('updateFromApi');
|
|
||||||
|
|
||||||
$devicePalettes = $component->get('devicePalettes');
|
|
||||||
expect($devicePalettes->pluck('name')->toArray())->toContain('api-palette');
|
|
||||||
});
|
|
||||||
|
|
|
||||||
|
|
@ -109,43 +109,3 @@ test('recipe settings can clear trmnlp_id', function (): void {
|
||||||
|
|
||||||
expect($plugin->fresh()->trmnlp_id)->toBeNull();
|
expect($plugin->fresh()->trmnlp_id)->toBeNull();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('recipe settings saves preferred_renderer when liquid enabled and recipe is liquid', function (): void {
|
|
||||||
config(['services.trmnl.liquid_enabled' => true]);
|
|
||||||
|
|
||||||
$user = User::factory()->create();
|
|
||||||
$this->actingAs($user);
|
|
||||||
|
|
||||||
$plugin = Plugin::factory()->create([
|
|
||||||
'user_id' => $user->id,
|
|
||||||
'markup_language' => 'liquid',
|
|
||||||
'preferred_renderer' => null,
|
|
||||||
]);
|
|
||||||
|
|
||||||
Livewire::test('plugins.recipes.settings', ['plugin' => $plugin])
|
|
||||||
->set('use_trmnl_liquid_renderer', true)
|
|
||||||
->call('saveTrmnlpId')
|
|
||||||
->assertHasNoErrors();
|
|
||||||
|
|
||||||
expect($plugin->fresh()->preferred_renderer)->toBe('trmnl-liquid');
|
|
||||||
});
|
|
||||||
|
|
||||||
test('recipe settings clears preferred_renderer when checkbox unchecked', function (): void {
|
|
||||||
config(['services.trmnl.liquid_enabled' => true]);
|
|
||||||
|
|
||||||
$user = User::factory()->create();
|
|
||||||
$this->actingAs($user);
|
|
||||||
|
|
||||||
$plugin = Plugin::factory()->create([
|
|
||||||
'user_id' => $user->id,
|
|
||||||
'markup_language' => 'liquid',
|
|
||||||
'preferred_renderer' => 'trmnl-liquid',
|
|
||||||
]);
|
|
||||||
|
|
||||||
Livewire::test('plugins.recipes.settings', ['plugin' => $plugin])
|
|
||||||
->set('use_trmnl_liquid_renderer', false)
|
|
||||||
->call('saveTrmnlpId')
|
|
||||||
->assertHasNoErrors();
|
|
||||||
|
|
||||||
expect($plugin->fresh()->preferred_renderer)->toBeNull();
|
|
||||||
});
|
|
||||||
|
|
|
||||||
|
|
@ -52,10 +52,8 @@ it('imports plugin with shared.liquid file', function (): void {
|
||||||
$pluginImportService = new PluginImportService();
|
$pluginImportService = new PluginImportService();
|
||||||
$plugin = $pluginImportService->importFromZip($zipFile, $user);
|
$plugin = $pluginImportService->importFromZip($zipFile, $user);
|
||||||
|
|
||||||
expect($plugin->render_markup_shared)->toBe('{% comment %}Shared styles{% endcomment %}')
|
expect($plugin->render_markup)->toContain('{% comment %}Shared styles{% endcomment %}')
|
||||||
->and($plugin->render_markup)->toContain('<div class="view view--{{ size }}">')
|
->and($plugin->render_markup)->toContain('<div class="view view--{{ size }}">');
|
||||||
->and($plugin->getMarkupForSize('full'))->toContain('{% comment %}Shared styles{% endcomment %}')
|
|
||||||
->and($plugin->getMarkupForSize('full'))->toContain('<div class="view view--{{ size }}">');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('imports plugin with files in root directory', function (): void {
|
it('imports plugin with files in root directory', function (): void {
|
||||||
|
|
@ -204,10 +202,8 @@ it('imports plugin from monorepo with shared.liquid in subdirectory', function (
|
||||||
$pluginImportService = new PluginImportService();
|
$pluginImportService = new PluginImportService();
|
||||||
$plugin = $pluginImportService->importFromZip($zipFile, $user);
|
$plugin = $pluginImportService->importFromZip($zipFile, $user);
|
||||||
|
|
||||||
expect($plugin->render_markup_shared)->toBe('{% comment %}Monorepo shared styles{% endcomment %}')
|
expect($plugin->render_markup)->toContain('{% comment %}Monorepo shared styles{% endcomment %}')
|
||||||
->and($plugin->render_markup)->toContain('<div class="view view--{{ size }}">')
|
->and($plugin->render_markup)->toContain('<div class="view view--{{ size }}">');
|
||||||
->and($plugin->getMarkupForSize('full'))->toContain('{% comment %}Monorepo shared styles{% endcomment %}')
|
|
||||||
->and($plugin->getMarkupForSize('full'))->toContain('<div class="view view--{{ size }}">');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('imports plugin from URL with zip_entry_path parameter', function (): void {
|
it('imports plugin from URL with zip_entry_path parameter', function (): void {
|
||||||
|
|
@ -356,10 +352,8 @@ it('imports specific plugin from monorepo zip with zip_entry_path parameter', fu
|
||||||
expect($plugin)->toBeInstanceOf(Plugin::class)
|
expect($plugin)->toBeInstanceOf(Plugin::class)
|
||||||
->and($plugin->user_id)->toBe($user->id)
|
->and($plugin->user_id)->toBe($user->id)
|
||||||
->and($plugin->name)->toBe('Example Plugin 2') // Should import example-plugin2, not example-plugin
|
->and($plugin->name)->toBe('Example Plugin 2') // Should import example-plugin2, not example-plugin
|
||||||
->and($plugin->render_markup_shared)->toBe('{% comment %}Plugin 2 shared styles{% endcomment %}')
|
->and($plugin->render_markup)->toContain('{% comment %}Plugin 2 shared styles{% endcomment %}')
|
||||||
->and($plugin->render_markup)->toContain('<div class="plugin2-content">Plugin 2 content</div>')
|
->and($plugin->render_markup)->toContain('<div class="plugin2-content">Plugin 2 content</div>');
|
||||||
->and($plugin->getMarkupForSize('full'))->toContain('{% comment %}Plugin 2 shared styles{% endcomment %}')
|
|
||||||
->and($plugin->getMarkupForSize('full'))->toContain('<div class="plugin2-content">Plugin 2 content</div>');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('sets icon_url when importing from URL with iconUrl parameter', function (): void {
|
it('sets icon_url when importing from URL with iconUrl parameter', function (): void {
|
||||||
|
|
@ -522,8 +516,8 @@ it('imports plugin with only shared.liquid file', function (): void {
|
||||||
|
|
||||||
expect($plugin)->toBeInstanceOf(Plugin::class)
|
expect($plugin)->toBeInstanceOf(Plugin::class)
|
||||||
->and($plugin->markup_language)->toBe('liquid')
|
->and($plugin->markup_language)->toBe('liquid')
|
||||||
->and($plugin->render_markup_shared)->toBe('<div class="shared-content">{{ data.title }}</div>')
|
->and($plugin->render_markup)->toContain('<div class="view view--{{ size }}">')
|
||||||
->and($plugin->render_markup)->toBeNull();
|
->and($plugin->render_markup)->toContain('<div class="shared-content">{{ data.title }}</div>');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('imports plugin with only shared.blade.php file', function (): void {
|
it('imports plugin with only shared.blade.php file', function (): void {
|
||||||
|
|
@ -541,8 +535,8 @@ it('imports plugin with only shared.blade.php file', function (): void {
|
||||||
|
|
||||||
expect($plugin)->toBeInstanceOf(Plugin::class)
|
expect($plugin)->toBeInstanceOf(Plugin::class)
|
||||||
->and($plugin->markup_language)->toBe('blade')
|
->and($plugin->markup_language)->toBe('blade')
|
||||||
->and($plugin->render_markup_shared)->toBe('<div class="shared-content">{{ $data["title"] }}</div>')
|
->and($plugin->render_markup)->toBe('<div class="shared-content">{{ $data["title"] }}</div>')
|
||||||
->and($plugin->render_markup)->toBeNull();
|
->and($plugin->render_markup)->not->toContain('<div class="view view--{{ size }}">');
|
||||||
});
|
});
|
||||||
|
|
||||||
// Helper methods
|
// Helper methods
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue