From 813188f7a4be56410adcf2006755b7c78dde9727 Mon Sep 17 00:00:00 2001 From: cookie-monster1649 Date: Sun, 12 Jul 2026 17:58:02 +1000 Subject: [PATCH] fix: use paired -dark icon for Settings-menu External links External links with position `settings` used the base (light) icon in Nextcloud's account/Settings menus. Core recolours those entries with the `--background-invert-if-dark` filter, which expects a dark-coloured source: in the dark theme the light base icon was inverted to black and became invisible. For Settings-menu entries, prefer the paired `-dark` icon variant (e.g. `foo-dark.svg` for `foo.svg`) when such a file exists in app data, falling back to the configured icon otherwise. Header links, guest/login links, public footer links and quota icons are unchanged. The same selection is applied in both navigation registration paths (Application::registerSites and BeforeTemplateRenderedListener), since both register the same navigation entry; changing only one had no visible effect. Fixes: https://github.com/nextcloud/external/issues/430 This change was AI-assisted and validated on Nextcloud 34.0.1. Signed-off-by: cookie-monster1649 Co-Authored-By: Claude Opus 4.8 (1M context) --- lib/AppInfo/Application.php | 19 ++++++++++++++----- lib/BeforeTemplateRenderedListener.php | 15 ++++++++++++++- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index c77d9f4f..9dbae086 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -63,13 +63,22 @@ public function registerSites( continue; } - $navigationManager->add(function () use ($site, $url): array { - if ($site['icon'] !== '') { - $image = $url->linkToRoute('external.icon.showIcon', ['icon' => $site['icon']]); - } else { - $image = $url->linkToRoute('external.icon.showIcon', ['icon' => 'external.svg']); + $navigationManager->add(function () use ($site, $url, $sitesManager): array { + $icon = $site['icon'] !== '' ? $site['icon'] : 'external.svg'; + + // Settings-menu entries are recoloured by Nextcloud core via the + // `--background-invert-if-dark` CSS filter, which expects a + // dark-coloured source icon. Prefer the paired `-dark` variant + // so the icon stays visible in the dark theme (nextcloud/external#430). + if ($site['type'] === SitesManager::TYPE_SETTING && !str_contains($icon, '-dark.')) { + $darkIcon = preg_replace('/(\.[^.]+)$/', '-dark$1', $icon); + if (is_string($darkIcon) && in_array($darkIcon, $sitesManager->getAvailableIcons(), true)) { + $icon = $darkIcon; + } } + $image = $url->linkToRoute('external.icon.showIcon', ['icon' => $icon]); + $href = $site['url']; if (!$site['redirect']) { $href = $url->linkToRoute('external.site.showPage', ['id' => $site['id'], 'path' => '']); diff --git a/lib/BeforeTemplateRenderedListener.php b/lib/BeforeTemplateRenderedListener.php index de35461e..690af745 100644 --- a/lib/BeforeTemplateRenderedListener.php +++ b/lib/BeforeTemplateRenderedListener.php @@ -89,7 +89,20 @@ protected function generateNavigationLinks(): void { } $this->navigationManager->add(function () use ($site) { - $image = $this->generateImageLink($site, false); + $icon = $site['icon'] !== '' ? $site['icon'] : 'external.svg'; + + // Settings-menu entries are recoloured by Nextcloud core via the + // `--background-invert-if-dark` CSS filter, which expects a + // dark-coloured source icon. Prefer the paired `-dark` variant + // so the icon stays visible in the dark theme (nextcloud/external#430). + if ($site['type'] === SitesManager::TYPE_SETTING && !str_contains($icon, '-dark.')) { + $darkIcon = preg_replace('/(\.[^.]+)$/', '-dark$1', $icon); + if (is_string($darkIcon) && in_array($darkIcon, $this->sitesManager->getAvailableIcons(), true)) { + $icon = $darkIcon; + } + } + + $image = $this->urlGenerator->linkToRoute('external.icon.showIcon', ['icon' => $icon, 'dark' => false]); $href = $this->getHref($site); return [