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.
73 lines
2.0 KiB
73 lines
2.0 KiB
import { useCallback } from 'react'; |
|
|
|
import { useHistory } from 'react-router-dom'; |
|
|
|
import { isFulfilled, isRejected } from '@reduxjs/toolkit'; |
|
|
|
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( |
|
async (element: HTMLAnchorElement) => { |
|
const result = await dispatch(openURL({ url: element.href })); |
|
|
|
if (isFulfilled(result)) { |
|
if (result.payload.accounts[0]) { |
|
history.push(`/@${result.payload.accounts[0].acct}`); |
|
} else if (result.payload.statuses[0]) { |
|
history.push( |
|
`/@${result.payload.statuses[0].account.acct}/${result.payload.statuses[0].id}`, |
|
); |
|
} else { |
|
window.location.href = element.href; |
|
} |
|
} else if (isRejected(result)) { |
|
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(); |
|
void handleMentionClick(target); |
|
} else if (isHashtagClick(target)) { |
|
e.preventDefault(); |
|
handleHashtagClick(target); |
|
} |
|
}, |
|
[handleMentionClick, handleHashtagClick], |
|
); |
|
|
|
return handleClick; |
|
};
|
|
|