pl-fe: allow to always display links target domain
Signed-off-by: Nicole Mikołajczyk <git@mkljczk.pl>
This commit is contained in:
@ -23,6 +23,21 @@ const GREENTEXT_CLASS = 'dark:text-accent-green text-lime-600';
|
||||
const nodesToText = (nodes: Array<DOMNode>): string =>
|
||||
nodes.map(node => node.type === 'text' ? node.data : node.type === 'tag' ? nodesToText(node.children as Array<DOMNode>) : '').join('');
|
||||
|
||||
const isHostNotVisible = (href: string, nodes: Array<DOMNode>): false | string => {
|
||||
try {
|
||||
const { host } = new URL(href);
|
||||
const text = nodesToText(nodes).trim();
|
||||
|
||||
if (new RegExp(`^(https?://)?(www\.)?${host}(/|$)`).test(text)) {
|
||||
return false;
|
||||
} else {
|
||||
return host;
|
||||
}
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
interface IParsedContent {
|
||||
/** HTML content to display. */
|
||||
html: string;
|
||||
@ -32,7 +47,10 @@ interface IParsedContent {
|
||||
hasQuote?: boolean;
|
||||
/** Related custom emojis. */
|
||||
emojis?: Array<CustomEmoji>;
|
||||
/** Whether to call a function to remove tracking parameters from URLs. */
|
||||
cleanUrls?: boolean;
|
||||
/** Whether to display link target domain when it's not part of the text. */
|
||||
displayTargetHost?: boolean;
|
||||
greentext?: boolean;
|
||||
speakAsCat?: boolean;
|
||||
}
|
||||
@ -81,6 +99,7 @@ function parseContent({
|
||||
hasQuote,
|
||||
emojis,
|
||||
cleanUrls = false,
|
||||
displayTargetHost = true,
|
||||
greentext = false,
|
||||
speakAsCat = false,
|
||||
}: IParsedContent, extractHashtags = false) {
|
||||
@ -158,6 +177,8 @@ function parseContent({
|
||||
}
|
||||
}
|
||||
|
||||
const host = displayTargetHost && isHostNotVisible(href, domNode.children as Array<DOMNode>);
|
||||
|
||||
const fallback = (
|
||||
// eslint-disable-next-line jsx-a11y/no-static-element-interactions
|
||||
<a
|
||||
@ -168,7 +189,10 @@ function parseContent({
|
||||
target='_blank'
|
||||
title={domNode.attribs.href}
|
||||
>
|
||||
{domToReact(domNode.children as DOMNode[], options)}
|
||||
{domToReact(domNode.children as Array<DOMNode>, options)}
|
||||
{host && (
|
||||
<span className='text-xs lowercase'>{' '}[{host}]</span>
|
||||
)}
|
||||
</a>
|
||||
);
|
||||
|
||||
@ -196,7 +220,7 @@ function parseContent({
|
||||
}
|
||||
}
|
||||
|
||||
if (classes?.includes('hashtag')) {
|
||||
if (classes?.includes('hashtag') || domNode.attribs.rel === 'tag') {
|
||||
const hashtag = nodesToText(domNode.children as Array<DOMNode>);
|
||||
if (hashtag) {
|
||||
return <HashtagLink hashtag={hashtag.replace(/^#/, '')} />;
|
||||
@ -248,10 +272,10 @@ function parseContent({
|
||||
}
|
||||
|
||||
const ParsedContent: React.FC<IParsedContent> = React.memo((props) => {
|
||||
const settings = useSettings();
|
||||
const { urlPrivacy } = useSettings();
|
||||
|
||||
if (props.cleanUrls === undefined) {
|
||||
props = { ...props, cleanUrls: settings.urlPrivacy.clearLinksInContent };
|
||||
props = { ...props, cleanUrls: urlPrivacy.clearLinksInContent, displayTargetHost: urlPrivacy.displayTargetHost };
|
||||
}
|
||||
|
||||
return parseContent(props, false);
|
||||
|
||||
@ -147,6 +147,7 @@ const StatusContent: React.FC<IStatusContent> = React.memo(({
|
||||
hasQuote: !!status.quote_id,
|
||||
emojis: status.emojis,
|
||||
cleanUrls: urlPrivacy.clearLinksInContent,
|
||||
displayTargetHost: urlPrivacy.displayTargetHost,
|
||||
greentext,
|
||||
speakAsCat: status.account.speak_as_cat,
|
||||
}, true), [content]);
|
||||
|
||||
@ -26,6 +26,7 @@ const UrlPrivacy = () => {
|
||||
|
||||
const { urlPrivacy } = useSettings();
|
||||
|
||||
const [displayTargetHost, setDisplayTargetHost] = useState(urlPrivacy.displayTargetHost);
|
||||
const [clearLinksInCompose, setClearLinksInCompose] = useState(urlPrivacy.clearLinksInCompose);
|
||||
const [clearLinksInContent, setClearLinksInContent] = useState(urlPrivacy.clearLinksInContent);
|
||||
// const [allowReferralMarketing, setAllowReferralMarketing] = useState(urlPrivacy.allowReferralMarketing);
|
||||
@ -35,6 +36,7 @@ const UrlPrivacy = () => {
|
||||
const onSubmit = () => {
|
||||
dispatch(changeSetting(['urlPrivacy'], {
|
||||
...urlPrivacy,
|
||||
displayTargetHost,
|
||||
clearLinksInCompose,
|
||||
clearLinksInContent,
|
||||
// allowReferralMarketing,
|
||||
@ -58,6 +60,12 @@ const UrlPrivacy = () => {
|
||||
|
||||
<CardBody>
|
||||
<Form onSubmit={onSubmit}>
|
||||
<List>
|
||||
<ListItem label={<FormattedMessage id='url_privacy.display_target_host' defaultMessage='Always display the domain external links lead to' />}>
|
||||
<Toggle checked={displayTargetHost} onChange={({ target }) => setDisplayTargetHost(target.checked)} />
|
||||
</ListItem>
|
||||
</List>
|
||||
|
||||
<List>
|
||||
<ListItem label={<FormattedMessage id='url_privacy.clear_links_in_compose' defaultMessage='Suggest removing tracking parameters when composing a post' />}>
|
||||
<Toggle checked={clearLinksInCompose} onChange={({ target }) => setClearLinksInCompose(target.checked)} />
|
||||
|
||||
@ -1670,6 +1670,7 @@
|
||||
"upload_progress.label": "Uploading…",
|
||||
"url_privacy.clear_links_in_compose": "Suggest removing tracking parameters when composing a post",
|
||||
"url_privacy.clear_links_in_content": "Remove tracking parameters from displayed posts",
|
||||
"url_privacy.display_target_host": "Always display the domain external links lead to",
|
||||
"url_privacy.hash_url.hint": "SHA256 hash of rules database, used to avoid unnecessary fetches, eg. {url}",
|
||||
"url_privacy.hash_url.label": "URL cleaning rules hash address (optional)",
|
||||
"url_privacy.hash_url.placeholder": "Hash URL",
|
||||
|
||||
@ -43,6 +43,7 @@ const settingsSchema = v.object({
|
||||
allowReferralMarketing: v.fallback(v.boolean(), false),
|
||||
rulesUrl: v.fallback(v.string(), ''),
|
||||
hashUrl: v.fallback(v.string(), ''),
|
||||
displayTargetHost: v.fallback(v.boolean(), true),
|
||||
}),
|
||||
|
||||
theme: v.fallback(v.optional(v.object({
|
||||
|
||||
Reference in New Issue
Block a user