Use webp in several places to save significantly on file size.
This commit is contained in:
parent
f7d2d01c73
commit
7bb7e28fa4
|
@ -1,4 +1,4 @@
|
|||
// Default background of public pages
|
||||
$public-page-bg: if($theme == 'light', '../img/hexbg.png', '../img/hexbg_dark.png');
|
||||
$public-page-bg: if($theme == 'light', '../img/hexbg.webp', '../img/hexbg_dark.webp');
|
||||
|
||||
$scrollbar-color: if($theme == 'light', $material-color-grey-400, $material-color-grey-800);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
header.navbar {
|
||||
background-image: url('../img/header_bg.png'), linear-gradient(90deg, #0a6fc2 0%, #2196f3 100%);
|
||||
background-image: url('../img/header_bg.webp'), linear-gradient(90deg, #0a6fc2 0%, #2196f3 100%);
|
||||
background-position: top left, center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: 500px 100px, cover;
|
||||
|
|
|
@ -10,6 +10,11 @@ use Psr\Http\Message\UriInterface;
|
|||
|
||||
abstract class AbstractCustomAsset implements CustomAssetInterface
|
||||
{
|
||||
public function __construct(
|
||||
protected readonly Environment $environment
|
||||
) {
|
||||
}
|
||||
|
||||
abstract protected function getPattern(): string;
|
||||
|
||||
abstract protected function getDefaultUrl(): string;
|
||||
|
@ -17,7 +22,7 @@ abstract class AbstractCustomAsset implements CustomAssetInterface
|
|||
public function getPath(): string
|
||||
{
|
||||
$pattern = sprintf($this->getPattern(), '');
|
||||
return Environment::getInstance()->getUploadsDirectory() . '/' . $pattern;
|
||||
return $this->environment->getUploadsDirectory() . '/' . $pattern;
|
||||
}
|
||||
|
||||
public function getUrl(): string
|
||||
|
@ -27,7 +32,7 @@ abstract class AbstractCustomAsset implements CustomAssetInterface
|
|||
$pattern = $this->getPattern();
|
||||
$mtime = filemtime($path);
|
||||
|
||||
return Environment::getInstance()->getAssetUrl() . self::UPLOADS_URL_PREFIX . '/' . sprintf(
|
||||
return $this->environment->getAssetUrl() . self::UPLOADS_URL_PREFIX . '/' . sprintf(
|
||||
$pattern,
|
||||
'.' . $mtime
|
||||
);
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Assets;
|
||||
|
||||
abstract class AbstractMultiPatternCustomAsset extends AbstractCustomAsset
|
||||
{
|
||||
abstract protected function getPatterns(): array;
|
||||
|
||||
protected function getPattern(): string
|
||||
{
|
||||
return $this->getPatterns()['default'];
|
||||
}
|
||||
|
||||
protected function getPathForPattern(string $pattern): string
|
||||
{
|
||||
$pattern = sprintf($pattern, '');
|
||||
return $this->environment->getUploadsDirectory() . '/' . $pattern;
|
||||
}
|
||||
|
||||
public function getPath(): string
|
||||
{
|
||||
$patterns = $this->getPatterns();
|
||||
foreach ($patterns as $pattern) {
|
||||
$path = $this->getPathForPattern($pattern);
|
||||
if (is_file($path)) {
|
||||
return $path;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->getPathForPattern($patterns['default']);
|
||||
}
|
||||
|
||||
public function delete(): void
|
||||
{
|
||||
foreach ($this->getPatterns() as $pattern) {
|
||||
@unlink($this->getPathForPattern($pattern));
|
||||
}
|
||||
}
|
||||
|
||||
public function getUrl(): string
|
||||
{
|
||||
foreach ($this->getPatterns() as $pattern) {
|
||||
$path = $this->getPathForPattern($pattern);
|
||||
|
||||
if (is_file($path)) {
|
||||
$mtime = filemtime($path);
|
||||
|
||||
return $this->environment->getAssetUrl() . self::UPLOADS_URL_PREFIX . '/' . sprintf(
|
||||
$pattern,
|
||||
'.' . $mtime
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->getDefaultUrl();
|
||||
}
|
||||
}
|
|
@ -4,20 +4,22 @@ declare(strict_types=1);
|
|||
|
||||
namespace App\Assets;
|
||||
|
||||
use App\Environment;
|
||||
use Intervention\Image\Constraint;
|
||||
use Intervention\Image\Image;
|
||||
|
||||
final class AlbumArtCustomAsset extends AbstractCustomAsset
|
||||
final class AlbumArtCustomAsset extends AbstractMultiPatternCustomAsset
|
||||
{
|
||||
protected function getPattern(): string
|
||||
protected function getPatterns(): array
|
||||
{
|
||||
return 'album_art%s.jpg';
|
||||
return [
|
||||
'default' => 'album_art%s.webp',
|
||||
'image/jpeg' => 'album_art%s.jpg',
|
||||
];
|
||||
}
|
||||
|
||||
protected function getDefaultUrl(): string
|
||||
{
|
||||
return Environment::getInstance()->getAssetUrl() . '/img/generic_song.jpg';
|
||||
return $this->environment->getAssetUrl() . '/img/generic_song.webp';
|
||||
}
|
||||
|
||||
public function upload(Image $image): void
|
||||
|
@ -26,6 +28,14 @@ final class AlbumArtCustomAsset extends AbstractCustomAsset
|
|||
$newImage->resize(1500, 1500, function (Constraint $constraint) {
|
||||
$constraint->upsize();
|
||||
});
|
||||
$newImage->save($this->getPath());
|
||||
|
||||
$this->delete();
|
||||
|
||||
$pattern = $this->getPattern();
|
||||
|
||||
$mimeType = $newImage->mime();
|
||||
$quality = ('image/png' === $mimeType) ? 100 : 90;
|
||||
|
||||
$newImage->save($this->getPathForPattern($pattern), $quality);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,18 +4,20 @@ declare(strict_types=1);
|
|||
|
||||
namespace App\Assets;
|
||||
|
||||
use App\Environment;
|
||||
|
||||
enum AssetTypes: string
|
||||
{
|
||||
case AlbumArt = 'album_art';
|
||||
case Background = 'background';
|
||||
case BrowserIcon = 'browser_icon';
|
||||
|
||||
public function createObject(): CustomAssetInterface
|
||||
public function createObject(Environment $environment): CustomAssetInterface
|
||||
{
|
||||
return match ($this) {
|
||||
self::AlbumArt => new AlbumArtCustomAsset(),
|
||||
self::Background => new BackgroundCustomAsset(),
|
||||
self::BrowserIcon => new BrowserIconCustomAsset(),
|
||||
self::AlbumArt => new AlbumArtCustomAsset($environment),
|
||||
self::Background => new BackgroundCustomAsset($environment),
|
||||
self::BrowserIcon => new BrowserIconCustomAsset($environment),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,54 +4,23 @@ declare(strict_types=1);
|
|||
|
||||
namespace App\Assets;
|
||||
|
||||
use App\Environment;
|
||||
use Intervention\Image\Constraint;
|
||||
use Intervention\Image\Image;
|
||||
|
||||
final class BackgroundCustomAsset extends AbstractCustomAsset
|
||||
final class BackgroundCustomAsset extends AbstractMultiPatternCustomAsset
|
||||
{
|
||||
protected function getPattern(): string
|
||||
{
|
||||
return $this->getPatterns()['default'];
|
||||
}
|
||||
|
||||
private function getPatterns(): array
|
||||
protected function getPatterns(): array
|
||||
{
|
||||
return [
|
||||
'default' => 'background%s.webp',
|
||||
'image/jpeg' => 'background%s.jpg',
|
||||
'image/png' => 'background%s.png',
|
||||
'default' => 'background%s.jpg',
|
||||
];
|
||||
}
|
||||
|
||||
private function getPathForPattern(string $pattern): string
|
||||
{
|
||||
$pattern = sprintf($pattern, '');
|
||||
return Environment::getInstance()->getUploadsDirectory() . '/' . $pattern;
|
||||
}
|
||||
|
||||
public function getPath(): string
|
||||
{
|
||||
$patterns = $this->getPatterns();
|
||||
foreach ($patterns as $pattern) {
|
||||
$path = $this->getPathForPattern($pattern);
|
||||
if (is_file($path)) {
|
||||
return $path;
|
||||
}
|
||||
}
|
||||
|
||||
return $patterns['default'];
|
||||
}
|
||||
|
||||
protected function getDefaultUrl(): string
|
||||
{
|
||||
return Environment::getInstance()->getAssetUrl() . '/img/hexbg.png';
|
||||
}
|
||||
|
||||
public function delete(): void
|
||||
{
|
||||
foreach ($this->getPatterns() as $pattern) {
|
||||
@unlink($this->getPathForPattern($pattern));
|
||||
}
|
||||
return $this->environment->getAssetUrl() . '/img/hexbg.webp';
|
||||
}
|
||||
|
||||
public function upload(Image $image): void
|
||||
|
@ -63,29 +32,11 @@ final class BackgroundCustomAsset extends AbstractCustomAsset
|
|||
|
||||
$this->delete();
|
||||
|
||||
$patterns = $this->getPatterns();
|
||||
$pattern = $this->getPattern();
|
||||
|
||||
$mimeType = $newImage->mime();
|
||||
$pattern = $patterns[$mimeType] ?? $patterns['default'];
|
||||
$quality = ('image/png' === $mimeType) ? 100 : 90;
|
||||
|
||||
$newImage->save($this->getPathForPattern($pattern), 90);
|
||||
}
|
||||
|
||||
public function getUrl(): string
|
||||
{
|
||||
foreach ($this->getPatterns() as $pattern) {
|
||||
$path = $this->getPathForPattern($pattern);
|
||||
|
||||
if (is_file($path)) {
|
||||
$mtime = filemtime($path);
|
||||
|
||||
return Environment::getInstance()->getAssetUrl() . self::UPLOADS_URL_PREFIX . '/' . sprintf(
|
||||
$pattern,
|
||||
'.' . $mtime
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->getDefaultUrl();
|
||||
$newImage->save($this->getPathForPattern($pattern), $quality);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ declare(strict_types=1);
|
|||
|
||||
namespace App\Assets;
|
||||
|
||||
use App\Environment;
|
||||
use Intervention\Image\Image;
|
||||
use Symfony\Component\Filesystem\Filesystem;
|
||||
|
||||
|
@ -35,15 +34,13 @@ final class BrowserIconCustomAsset extends AbstractCustomAsset
|
|||
|
||||
protected function getDefaultUrl(): string
|
||||
{
|
||||
$env = Environment::getInstance();
|
||||
|
||||
$assetUrl = $env->getAssetUrl();
|
||||
return $assetUrl . '/icons/' . $env->getAppEnvironmentEnum()->value . '/original.png';
|
||||
$assetUrl = $this->environment->getAssetUrl();
|
||||
return $assetUrl . '/icons/' . $this->environment->getAppEnvironmentEnum()->value . '/original.png';
|
||||
}
|
||||
|
||||
public function upload(Image $image): void
|
||||
{
|
||||
$uploadsDir = Environment::getInstance()->getUploadsDirectory() . '/browser_icon';
|
||||
$uploadsDir = $this->environment->getUploadsDirectory() . '/browser_icon';
|
||||
(new Filesystem())->mkdir($uploadsDir);
|
||||
|
||||
$newImage = clone $image;
|
||||
|
@ -59,16 +56,15 @@ final class BrowserIconCustomAsset extends AbstractCustomAsset
|
|||
|
||||
public function delete(): void
|
||||
{
|
||||
$uploadsDir = Environment::getInstance()->getUploadsDirectory() . '/browser_icon';
|
||||
$uploadsDir = $this->environment->getUploadsDirectory() . '/browser_icon';
|
||||
(new Filesystem())->remove($uploadsDir);
|
||||
}
|
||||
|
||||
public function getUrlForSize(int $size): string
|
||||
{
|
||||
$env = Environment::getInstance();
|
||||
$assetUrl = $env->getAssetUrl();
|
||||
$assetUrl = $this->environment->getAssetUrl();
|
||||
|
||||
$uploadsDir = $env->getUploadsDirectory();
|
||||
$uploadsDir = $this->environment->getUploadsDirectory();
|
||||
$iconPath = $uploadsDir . '/browser_icon/' . $size . '.png';
|
||||
|
||||
if (is_file($iconPath)) {
|
||||
|
@ -76,6 +72,6 @@ final class BrowserIconCustomAsset extends AbstractCustomAsset
|
|||
return $assetUrl . '/uploads/browser_icon/' . $size . '.' . $mtime . '.png';
|
||||
}
|
||||
|
||||
return $assetUrl . '/icons/' . $env->getAppEnvironmentEnum()->value . '/' . $size . '.png';
|
||||
return $assetUrl . '/icons/' . $this->environment->getAppEnvironmentEnum()->value . '/' . $size . '.png';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,18 +6,24 @@ namespace App\Controller\Api\Admin\CustomAssets;
|
|||
|
||||
use App\Assets\AssetTypes;
|
||||
use App\Entity;
|
||||
use App\Environment;
|
||||
use App\Http\Response;
|
||||
use App\Http\ServerRequest;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
final class DeleteCustomAssetAction
|
||||
{
|
||||
public function __construct(
|
||||
private readonly Environment $environment
|
||||
) {
|
||||
}
|
||||
|
||||
public function __invoke(
|
||||
ServerRequest $request,
|
||||
Response $response,
|
||||
string $type
|
||||
): ResponseInterface {
|
||||
$customAsset = AssetTypes::from($type)->createObject();
|
||||
$customAsset = AssetTypes::from($type)->createObject($this->environment);
|
||||
$customAsset->delete();
|
||||
|
||||
return $response->withJson(Entity\Api\Status::success());
|
||||
|
|
|
@ -5,18 +5,24 @@ declare(strict_types=1);
|
|||
namespace App\Controller\Api\Admin\CustomAssets;
|
||||
|
||||
use App\Assets\AssetTypes;
|
||||
use App\Environment;
|
||||
use App\Http\Response;
|
||||
use App\Http\ServerRequest;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
final class GetCustomAssetAction
|
||||
{
|
||||
public function __construct(
|
||||
private readonly Environment $environment
|
||||
) {
|
||||
}
|
||||
|
||||
public function __invoke(
|
||||
ServerRequest $request,
|
||||
Response $response,
|
||||
string $type
|
||||
): ResponseInterface {
|
||||
$customAsset = AssetTypes::from($type)->createObject();
|
||||
$customAsset = AssetTypes::from($type)->createObject($this->environment);
|
||||
|
||||
return $response->withJson(
|
||||
[
|
||||
|
|
|
@ -6,6 +6,7 @@ namespace App\Controller\Api\Admin\CustomAssets;
|
|||
|
||||
use App\Assets\AssetTypes;
|
||||
use App\Entity;
|
||||
use App\Environment;
|
||||
use App\Http\Response;
|
||||
use App\Http\ServerRequest;
|
||||
use App\Media\AlbumArt;
|
||||
|
@ -14,12 +15,17 @@ use Psr\Http\Message\ResponseInterface;
|
|||
|
||||
final class PostCustomAssetAction
|
||||
{
|
||||
public function __construct(
|
||||
private readonly Environment $environment
|
||||
) {
|
||||
}
|
||||
|
||||
public function __invoke(
|
||||
ServerRequest $request,
|
||||
Response $response,
|
||||
string $type
|
||||
): ResponseInterface {
|
||||
$customAsset = AssetTypes::from($type)->createObject();
|
||||
$customAsset = AssetTypes::from($type)->createObject($this->environment);
|
||||
|
||||
$flowResponse = Flow::process($request, $response);
|
||||
if ($flowResponse instanceof ResponseInterface) {
|
||||
|
|
|
@ -124,7 +124,7 @@ final class Customization
|
|||
{
|
||||
$publicCss = $this->settings->getPublicCustomCss() ?? '';
|
||||
|
||||
$background = new BackgroundCustomAsset();
|
||||
$background = new BackgroundCustomAsset($this->environment);
|
||||
if ($background->isUploaded()) {
|
||||
$backgroundUrl = $background->getUrl();
|
||||
|
||||
|
@ -156,7 +156,7 @@ final class Customization
|
|||
|
||||
public function getBrowserIconUrl(int $size = 256): string
|
||||
{
|
||||
return (new BrowserIconCustomAsset())->getUrlForSize($size);
|
||||
return (new BrowserIconCustomAsset($this->environment))->getUrlForSize($size);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -8,6 +8,7 @@ use App\Assets\AlbumArtCustomAsset;
|
|||
use App\Doctrine\ReloadableEntityManagerInterface;
|
||||
use App\Doctrine\Repository;
|
||||
use App\Entity;
|
||||
use App\Environment;
|
||||
use App\Flysystem\ExtendedFilesystemInterface;
|
||||
use App\Flysystem\StationFilesystems;
|
||||
use App\Radio\Enums\StreamFormats;
|
||||
|
@ -22,7 +23,8 @@ final class StationRepository extends Repository
|
|||
{
|
||||
public function __construct(
|
||||
ReloadableEntityManagerInterface $em,
|
||||
private readonly SettingsRepository $settingsRepo
|
||||
private readonly SettingsRepository $settingsRepo,
|
||||
private readonly Environment $environment
|
||||
) {
|
||||
parent::__construct($em);
|
||||
}
|
||||
|
@ -186,7 +188,7 @@ final class StationRepository extends Repository
|
|||
}
|
||||
|
||||
$customUrl = $this->settingsRepo->readSettings()->getDefaultAlbumArtUrlAsUri();
|
||||
return $customUrl ?? (new AlbumArtCustomAsset())->getUri();
|
||||
return $customUrl ?? (new AlbumArtCustomAsset($this->environment))->getUri();
|
||||
}
|
||||
|
||||
public function setFallback(
|
||||
|
|
|
@ -94,7 +94,7 @@ server {
|
|||
}
|
||||
|
||||
location /static/uploads {
|
||||
rewrite ^(.+)\.(?:\w+)\.(js|css|png|jpg)$ $1.$2 last;
|
||||
rewrite ^(.+)\.(?:\w+)\.(js|css|png|jpg|webp)$ $1.$2 last;
|
||||
|
||||
alias /var/azuracast/uploads;
|
||||
try_files $uri =404;
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 81 KiB |
Binary file not shown.
After Width: | Height: | Size: 99 KiB |
Binary file not shown.
After Width: | Height: | Size: 408 KiB |
Binary file not shown.
After Width: | Height: | Size: 465 KiB |
Loading…
Reference in New Issue