feat: show favicons for external chat links
Adds DuckDuckGo favicon lookup for external URLs Shows favicons in markdown and fetch tool link rows Hides missing icons automatically
This commit is contained in:
@@ -17,7 +17,7 @@ import { Icon } from "@/components/icon/Icon";
|
||||
import { copyTextToClipboard } from '@/lib/clipboard';
|
||||
import { useI18n } from '@/lib/i18n';
|
||||
|
||||
import { isExternalHttpUrl, isLoopbackHttpUrl, openExternalUrl } from '@/lib/url';
|
||||
import { getExternalFaviconUrl, isExternalHttpUrl, isLoopbackHttpUrl, openExternalUrl } from '@/lib/url';
|
||||
import { useOptionalThemeSystem } from '@/contexts/useThemeSystem';
|
||||
import { getDefaultTheme } from '@/lib/theme/themes';
|
||||
import { generateSyntaxTheme } from '@/lib/theme/syntaxThemeGenerator';
|
||||
@@ -92,6 +92,27 @@ const useExternalLinkInteractions = ({
|
||||
}, [containerRef, enabled]);
|
||||
};
|
||||
|
||||
const ExternalLinkFavicon: React.FC<{ href: string }> = ({ href }) => {
|
||||
const [failed, setFailed] = React.useState(false);
|
||||
const faviconUrl = React.useMemo(() => getExternalFaviconUrl(href), [href]);
|
||||
|
||||
if (!faviconUrl || failed) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<img
|
||||
src={faviconUrl}
|
||||
alt=""
|
||||
aria-hidden="true"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
className="mr-1 inline-block size-4 rounded-sm align-[-0.1875em]"
|
||||
onError={() => setFailed(true)}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
// Table utility functions
|
||||
const extractTableData = (tableEl: HTMLTableElement): { headers: string[]; rows: string[][] } => {
|
||||
const headers: string[] = [];
|
||||
@@ -935,15 +956,17 @@ const buildMarkdownComponents = ({
|
||||
},
|
||||
a({ href, children, ...props }) {
|
||||
const targetHref = href ?? '';
|
||||
const isExternal = isExternalHttpUrl(targetHref);
|
||||
const isLoopback = onPreviewLoopback ? isLoopbackHttpUrl(targetHref) : false;
|
||||
return (
|
||||
<>
|
||||
<a
|
||||
{...props}
|
||||
href={href}
|
||||
target={isExternalHttpUrl(targetHref) ? '_blank' : undefined}
|
||||
rel={isExternalHttpUrl(targetHref) ? 'noopener noreferrer' : undefined}
|
||||
target={isExternal ? '_blank' : undefined}
|
||||
rel={isExternal ? 'noopener noreferrer' : undefined}
|
||||
>
|
||||
{isExternal ? <ExternalLinkFavicon href={targetHref} /> : null}
|
||||
{children}
|
||||
</a>
|
||||
{isLoopback && onPreviewLoopback ? (
|
||||
|
||||
Reference in New Issue
Block a user