mirror of
https://github.com/glitch-soc/mastodon.git
synced 2025-12-14 00:08:46 +00:00
[Glitch] Emoji: Statuses
Port 0c1ca6c969 to glitch-soc
Signed-off-by: Claire <claire.github-309c@sitedethib.com>
This commit is contained in:
@@ -1,25 +1,48 @@
|
||||
import type { List } from 'immutable';
|
||||
|
||||
import type { CustomEmoji } from '../models/custom_emoji';
|
||||
import type { Status } from '../models/status';
|
||||
|
||||
import { EmojiHTML } from './emoji/html';
|
||||
import type { IconName } from './media_icon';
|
||||
import { MediaIcon } from './media_icon';
|
||||
import { StatusBanner, BannerVariant } from './status_banner';
|
||||
|
||||
export const ContentWarning: React.FC<{
|
||||
text: string;
|
||||
status: Status;
|
||||
expanded?: boolean;
|
||||
onClick?: () => void;
|
||||
icons?: IconName[];
|
||||
}> = ({ text, expanded, onClick, icons }) => (
|
||||
<StatusBanner
|
||||
expanded={expanded}
|
||||
onClick={onClick}
|
||||
variant={BannerVariant.Warning}
|
||||
>
|
||||
{icons?.map((icon) => (
|
||||
<MediaIcon
|
||||
className='status__content__spoiler-icon'
|
||||
icon={icon}
|
||||
key={`icon-${icon}`}
|
||||
}> = ({ status, expanded, onClick, icons }) => {
|
||||
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}
|
||||
>
|
||||
{icons?.map((icon) => (
|
||||
<MediaIcon
|
||||
className='status__content__spoiler-icon'
|
||||
icon={icon}
|
||||
key={`icon-${icon}`}
|
||||
/>
|
||||
))}
|
||||
<EmojiHTML
|
||||
as='span'
|
||||
htmlString={text}
|
||||
extraEmojis={status.get('emoji') as List<CustomEmoji>}
|
||||
/>
|
||||
))}
|
||||
<span dangerouslySetInnerHTML={{ __html: text }} />
|
||||
</StatusBanner>
|
||||
);
|
||||
</StatusBanner>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -8,6 +8,7 @@ import classNames from 'classnames';
|
||||
import { animated, useSpring } from '@react-spring/web';
|
||||
import escapeTextContentForBrowser from 'escape-html';
|
||||
|
||||
import { EmojiHTML } from '@/flavours/glitch/components/emoji/html';
|
||||
import CheckIcon from '@/material-icons/400-24px/check.svg?react';
|
||||
import { openModal } from 'flavours/glitch/actions/modal';
|
||||
import { fetchPoll, vote } from 'flavours/glitch/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 {
|
||||
prepend: PropTypes.string,
|
||||
withDismiss: PropTypes.bool,
|
||||
isQuotedPost: PropTypes.bool,
|
||||
shouldHighlightOnMount: PropTypes.bool,
|
||||
shouldHighlightOnMount: PropTypes.bool,
|
||||
getScrollPosition: PropTypes.func,
|
||||
updateScrollBottom: PropTypes.func,
|
||||
expanded: PropTypes.bool,
|
||||
@@ -739,7 +739,7 @@ class Status extends ImmutablePureComponent {
|
||||
</header>
|
||||
)}
|
||||
|
||||
{status.get('spoiler_text').length > 0 && <ContentWarning text={status.getIn(['translation', 'spoilerHtml']) || status.get('spoilerHtml')} expanded={expanded} onClick={this.handleExpandedToggle} icons={mediaIcons} />}
|
||||
<ContentWarning status={status} expanded={expanded} onClick={this.handleExpandedToggle} icons={mediaIcons} />
|
||||
|
||||
{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>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user