From befa580d67f16b45079c7f989af2628848ecc0c9 Mon Sep 17 00:00:00 2001 From: rumblefrog Date: Sun, 10 May 2026 14:05:31 -0400 Subject: [PATCH 1/2] fix(brand): ship favicon.zip from #1235 (correct shield-with-cross mark) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #1251 closed #1235 with a hand-authored "S" rounded-square SVG that matched .sidebar__brand-mark, but rumblefrog had attached the actual intended favicon set as a comment on the issue (favicon.zip). The shipped icon was therefore wrong on the dimension that mattered: it was a stylistic riff on the sidebar brand, not the canonical SourceBans++ shield-with-cross mark. Replace the icon artwork byte-faithful from the favicon.zip: - favicon.svg → orange shield (#ea580c) with a black "+" centred and a small white "++" tucked in the bottom-right (the literal "++" in SourceBans++). - favicon.ico → 3-icon (48x48 + 32x32 + 16x16) — was 2-icon prior. - apple-touch-icon-180.png → repainted from the zip's apple-touch-icon (kept the existing filename so the header.tpl doesn't move). - favicon-96x96.png (new) → higher-DPI tab strip source. - web-app-manifest-{192,512}x{192,512}.png (new) → maskable PWA install sources referenced by the new manifest. - site.webmanifest (new) → wires up the install-as-PWA path. Faithful to the zip with one fix: icon paths drop the leading slash so they resolve relative to the manifest URL (subdir installs would 404 on the root-relative shape the zip ships). Replaces both copies (themes/default/images/ + install/images/). Wire-up changes in web/themes/default/core/header.tpl: - Add for the new 96 source. - Add for the PWA install path. - Refresh the explanatory comment to describe the new mark and the manifest plumbing (the prior comment described the "S" SVG that's no longer there). Theme-color metas + the SVG / ICO / apple-touch-icon tags from #1251 are unchanged — that scaffolding was correct; only the asset behind it was wrong. The legacy installer (web/install/template/header.php) needs no markup change — it already references favicon.svg from the theme and favicon.ico from install/images/, both of which now ship the new mark. Closes #1235 --- web/install/images/favicon.ico | Bin 1590 -> 15086 bytes web/themes/default/core/header.tpl | 26 ++++++++++++------ .../default/images/apple-touch-icon-180.png | Bin 5752 -> 4043 bytes web/themes/default/images/favicon-96x96.png | Bin 0 -> 1902 bytes web/themes/default/images/favicon.ico | Bin 1590 -> 15086 bytes web/themes/default/images/favicon.svg | 2 +- web/themes/default/images/site.webmanifest | 21 ++++++++++++++ .../images/web-app-manifest-192x192.png | Bin 0 -> 3959 bytes .../images/web-app-manifest-512x512.png | Bin 0 -> 15055 bytes 9 files changed, 39 insertions(+), 10 deletions(-) create mode 100644 web/themes/default/images/favicon-96x96.png create mode 100644 web/themes/default/images/site.webmanifest create mode 100644 web/themes/default/images/web-app-manifest-192x192.png create mode 100644 web/themes/default/images/web-app-manifest-512x512.png diff --git a/web/install/images/favicon.ico b/web/install/images/favicon.ico index 7567a4807c08a54a2752acc7f490bf658d68640f..9e8fdfbe9a260b0381c362c9d31297eaaf604d9f 100644 GIT binary patch literal 15086 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 diff --git a/web/themes/default/core/header.tpl b/web/themes/default/core/header.tpl index 727ad754d..8985f24eb 100644 --- a/web/themes/default/core/header.tpl +++ b/web/themes/default/core/header.tpl @@ -39,19 +39,27 @@ {$title} {* - Favicon set (#1235): the SVG is the primary — Chrome/Firefox/Safari - prefer it and the @media (prefers-color-scheme: dark) rule baked - into the file lightens the orange to --brand-400 (#fb923c) when - the OS chrome is dark, matching the dark-theme accent. The .ico - is the legacy fallback. apple-touch-icon-180 covers iOS home - screens. The two theme-color metas paint the mobile chrome - bar: --brand-600 (#ea580c) by default, --zinc-950 (#09090b — - the value html.dark resolves --bg-page to in theme.css) when - the OS is dark. + Favicon set (#1235): the icon artwork ships byte-faithful + from the favicon.zip rumblefrog attached to #1235 — orange shield + (`#ea580c`) with a black "+" centred and a small white "++" tucked + in the bottom-right (the "++" in SourceBans++). The SVG is the + primary — Chrome/Firefox/Safari prefer it; the .ico (3-icon: + 48x48 + 32x32 + 16x16) is the legacy fallback; favicon-96x96 + covers higher-DPI tab strips that pick a 96px source over the + SVG; apple-touch-icon-180 covers iOS home screens. The web app + manifest wires up the install-as-PWA path on Edge/Chrome with + maskable 192x192 + 512x512 sources. The two theme-color metas + paint the in-browser chrome bar: --brand-600 (`#ea580c`) by + default, --zinc-950 (`#09090b` — the value html.dark resolves + --bg-page to in theme.css) when the OS is dark; HTML metas + win over the manifest's static theme_color for the in-browser + case. *} + + diff --git a/web/themes/default/images/apple-touch-icon-180.png b/web/themes/default/images/apple-touch-icon-180.png index 1cf17b71831d1131886489d79b2f95493f7789fc..a121ff0a51d7f7f870f9ec146bbccac80d567823 100644 GIT binary patch literal 4043 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 literal 5752 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 literal 0 HcmV?d00001 diff --git a/web/themes/default/images/favicon.ico b/web/themes/default/images/favicon.ico index 7567a4807c08a54a2752acc7f490bf658d68640f..9e8fdfbe9a260b0381c362c9d31297eaaf604d9f 100644 GIT binary patch literal 15086 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 diff --git a/web/themes/default/images/favicon.svg b/web/themes/default/images/favicon.svg index 39b509bc5..d0769af3a 100644 --- a/web/themes/default/images/favicon.svg +++ b/web/themes/default/images/favicon.svg @@ -1 +1 @@ - + \ No newline at end of file diff --git a/web/themes/default/images/site.webmanifest b/web/themes/default/images/site.webmanifest new file mode 100644 index 000000000..e06509d8c --- /dev/null +++ b/web/themes/default/images/site.webmanifest @@ -0,0 +1,21 @@ +{ + "name": "SourceBans++", + "short_name": "SourceBans++", + "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" + } + ], + "theme_color": "#ffffff", + "background_color": "#ffffff", + "display": "standalone" +} diff --git a/web/themes/default/images/web-app-manifest-192x192.png b/web/themes/default/images/web-app-manifest-192x192.png new file mode 100644 index 0000000000000000000000000000000000000000..87aebe00dce9453c345527f9258b8b07d9d3dd82 GIT binary patch literal 3959 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 P1*V~*qg;H=_VND%KL?Oy literal 0 HcmV?d00001 From 54b039233cbaf60ada42603fda5c701f5b396074 Mon Sep 17 00:00:00 2001 From: rumblefrog Date: Sun, 10 May 2026 14:30:04 -0400 Subject: [PATCH 2/2] fix(brand): wire `template.logo` setting back into the chrome brand mark MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The `template.logo` admin setting (Admin → Settings → General → Logo path, default `logos/sb-large.png`) was a vestigial v1.x setting in v2.0 — the legacy panel rendered it as a top-banner ``, and when the v2.0 chrome rewrote the layout to use `.sidebar__brand-mark` (a CSS-rendered "S" rounded-square), no template was updated to consume `$logo` anymore. The setting still appeared in the admin UI and saved back to a row nobody read; the default value (`logos/sb-large.png`) pointed at a path that didn't even exist in `web/themes/default/`. This commit resurrects the setting and wires it into the three places the chrome renders the brand mark: - `core/navbar.tpl` — the sidebar's top-left mark (every authenticated route). Renders ``. No View binds to this template (it's rendered procedurally by `core/navbar.php`), so SmartyTemplateRule doesn't fire — and `$logo` is in scope via the `$theme->assign('logo', …)` call in `core/header.php`, which runs earlier in the page-builder lifecycle (header → navbar → title → page → footer). - `page_login.tpl` — the sign-in card's brand row. Same swap, but the template binds to `Sbpp\View\LoginView` so SmartyTemplateRule cross- checks property↔reference parity. Pre-resolves the joined URL in `page.login.php` and passes a single `$brand_logo_url` property (cleaner than threading both `$theme_url` + `$logo` through the View surface for what's just a precomputed `themes//`). - `updater.tpl` — the DB updater's header. The updater runs in its own bootstrap context (`web/updater/index.php`) which doesn't load `core/header.php`, so `$logo` / `$theme_url` aren't in scope. Hardcoded to `../themes/default/images/favicon.svg` here — the updater is an internal one-off page (admin-only, runs once per upgrade), and threading the setting through `UpdaterView` would be plumbing for zero customisation value. Default value flips from the broken-in-v2.0 `logos/sb-large.png` to `images/favicon.svg` (the SourceBans++ shield from #1235's favicon set): - `web/install/includes/sql/data.sql` — fresh installs. - `web/updater/data/809.php` (registered in `store.json`) — paired migration converts existing installs whose value is still the v1.x default forward to the new default. Conditional WHERE means admins with custom values are untouched. Idempotent (the WHERE matches zero rows on re-run). CSS: `.sidebar__brand-mark` rule drops the orange-rounded-square + centered-letter styling (`background`, `color`, `display: grid; place-items: center`, `font-*`, `border-radius`) that was designed for the pre-#1235 `
S
` shape. The new mark's visual identity (orange shield + cross) lives in the SVG itself; the CSS keeps just sizing + flex-shrink so the brand row's layout is unchanged. Settings UI: adds a `

` below the "Logo path" input + `aria-describedby` link — text explains it's theme-relative, what the default is, and what surfaces it controls. Same shape as the sibling token-lifetime help paragraphs. Refs #1235 --- web/includes/View/LoginView.php | 10 +++++++ web/install/includes/sql/data.sql | 2 +- web/pages/page.login.php | 13 +++++++++ web/themes/default/core/navbar.tpl | 18 ++++++++++-- web/themes/default/css/theme.css | 8 ++++- .../default/page_admin_settings_settings.tpl | 7 ++++- web/themes/default/page_login.tpl | 7 ++++- web/themes/default/updater.tpl | 12 +++++++- web/updater/data/809.php | 29 +++++++++++++++++++ web/updater/store.json | 3 +- 10 files changed, 101 insertions(+), 8 deletions(-) create mode 100644 web/updater/data/809.php diff --git a/web/includes/View/LoginView.php b/web/includes/View/LoginView.php index f185eed93..4c0dde6f7 100644 --- a/web/includes/View/LoginView.php +++ b/web/includes/View/LoginView.php @@ -33,6 +33,15 @@ * the actual login wiring posts via * `sb.api.call(Actions.AuthLogin, …)` with a hardcoded * `redirect: ''` (post-login destination is the dashboard). + * - `$brand_logo_url` — Pre-resolved URL for the brand mark image + * in the sign-in card header (``). + * The page handler joins `$theme_url` (`themes/`, set by + * init.php) with `Config::get('template.logo')` (the v1.x setting + * resurrected by #1235 — default `images/favicon.svg`, the new + * SourceBans++ shield mark; admins can repoint at any + * theme-relative path). Pre-resolving here keeps `theme_url` and + * `logo` out of the View property surface (`core/header.tpl`'s + * globally-assigned `$theme_url` doesn't bleed into page Views). */ final class LoginView extends View { @@ -56,6 +65,7 @@ public function __construct( public readonly bool $normallogin_show, public readonly bool $steamlogin_show, public readonly string $redir, + public readonly string $brand_logo_url, ) { } diff --git a/web/install/includes/sql/data.sql b/web/install/includes/sql/data.sql index 97037b590..3eaacb7f5 100644 --- a/web/install/includes/sql/data.sql +++ b/web/install/includes/sql/data.sql @@ -36,7 +36,7 @@ INSERT INTO `{prefix}_settings` (`setting`, `value`) VALUES ('bans.customreasons', ''), ('config.password.minlength', '7'), ('config.debug', '0'), -('template.logo', 'logos/sb-large.png'), +('template.logo', 'images/favicon.svg'), ('template.title', 'SourceBans++'), ('config.enableprotest', '1'), ('config.enablecomms', '1'), diff --git a/web/pages/page.login.php b/web/pages/page.login.php index 2d3ad4caf..799a4c360 100644 --- a/web/pages/page.login.php +++ b/web/pages/page.login.php @@ -117,10 +117,23 @@ // (post-login destination is the dashboard). Any third-party theme // that forked the pre-v2.0.0 default and still calls `DoLogin(...)` // from removed legacy bulk JS would no-op there. +// `template.logo` is the operator-configurable brand mark path, +// resolved relative to the active theme directory. Default ships as +// `images/favicon.svg` (the SourceBans++ shield from the favicon set); +// admins can override via Admin → Settings → General → Logo path. The +// theme-relative join mirrors what `core/navbar.tpl` does at runtime +// for the in-panel sidebar; pre-resolving here keeps `$theme_url` / +// `$logo` out of `LoginView`'s property surface (the chrome's globally- +// assigned `$theme_url` doesn't bleed into page Views). +$themeName = (string) (Config::get('config.theme') ?: 'default'); +$brandLogoPath = (string) Config::get('template.logo'); +$brandLogoUrl = 'themes/' . $themeName . '/' . ltrim($brandLogoPath, '/'); + $loginView = new \Sbpp\View\LoginView( normallogin_show: Config::getBool('config.enablenormallogin'), steamlogin_show: Config::getBool('config.enablesteamlogin'), redir: "DoLogin('');", + brand_logo_url: $brandLogoUrl, ); // `page_login.tpl` renders with the custom `-{ … }-` delimiter pair so diff --git a/web/themes/default/core/navbar.tpl b/web/themes/default/core/navbar.tpl index 2fc1ffe9c..98465a218 100644 --- a/web/themes/default/core/navbar.tpl +++ b/web/themes/default/core/navbar.tpl @@ -26,9 +26,23 @@ testid (rather than the `.sidebar__brand` class chain) keeps the assertion compliant with AGENTS.md's "Selectors must use testability hooks; never CSS class chains as the primary - selector" rule. *} + selector" rule. + + #1235 — the brand mark renders the operator-configurable + `template.logo` setting (Admin → Settings → General → Logo + path), resolved relative to the active theme's directory. + `$logo` is assigned by `core/header.php` (which runs before + this template per page-builder.php's lifecycle: + header → navbar → title → page → footer), so it's always in + scope here. Default ships as `images/favicon.svg` — the + canonical SourceBans++ shield-with-cross mark from the + favicon set; admins can repoint at any theme-relative path + (PNG / SVG / etc). The setting was vestigial in v2.0 until + this PR wired it back in; sees `web/updater/data/809.php` + for the upgrade-path migration that converts the v1.x + `logos/sb-large.png` default forward. *}

- + +

+ Path to the brand mark image rendered in the sidebar and sign-in card, resolved relative to the active theme directory (themes/<theme>/). Default: images/favicon.svg — the SourceBans++ shield from the favicon set. Any theme-relative SVG / PNG works. +

diff --git a/web/themes/default/page_login.tpl b/web/themes/default/page_login.tpl index 20dd4f813..a27282ba1 100644 --- a/web/themes/default/page_login.tpl +++ b/web/themes/default/page_login.tpl @@ -73,7 +73,12 @@