import { useCallback } from 'react'; import type { ComponentProps, FC } from 'react'; import classNames from 'classnames'; import { Link } from 'react-router-dom'; import type { ApiMentionJSON } from '@/flavours/glitch/api_types/statuses'; import type { OnElementHandler } from '@/flavours/glitch/utils/html'; export interface HandledLinkProps { href: string; text: string; prevText?: string; hashtagAccountId?: string; mention?: Pick; } export const HandledLink: FC> = ({ href, text, prevText, hashtagAccountId, mention, className, children, ...props }) => { // Handle hashtags if (text.startsWith('#') || prevText?.endsWith('#')) { const hashtag = text.slice(1).trim(); return ( {children} ); } else if ((text.startsWith('@') || prevText?.endsWith('@')) && mention) { // Handle mentions return ( {children} ); } // Non-absolute paths treated as internal links. This shouldn't happen, but just in case. if (href.startsWith('/')) { return ( {children} ); } return ( {children} ); }; export const useElementHandledLink = ({ hashtagAccountId, hrefToMention, }: { hashtagAccountId?: string; hrefToMention?: (href: string) => ApiMentionJSON | undefined; } = {}) => { const onElement = useCallback( (element, { key, ...props }, children) => { if (element instanceof HTMLAnchorElement) { const mention = hrefToMention?.(element.href); return ( {children} ); } return undefined; }, [hashtagAccountId, hrefToMention], ); return { onElement }; };