import Icon from '../Icon/index.js'; import Card from '../Card/index.js'; import FallbackImage from '../FallbackImage/index.js'; import styles from './styles.module.css'; interface ShareSource { label: string; icon?: string; } export interface ShareCardProps { url: string; title: string; description?: string; image?: string; } const SOURCE_RULES: Array<{ test: RegExp; label: string; icon: string }> = [ { test: /(?:^|\.)(?:x\.com|twitter\.com|t\.co)$/i, label: 'X', icon: 'simple-icons:x', }, { test: /(?:^|\.)github\.com$/i, label: 'GitHub', icon: 'simple-icons:github', }, { test: /(?:^|\.)(?:youtube\.com|youtu\.be)$/i, label: 'YouTube', icon: 'simple-icons:youtube', }, { test: /(?:^|\.)(?:reddit\.com|redd\.it)$/i, label: 'Reddit', icon: 'simple-icons:reddit', }, { test: /(?:^|\.)apple\.com$/i, label: 'Apple', icon: 'simple-icons:apple' }, { test: /(?:^|\.)anthropic\.com$/i, label: 'Anthropic', icon: 'simple-icons:anthropic', }, { test: /(?:^|\.)spotify\.com$/i, label: 'Spotify', icon: 'simple-icons:spotify', }, { test: /(?:^|\.)weixin\.qq\.com$/i, label: 'WeChat', icon: 'simple-icons:wechat', }, { test: /(?:^|\.)bilibili\.com$|^b23\.tv$/i, label: 'bilibili', icon: 'simple-icons:bilibili', }, { test: /(?:^|\.)zhihu\.com$|^zhuanlan\.zhihu\.com$/i, label: 'Zhihu', icon: 'simple-icons:zhihu', }, { test: /(?:^|\.)luogu\.com\.cn$/i, label: 'Luogu', icon: 'simple-icons:luogu', }, { test: /(?:^|\.)codeforces\.com$/i, label: 'Codeforces', icon: 'simple-icons:codeforces', }, ]; function inferSource(url: string): ShareSource { try { const host = new URL(url).hostname.replace(/^www\./, ''); const match = SOURCE_RULES.find((r) => r.test.test(host)); if (match) return { label: match.label, icon: match.icon }; return { label: host, icon: 'lucide:link' }; } catch { return { label: url, icon: 'lucide:link' }; } } export default function ShareCard({ url, title, description, image }: ShareCardProps) { const resolvedSource = inferSource(url); return ( } />

{title}

{resolvedSource.label} {description && ( <> {description} )}
); }