mirror of
http://172.20.10.11:3000/gitadmin/INSIGHT-MVP.git
synced 2026-06-25 00:16:41 +02:00
fix: use direct favicon.ico, open links in app mode (popup window)
- Favicon loaded directly from website's /favicon.ico instead of Google's service (which was unreliable/blocked on internal networks) - Letter-initial fallback when favicon can't be loaded - External links open in popup window (app mode) instead of new tab Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
65c5c7b7dd
commit
0a52606012
2 changed files with 50 additions and 35 deletions
|
|
@ -7,11 +7,11 @@ function generateId(): string {
|
||||||
return Date.now().toString(36) + Math.random().toString(36).slice(2, 10);
|
return Date.now().toString(36) + Math.random().toString(36).slice(2, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Favicon-URL aus einer Website-URL ableiten (Google Favicon Service) */
|
/** Favicon-URL direkt von der Webseite laden */
|
||||||
function getFaviconUrl(url: string): string | null {
|
function getFaviconUrl(url: string): string | null {
|
||||||
try {
|
try {
|
||||||
const domain = new URL(url).hostname;
|
const parsed = new URL(url);
|
||||||
return `https://www.google.com/s2/favicons?domain=${domain}&sz=32`;
|
return `${parsed.origin}/favicon.ico`;
|
||||||
} catch {
|
} catch {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,11 +12,11 @@ interface ExternalLink {
|
||||||
sortOrder: number;
|
sortOrder: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Favicon-URL aus einer Website-URL ableiten (Google Favicon Service) */
|
/** Favicon-URL direkt von der Webseite laden */
|
||||||
function getFaviconUrl(url: string): string | null {
|
function getFaviconUrl(url: string): string | null {
|
||||||
try {
|
try {
|
||||||
const domain = new URL(url).hostname;
|
const parsed = new URL(url);
|
||||||
return `https://www.google.com/s2/favicons?domain=${domain}&sz=32`;
|
return `${parsed.origin}/favicon.ico`;
|
||||||
} catch {
|
} catch {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
@ -82,37 +82,52 @@ export function AppLayout() {
|
||||||
<a
|
<a
|
||||||
key={link.id}
|
key={link.id}
|
||||||
href={link.url}
|
href={link.url}
|
||||||
target="_blank"
|
onClick={(e) => {
|
||||||
rel="noopener noreferrer"
|
e.preventDefault();
|
||||||
|
window.open(
|
||||||
|
link.url,
|
||||||
|
link.label,
|
||||||
|
'popup,noopener',
|
||||||
|
);
|
||||||
|
}}
|
||||||
className={styles.navLink}
|
className={styles.navLink}
|
||||||
>
|
>
|
||||||
{favicon ? (
|
<img
|
||||||
<img
|
src={favicon || ''}
|
||||||
src={favicon}
|
alt=""
|
||||||
alt=""
|
style={{
|
||||||
style={{
|
width: 16,
|
||||||
width: 16,
|
height: 16,
|
||||||
height: 16,
|
objectFit: 'contain',
|
||||||
objectFit: 'contain',
|
borderRadius: 2,
|
||||||
borderRadius: 2,
|
}}
|
||||||
}}
|
onError={(e) => {
|
||||||
/>
|
// Fallback: erstes Zeichen des Labels als Text-Icon
|
||||||
) : (
|
const el = e.target as HTMLImageElement;
|
||||||
<svg
|
el.style.display = 'none';
|
||||||
width="16"
|
const fallback = el.nextElementSibling;
|
||||||
height="16"
|
if (fallback)
|
||||||
viewBox="0 0 16 16"
|
(fallback as HTMLElement).style.display =
|
||||||
fill="none"
|
'flex';
|
||||||
stroke="currentColor"
|
}}
|
||||||
strokeWidth="1.5"
|
/>
|
||||||
strokeLinecap="round"
|
<span
|
||||||
strokeLinejoin="round"
|
style={{
|
||||||
>
|
display: 'none',
|
||||||
<path d="M10 2h4v4" />
|
width: 16,
|
||||||
<path d="M6 10L14 2" />
|
height: 16,
|
||||||
<path d="M14 9v4a1 1 0 01-1 1H3a1 1 0 01-1-1V3a1 1 0 011-1h4" />
|
alignItems: 'center',
|
||||||
</svg>
|
justifyContent: 'center',
|
||||||
)}
|
fontSize: '0.625rem',
|
||||||
|
fontWeight: 700,
|
||||||
|
background: 'rgba(255,255,255,0.15)',
|
||||||
|
borderRadius: 2,
|
||||||
|
color: 'rgba(255,255,255,0.8)',
|
||||||
|
flexShrink: 0,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{link.label.charAt(0).toUpperCase()}
|
||||||
|
</span>
|
||||||
{link.label}
|
{link.label}
|
||||||
<svg
|
<svg
|
||||||
width="10"
|
width="10"
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue