Change design of quote posts in web UI (#35584)
This commit is contained in:
parent
39250ab961
commit
92bf55afd0
7 changed files with 210 additions and 109 deletions
63
app/javascript/mastodon/components/learn_more_link.tsx
Normal file
63
app/javascript/mastodon/components/learn_more_link.tsx
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
import { useState, useRef, useCallback, useId } from 'react';
|
||||
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
import Overlay from 'react-overlays/Overlay';
|
||||
|
||||
export const LearnMoreLink: React.FC<{ children: React.ReactNode }> = ({
|
||||
children,
|
||||
}) => {
|
||||
const accessibilityId = useId();
|
||||
const [open, setOpen] = useState(false);
|
||||
const triggerRef = useRef(null);
|
||||
|
||||
const handleClick = useCallback(() => {
|
||||
setOpen(!open);
|
||||
}, [open, setOpen]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<button
|
||||
className='link-button'
|
||||
ref={triggerRef}
|
||||
onClick={handleClick}
|
||||
aria-expanded={open}
|
||||
aria-controls={accessibilityId}
|
||||
>
|
||||
<FormattedMessage
|
||||
id='learn_more_link.learn_more'
|
||||
defaultMessage='Learn more'
|
||||
/>
|
||||
</button>
|
||||
|
||||
<Overlay
|
||||
show={open}
|
||||
rootClose
|
||||
onHide={handleClick}
|
||||
offset={[5, 5]}
|
||||
placement='bottom-end'
|
||||
target={triggerRef}
|
||||
>
|
||||
{({ props }) => (
|
||||
<div
|
||||
{...props}
|
||||
role='region'
|
||||
id={accessibilityId}
|
||||
className='account__domain-pill__popout learn-more__popout dropdown-animation'
|
||||
>
|
||||
<div className='learn-more__popout__content'>{children}</div>
|
||||
|
||||
<div>
|
||||
<button className='link-button' onClick={handleClick}>
|
||||
<FormattedMessage
|
||||
id='learn_more_link.got_it'
|
||||
defaultMessage='Got it'
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</Overlay>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
@ -138,6 +138,16 @@ class StatusContent extends PureComponent {
|
|||
|
||||
onCollapsedToggle(collapsed);
|
||||
}
|
||||
|
||||
// Remove quote fallback link from the DOM so it doesn't
|
||||
// mess with paragraph margins
|
||||
if (!!status.get('quote')) {
|
||||
const inlineQuote = node.querySelector('.quote-inline');
|
||||
|
||||
if (inlineQuote) {
|
||||
inlineQuote.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
handleMouseEnter = ({ currentTarget }) => {
|
||||
|
|
|
|||
|
|
@ -3,19 +3,15 @@ import { useEffect, useMemo } from 'react';
|
|||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
import classNames from 'classnames';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
import type { Map as ImmutableMap } from 'immutable';
|
||||
|
||||
import ArticleIcon from '@/material-icons/400-24px/article.svg?react';
|
||||
import ChevronRightIcon from '@/material-icons/400-24px/chevron_right.svg?react';
|
||||
import { Icon } from 'mastodon/components/icon';
|
||||
import { LearnMoreLink } from 'mastodon/components/learn_more_link';
|
||||
import StatusContainer from 'mastodon/containers/status_container';
|
||||
import type { Status } from 'mastodon/models/status';
|
||||
import type { RootState } from 'mastodon/store';
|
||||
import { useAppDispatch, useAppSelector } from 'mastodon/store';
|
||||
|
||||
import QuoteIcon from '../../images/quote.svg?react';
|
||||
import { fetchStatus } from '../actions/statuses';
|
||||
import { makeGetStatus } from '../selectors';
|
||||
|
||||
|
|
@ -31,7 +27,6 @@ const QuoteWrapper: React.FC<{
|
|||
'status__quote--error': isError,
|
||||
})}
|
||||
>
|
||||
<Icon id='quote' icon={QuoteIcon} className='status__quote-icon' />
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
|
|
@ -45,27 +40,20 @@ const NestedQuoteLink: React.FC<{
|
|||
accountId ? state.accounts.get(accountId) : undefined,
|
||||
);
|
||||
|
||||
const quoteAuthorName = account?.display_name_html;
|
||||
const quoteAuthorName = account?.acct;
|
||||
|
||||
if (!quoteAuthorName) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const quoteAuthorElement = (
|
||||
<span dangerouslySetInnerHTML={{ __html: quoteAuthorName }} />
|
||||
);
|
||||
const quoteUrl = `/@${account.get('acct')}/${status.get('id') as string}`;
|
||||
|
||||
return (
|
||||
<Link to={quoteUrl} className='status__quote-author-button'>
|
||||
<div className='status__quote-author-button'>
|
||||
<FormattedMessage
|
||||
id='status.quote_post_author'
|
||||
defaultMessage='Post by {name}'
|
||||
values={{ name: quoteAuthorElement }}
|
||||
defaultMessage='Quoted a post by @{name}'
|
||||
values={{ name: quoteAuthorName }}
|
||||
/>
|
||||
<Icon id='chevron_right' icon={ChevronRightIcon} />
|
||||
<Icon id='article' icon={ArticleIcon} />
|
||||
</Link>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
@ -112,39 +100,42 @@ export const QuotedStatus: React.FC<{
|
|||
defaultMessage='Hidden due to one of your filters'
|
||||
/>
|
||||
);
|
||||
} else if (quoteState === 'deleted') {
|
||||
quoteError = (
|
||||
<FormattedMessage
|
||||
id='status.quote_error.removed'
|
||||
defaultMessage='This post was removed by its author.'
|
||||
/>
|
||||
);
|
||||
} else if (quoteState === 'unauthorized') {
|
||||
quoteError = (
|
||||
<FormattedMessage
|
||||
id='status.quote_error.unauthorized'
|
||||
defaultMessage='This post cannot be displayed as you are not authorized to view it.'
|
||||
/>
|
||||
);
|
||||
} else if (quoteState === 'pending') {
|
||||
quoteError = (
|
||||
<FormattedMessage
|
||||
id='status.quote_error.pending_approval'
|
||||
defaultMessage='This post is pending approval from the original author.'
|
||||
/>
|
||||
<>
|
||||
<FormattedMessage
|
||||
id='status.quote_error.pending_approval'
|
||||
defaultMessage='Post pending'
|
||||
/>
|
||||
|
||||
<LearnMoreLink>
|
||||
<h6>
|
||||
<FormattedMessage
|
||||
id='status.quote_error.pending_approval_popout.title'
|
||||
defaultMessage='Pending quote? Remain calm'
|
||||
/>
|
||||
</h6>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id='status.quote_error.pending_approval_popout.body'
|
||||
defaultMessage='Quotes shared across the Fediverse may take time to display, as different servers have different protocols.'
|
||||
/>
|
||||
</p>
|
||||
</LearnMoreLink>
|
||||
</>
|
||||
);
|
||||
} else if (quoteState === 'rejected' || quoteState === 'revoked') {
|
||||
} else if (
|
||||
!status ||
|
||||
!quotedStatusId ||
|
||||
quoteState === 'deleted' ||
|
||||
quoteState === 'rejected' ||
|
||||
quoteState === 'revoked' ||
|
||||
quoteState === 'unauthorized'
|
||||
) {
|
||||
quoteError = (
|
||||
<FormattedMessage
|
||||
id='status.quote_error.rejected'
|
||||
defaultMessage='This post cannot be displayed as the original author does not allow it to be quoted.'
|
||||
/>
|
||||
);
|
||||
} else if (!status || !quotedStatusId) {
|
||||
quoteError = (
|
||||
<FormattedMessage
|
||||
id='status.quote_error.not_found'
|
||||
defaultMessage='This post cannot be displayed.'
|
||||
id='status.quote_error.not_available'
|
||||
defaultMessage='Post unavailable'
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
@ -168,7 +159,7 @@ export const QuotedStatus: React.FC<{
|
|||
isQuotedPost
|
||||
id={quotedStatusId}
|
||||
contextType={contextType}
|
||||
avatarSize={40}
|
||||
avatarSize={32}
|
||||
>
|
||||
{canRenderChildQuote && (
|
||||
<QuotedStatus
|
||||
|
|
|
|||
|
|
@ -498,6 +498,8 @@
|
|||
"keyboard_shortcuts.translate": "to translate a post",
|
||||
"keyboard_shortcuts.unfocus": "Unfocus compose textarea/search",
|
||||
"keyboard_shortcuts.up": "Move up in the list",
|
||||
"learn_more_link.got_it": "Got it",
|
||||
"learn_more_link.learn_more": "Learn more",
|
||||
"lightbox.close": "Close",
|
||||
"lightbox.next": "Next",
|
||||
"lightbox.previous": "Previous",
|
||||
|
|
@ -873,12 +875,11 @@
|
|||
"status.open": "Expand this post",
|
||||
"status.pin": "Pin on profile",
|
||||
"status.quote_error.filtered": "Hidden due to one of your filters",
|
||||
"status.quote_error.not_found": "This post cannot be displayed.",
|
||||
"status.quote_error.pending_approval": "This post is pending approval from the original author.",
|
||||
"status.quote_error.rejected": "This post cannot be displayed as the original author does not allow it to be quoted.",
|
||||
"status.quote_error.removed": "This post was removed by its author.",
|
||||
"status.quote_error.unauthorized": "This post cannot be displayed as you are not authorized to view it.",
|
||||
"status.quote_post_author": "Post by {name}",
|
||||
"status.quote_error.not_available": "Post unavailable",
|
||||
"status.quote_error.pending_approval": "Post pending",
|
||||
"status.quote_error.pending_approval_popout.body": "Quotes shared across the Fediverse may take time to display, as different servers have different protocols.",
|
||||
"status.quote_error.pending_approval_popout.title": "Pending quote? Remain calm",
|
||||
"status.quote_post_author": "Quoted a post by @{name}",
|
||||
"status.read_more": "Read more",
|
||||
"status.reblog": "Boost",
|
||||
"status.reblog_private": "Boost with original visibility",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue