fix(favicon): скругляем углы кастомного лого как у плитки в хедере

Кастомное лого квадратное, и в фавиконе показывалось с острыми углами. Теперь
лого прогоняется через canvas со скруглённым клипом (radiusRatio 0.3 — как
rounded-linear-lg 12px на плитке 40px в хедере) и отдаётся скруглённым PNG.
При сбое canvas (taint/нет 2d-контекста) — фолбэк на сырой лого. Применяется и
в кабинете (useBranding), и на лендинге (QuickPurchase); буквенная монограмма
уже скруглена через rx.
This commit is contained in:
c0mrade
2026-06-03 12:33:10 +03:00
parent 085958342e
commit 71047780c9
3 changed files with 86 additions and 6 deletions

View File

@@ -9,7 +9,7 @@ import {
preloadLogo,
isLogoPreloaded,
} from '@/api/branding';
import { setFavicon, letterFaviconDataUri } from '@/utils/favicon';
import { setFavicon, letterFaviconDataUri, roundedFaviconDataUri } from '@/utils/favicon';
const FALLBACK_NAME = import.meta.env.VITE_APP_NAME || 'Cabinet';
const FALLBACK_LOGO = import.meta.env.VITE_APP_LOGO || 'V';
@@ -43,10 +43,20 @@ export function useBranding() {
document.title = appName || 'VPN';
}, [appName]);
// Update favicon — custom logo when available, else a brand-letter monogram
// so the tab always carries an icon instead of the browser default.
// Update favicon — custom logo (rounded like the header tile) when available,
// else a brand-letter monogram so the tab always carries an icon.
useEffect(() => {
setFavicon(logoUrl || letterFaviconDataUri(logoLetter));
if (!logoUrl) {
setFavicon(letterFaviconDataUri(logoLetter));
return;
}
let cancelled = false;
roundedFaviconDataUri(logoUrl).then((rounded) => {
if (!cancelled) setFavicon(rounded || logoUrl);
});
return () => {
cancelled = true;
};
}, [logoUrl, logoLetter]);
// Fullscreen setting from server