You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
61 lines
1.5 KiB
61 lines
1.5 KiB
import { useCallback } from 'react'; |
|
|
|
import { useHistory } from 'react-router-dom'; |
|
|
|
import { openURL } from 'mastodon/actions/search'; |
|
import { useAppDispatch } from 'mastodon/store'; |
|
|
|
const isMentionClick = (element: HTMLAnchorElement) => |
|
element.classList.contains('mention'); |
|
|
|
const isHashtagClick = (element: HTMLAnchorElement) => |
|
element.textContent?.[0] === '#' || |
|
element.previousSibling?.textContent?.endsWith('#'); |
|
|
|
export const useLinks = () => { |
|
const history = useHistory(); |
|
const dispatch = useAppDispatch(); |
|
|
|
const handleHashtagClick = useCallback( |
|
(element: HTMLAnchorElement) => { |
|
const { textContent } = element; |
|
|
|
if (!textContent) return; |
|
|
|
history.push(`/tags/${textContent.replace(/^#/, '')}`); |
|
}, |
|
[history], |
|
); |
|
|
|
const handleMentionClick = useCallback( |
|
(element: HTMLAnchorElement) => { |
|
dispatch( |
|
openURL(element.href, history, () => { |
|
window.location.href = element.href; |
|
}), |
|
); |
|
}, |
|
[dispatch, history], |
|
); |
|
|
|
const handleClick = useCallback( |
|
(e: React.MouseEvent) => { |
|
const target = (e.target as HTMLElement).closest('a'); |
|
|
|
if (!target || e.button !== 0 || e.ctrlKey || e.metaKey) { |
|
return; |
|
} |
|
|
|
if (isMentionClick(target)) { |
|
e.preventDefault(); |
|
handleMentionClick(target); |
|
} else if (isHashtagClick(target)) { |
|
e.preventDefault(); |
|
handleHashtagClick(target); |
|
} |
|
}, |
|
[handleMentionClick, handleHashtagClick], |
|
); |
|
|
|
return handleClick; |
|
};
|
|
|