feat: add favicon and web app manifest support

- Introduced new favicon files: apple-touch-icon.png, favicon-96x96.png, favicon.ico, favicon.svg.
- Updated auth-request.php to include new favicon paths in the whitelist.
- Added web app manifest files: web-app-manifest-192x192.png, web-app-manifest-512x512.png, and created a manifest.json structure in ThemeHelper.
- Refactored DefaultPageLayout to include favicon links and manifest reference.

This update enhances the application's branding and improves the user experience on mobile devices.
This commit is contained in:
Zack Spear
2025-06-10 18:09:39 -07:00
parent 7fe3b4dcd0
commit 8dc5410e14
10 changed files with 93 additions and 2 deletions

BIN
emhttp/apple-touch-icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

View File

@@ -44,7 +44,14 @@ $arrWhitelist = [
'/webGui/images/green-on.png',
'/webGui/images/red-on.png',
'/webGui/images/yellow-on.png',
'/webGui/images/UN-logotype-gradient.svg'
'/webGui/images/UN-logotype-gradient.svg',
'/apple-touch-icon.png',
'/favicon-96x96.png',
'/favicon.ico',
'/favicon.svg',
'/web-app-manifest-192x192.png',
'/web-app-manifest-512x512.png',
'/manifest.json'
];
// Add JS files from the unraid-components directory using cache

BIN
emhttp/favicon-96x96.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

3
emhttp/favicon.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 8.0 KiB

View File

@@ -85,7 +85,9 @@ if (count($pages)) {
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="robots" content="noindex, nofollow">
<meta name="referrer" content="same-origin">
<link type="image/png" rel="shortcut icon" href="/webGui/images/<?= _var($var, 'mdColor', 'red-on') ?>.png">
<? require_once "$docroot/plugins/dynamix/include/DefaultPageLayout/Favicon.php"; ?>
<link type="text/css" rel="stylesheet" href="<? autov("/webGui/styles/default-fonts.css") ?>">
<link type="text/css" rel="stylesheet" href="<? autov("/webGui/styles/default-cases.css") ?>">
<link type="text/css" rel="stylesheet" href="<? autov("/webGui/styles/font-awesome.css") ?>">

View File

@@ -0,0 +1,11 @@
<?php
$docroot = $docroot ?? $_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp';
$themeHelper->checkManifestFile();
?>
<link type="image/png" rel="shortcut icon" href="/webGui/images/<?= _var($var, 'mdColor', 'red-on') ?>.png">
<link rel="icon" type="image/png" href="/favicon-96x96.png" sizes="96x96" />
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
<meta name="apple-mobile-web-app-title" content="<?= _var($var, 'NAME') ?>" />
<link rel="manifest" href="/manifest.json" />

View File

@@ -33,6 +33,7 @@ class ThemeHelper {
private bool $lightTheme;
private string $fgcolor;
private bool $unlimitedWidth = false;
private string $manifestFile = '/usr/local/emhttp/manifest.json';
/**
* Constructor for ThemeHelper
@@ -127,6 +128,73 @@ class ThemeHelper {
exec("sed -ri 's/^\.logLine\{color:#......;/.logLine{color:{$this->fgcolor};/' $docroot/plugins/dynamix.docker.manager/log.htm >/dev/null &");
}
/**
* @todo finalize and configure in createManifestFile
*/
public function getManifestThemeColor(?array $display = null): string {
// check DisplaySettings "header custom background color"
if (!empty($display) && isset($display['background'])) {
return (!str_starts_with($display['background'], '#'))
? "#{$display['background']}"
: $display['background'];
}
// matches the default background colors for the themes...@todo: make this dynamic
$colors = [
self::THEME_AZURE => '#e8e8e8',
self::THEME_WHITE => self::COLOR_WHITE,
self::THEME_BLACK => self::COLOR_BLACK,
self::THEME_GRAY => '#1d1b1b',
];
return $colors[$this->themeName] ?? self::COLOR_BLACK;
}
/**
* @todo the api / emhttp should potentially write this / update this. So for now we'll create a simple version.
*/
public function createManifestFile(string $name = 'Unraid'): void {
$manifest = [
'name' => $name,
'short_name' => $name,
'icons' => [
[
'src' => "/web-app-manifest-192x192.png",
'sizes' => '192x192',
'type' => 'image/png',
'purpose' => 'maskable'
],
[
'src' => "/web-app-manifest-512x512.png",
'sizes' => '512x512',
'type' => 'image/png',
'purpose' => 'maskable'
]
],
// @todo: make colors dynamic based on theme and display settings via getManifestThemeColor.
// Needs something to prevent overkill when checking.
'theme_color' => '#1c1c1c',
'background_color' => '#1c1c1c',
'display' => 'standalone',
];
file_put_contents($this->manifestFile, json_encode($manifest, JSON_PRETTY_PRINT));
}
/**
* @todo finalize to check if the manifest file exists and if it does, check if the name matches the name of the webgui
* for now we'll just create the manifest file with "Unraid" as the name and not check it.
*/
public function checkManifestFile(?string $name = ''): void {
if (file_exists($this->manifestFile) && !empty($name)) {
$manifest = json_decode(file_get_contents($this->manifestFile), true);
if ($manifest['name'] !== $name) {
$manifest['name'] = $name;
$manifest['short_name'] = $name;
file_put_contents($this->manifestFile, json_encode($manifest, JSON_PRETTY_PRINT));
}
} else {
$this->createManifestFile($name);
}
}
/**
* Get all available theme names from the themes directory
*

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB