Emoji: Statuses (#36393)

This commit is contained in:
Echo authored and GitHub committed 2025-10-08 14:18:11 +00:00
1 parent 2b213e9b1b
commit 0c1ca6c969
14 files changed
+121 -78

No files matched your search

@@ -1,15 +1,38 @@
import type { List } from 'immutable';
import type { CustomEmoji } from '../models/custom_emoji';
import type { Status } from '../models/status';
import { EmojiHTML } from './emoji/html';
import { StatusBanner, BannerVariant } from './status_banner';
export const ContentWarning: React.FC<{
text: string;
status: Status;
expanded?: boolean;
onClick?: () => void;
}> = ({ text, expanded, onClick }) => (
<StatusBanner
expanded={expanded}
onClick={onClick}
variant={BannerVariant.Warning}
>
<span dangerouslySetInnerHTML={{ __html: text }} />
</StatusBanner>
);
}> = ({ status, expanded, onClick }) => {
const hasSpoiler = !!status.get('spoiler_text');
if (!hasSpoiler) {
return null;
}
const text =
status.getIn(['translation', 'spoilerHtml']) || status.get('spoilerHtml');
if (typeof text !== 'string' || text.length === 0) {
return null;
}
return (
<StatusBanner
expanded={expanded}
onClick={onClick}
variant={BannerVariant.Warning}
>
<EmojiHTML
as='span'
htmlString={text}
extraEmojis={status.get('emoji') as List<CustomEmoji>}
/>
</StatusBanner>
);
};
+4 -2
View File
@@ -8,6 +8,7 @@ import classNames from 'classnames';
import { animated, useSpring } from '@react-spring/web';
import escapeTextContentForBrowser from 'escape-html';
import { EmojiHTML } from '@/mastodon/components/emoji/html';
import CheckIcon from '@/material-icons/400-24px/check.svg?react';
import { openModal } from 'mastodon/actions/modal';
import { fetchPoll, vote } from 'mastodon/actions/polls';
@@ -305,10 +306,11 @@ const PollOption: React.FC<PollOptionProps> = (props) => {
</span>
)}
<span
<EmojiHTML
className='poll__option__text translate'
lang={lang}
dangerouslySetInnerHTML={{ __html: titleHtml }}
htmlString={titleHtml}
extraEmojis={poll.emojis}
/>
{!!voted && (
@@ -118,7 +118,7 @@ class Status extends ImmutablePureComponent {
unread: PropTypes.bool,
showThread: PropTypes.bool,
isQuotedPost: PropTypes.bool,
shouldHighlightOnMount: PropTypes.bool,
shouldHighlightOnMount: PropTypes.bool,
getScrollPosition: PropTypes.func,
updateScrollBottom: PropTypes.func,
cacheMediaWidth: PropTypes.func,
@@ -600,7 +600,7 @@ class Status extends ImmutablePureComponent {
{matchedFilters && <FilterWarning title={matchedFilters.join(', ')} expanded={this.state.showDespiteFilter} onClick={this.handleFilterToggle} />}
{(status.get('spoiler_text').length > 0 && (!matchedFilters || this.state.showDespiteFilter)) && <ContentWarning text={status.getIn(['translation', 'spoilerHtml']) || status.get('spoilerHtml')} expanded={expanded} onClick={this.handleExpandedToggle} />}
{(!matchedFilters || this.state.showDespiteFilter) && <ContentWarning status={status} expanded={expanded} onClick={this.handleExpandedToggle} />}
{expanded && (
<>
@@ -83,14 +83,15 @@ export const HandledLink: FC<HandledLinkProps & ComponentProps<'a'>> = ({
export const useElementHandledLink = ({
hashtagAccountId,
mentionAccountId,
hrefToMentionAccountId,
}: {
hashtagAccountId?: string;
mentionAccountId?: string;
hrefToMentionAccountId?: (href: string) => string | undefined;
} = {}) => {
const onElement = useCallback<OnElementHandler>(
(element, { key, ...props }) => {
if (element instanceof HTMLAnchorElement) {
const mentionId = hrefToMentionAccountId?.(element.href);
return (
<HandledLink
{...props}
@@ -98,13 +99,13 @@ export const useElementHandledLink = ({
href={element.href}
text={element.innerText}
hashtagAccountId={hashtagAccountId}
mentionAccountId={mentionAccountId}
mentionAccountId={mentionId}
/>
);
}
return undefined;
},
[hashtagAccountId, mentionAccountId],
[hashtagAccountId, hrefToMentionAccountId],
);
return { onElement };
};
@@ -3,6 +3,8 @@ import { useCallback, useRef, useId } from 'react';
import { FormattedMessage } from 'react-intl';
import { AnimateEmojiProvider } from './emoji/context';
export enum BannerVariant {
Warning = 'warning',
Filter = 'filter',
@@ -34,8 +36,7 @@ export const StatusBanner: React.FC<{
return (
// Element clicks are passed on to button
// eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions
<div
<AnimateEmojiProvider
className={
variant === BannerVariant.Warning
? 'content-warning'
@@ -69,6 +70,6 @@ export const StatusBanner: React.FC<{
/>
)}
</button>
</div>
</AnimateEmojiProvider>
);
};