Skip to content

Commit

Permalink
Siplified configuration and icon injection
Browse files Browse the repository at this point in the history
  • Loading branch information
Spomky committed Jan 15, 2024
1 parent d9017c4 commit 0184663
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 26 deletions.
12 changes: 12 additions & 0 deletions src/DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,12 @@ private function getIconsNode(string $info): ArrayNodeDefinition
->treatTrueLike([])
->treatNullLike([])
->arrayPrototype()
->beforeNormalization()
->ifString()
->then(static fn (string $v): array => [
'src' => $v,
])
->end()
->children()
->scalarNode('src')
->isRequired()
Expand Down Expand Up @@ -502,6 +508,12 @@ private function getScreenshotsNode(string $info): ArrayNodeDefinition
->treatTrueLike([])
->treatNullLike([])
->arrayPrototype()
->beforeNormalization()
->ifString()
->then(static fn (string $v): array => [
'src' => $v,
])
->end()
->children()
->scalarNode('src')
->info('The path to the screenshot. Can be served by Asset Mapper.')
Expand Down
27 changes: 24 additions & 3 deletions src/Normalizer/IconNormalizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,32 +5,39 @@
namespace SpomkyLabs\PwaBundle\Normalizer;

use SpomkyLabs\PwaBundle\Dto\Icon;
use SpomkyLabs\PwaBundle\ImageProcessor\ImageProcessor;
use Symfony\Component\AssetMapper\AssetMapperInterface;
use Symfony\Component\AssetMapper\MappedAsset;
use Symfony\Component\Mime\MimeTypes;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
use function assert;

final readonly class IconNormalizer implements NormalizerInterface
{
public function __construct(
private AssetMapperInterface $assetMapper
private AssetMapperInterface $assetMapper,
private null|ImageProcessor $imageProcessor,
) {
}

public function normalize(mixed $object, string $format = null, array $context = []): array
{
assert($object instanceof Icon);
$url = null;
$asset = null;
if (! str_starts_with($object->src, '/')) {
$url = $this->assetMapper->getAsset($object->src)?->publicPath;
$asset = $this->assetMapper->getAsset($object->src);
$url = $asset?->publicPath;
}
if ($url === null) {
$url = $object->src;
}
$format = $this->getFormat($object, $asset);

$result = [
'src' => $url,
'sizes' => $object->getSizeList(),
'type' => $object->format,
'type' => $format,
'purpose' => $object->purpose,
];

Expand All @@ -56,4 +63,18 @@ public function getSupportedTypes(?string $format): array
Icon::class => true,
];
}

private function getFormat(Icon $object, ?MappedAsset $asset): ?string
{
if ($object->format !== null) {
return $object->format;
}

if ($this->imageProcessor === null || $asset === null || ! class_exists(MimeTypes::class)) {
return null;
}

$mime = MimeTypes::getDefault();
return $mime->guessMimeType($asset->sourcePath);
}
}
30 changes: 28 additions & 2 deletions src/Twig/PwaRuntime.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,40 @@ public function __construct(
$this->manifestPublicUrl = '/' . trim($manifestPublicUrl, '/');
}

public function load(): string
public function load(bool $themeColor = true, bool $icons = true): string
{
$url = $this->assetMapper->getPublicPath($this->manifestPublicUrl) ?? $this->manifestPublicUrl;
$output = sprintf('<link rel="manifest" href="%s">', $url);
if ($this->manifest->themeColor !== null) {
if ($this->manifest->icons !== [] && $icons === true) {
foreach ($this->manifest->icons as $icon) {
$iconUrl = $this->getIconPublicUrl($icon->src);
$output .= sprintf(
'%s<link rel="%s" sizes="%s" href="%s">',
PHP_EOL,
str_contains($icon->purpose ?? '', 'maskable') ? 'mask-icon' : 'icon',
$icon->getSizeList(),
$iconUrl
);
}
}
if ($this->manifest->themeColor !== null && $themeColor === true) {
$output .= sprintf('%s<meta name="theme-color" content="%s">', PHP_EOL, $this->manifest->themeColor);
}

return $output;
}

private function getIconPublicUrl(string $source): ?string
{
$url = null;
if (! str_starts_with($source, '/')) {
$asset = $this->assetMapper->getAsset($source);
$url = $asset?->publicPath;
}
if ($url === null) {
$url = $source;
}

return $url;
}
}
23 changes: 2 additions & 21 deletions tests/config.php
Original file line number Diff line number Diff line change
Expand Up @@ -114,16 +114,7 @@
'scope' => '/app/',
'start_url' => 'https://example.com',
'theme_color' => 'red',
'screenshots' => [
[
'src' => 'pwa/screenshots/360x800.svg',
'platform' => 'android',
'format' => 'png',
'label' => '360x800',
'width' => 360,
'height' => 800,
],
],
'screenshots' => ['pwa/screenshots/360x800.svg'],
'share_target' => [
'action' => 'shared_content_receiver',
'action_params' => [
Expand Down Expand Up @@ -154,21 +145,11 @@
'name' => 'New reminder',
'url' => '/create/reminder',
'icons' => [
'pwa/1920x1920.svg',
[
'src' => 'pwa/1920x1920.svg',
'sizes' => [48, 72, 96, 128, 256],
'format' => 'webp',
],
[
'src' => 'pwa/1920x1920.svg',
'sizes' => [48, 72, 96, 128, 256],
'format' => 'png',
'purpose' => 'maskable',
],
[
'src' => 'pwa/1920x1920.svg',
'sizes' => [0],
],
],
],
],
Expand Down

0 comments on commit 0184663

Please sign in to comment.