mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-07 19:22:14 +09:00
fix(app): only parse markdown in rich embeds (#2948)
This commit is contained in:
@@ -20,6 +20,10 @@ export function hasRichEmbedContent(embed: RichEmbedContentFields): boolean {
|
||||
);
|
||||
}
|
||||
|
||||
export function embedAllowsMarkdown(embed: Pick<MessageEmbed, 'type'>): boolean {
|
||||
return embed.type === MessageEmbedTypes.RICH || embed.type === MessageEmbedTypes.BLUESKY;
|
||||
}
|
||||
|
||||
type MediaOnlyEmbedFields = RichEmbedContentFields & Pick<MessageEmbed, 'image' | 'thumbnail' | 'video' | 'audio'>;
|
||||
|
||||
export function isMediaOnlyEmbed(embed: MediaOnlyEmbedFields): boolean {
|
||||
|
||||
@@ -205,6 +205,7 @@ export const BlueskyEmbed: FC<BlueskyEmbedProps> = observer(
|
||||
<EmbedTitle
|
||||
title={embed.title}
|
||||
url={embed.url}
|
||||
markdown
|
||||
messageId={message.id}
|
||||
channelId={message.channelId}
|
||||
data-flx="channel.embeds.channel-embed.bluesky-embed.embed-title"
|
||||
@@ -212,6 +213,7 @@ export const BlueskyEmbed: FC<BlueskyEmbedProps> = observer(
|
||||
)}
|
||||
<EmbedDescription
|
||||
description={embed.description}
|
||||
markdown
|
||||
messageId={message.id}
|
||||
channelId={message.channelId}
|
||||
data-flx="channel.embeds.channel-embed.bluesky-embed.embed-description"
|
||||
@@ -255,8 +257,6 @@ export const BlueskyEmbed: FC<BlueskyEmbedProps> = observer(
|
||||
<EmbedFooterComponent
|
||||
footer={embed.footer}
|
||||
timestamp={embed.timestamp ? new Date(embed.timestamp) : undefined}
|
||||
messageId={message.id}
|
||||
channelId={message.channelId}
|
||||
data-flx="channel.embeds.channel-embed.bluesky-embed.embed-footer-component"
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -69,47 +69,58 @@ export const EmbedAuthorComponent: FC<{author?: EmbedAuthor}> = observer(({autho
|
||||
</div>
|
||||
);
|
||||
});
|
||||
export const EmbedTitle: FC<{title?: string; url?: string; messageId?: string; channelId?: string}> = observer(
|
||||
({title, url, messageId, channelId}) => {
|
||||
if (title == null || title.length === 0) return null;
|
||||
const options = {
|
||||
context: MarkdownContext.RESTRICTED_INLINE_REPLY,
|
||||
messageId,
|
||||
channelId,
|
||||
disableEmojiInteractions: Boolean(url),
|
||||
};
|
||||
return (
|
||||
<div className={styles.embedTitle} data-flx="channel.embeds.embed.embed-title.embed-title">
|
||||
{url ? (
|
||||
<EmbedLink url={url} data-flx="channel.embeds.channel-embed.embed-parts.embed-title.embed-link">
|
||||
<SafeMarkdown content={title} options={options} data-flx="channel.embeds.embed.embed-title.safe-markdown" />
|
||||
</EmbedLink>
|
||||
) : (
|
||||
<span data-flx="channel.embeds.embed.embed-title.span">
|
||||
<SafeMarkdown
|
||||
content={title}
|
||||
options={options}
|
||||
data-flx="channel.embeds.embed.embed-title.safe-markdown--2"
|
||||
/>
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
},
|
||||
);
|
||||
export const EmbedTitle: FC<{
|
||||
title?: string;
|
||||
url?: string;
|
||||
markdown: boolean;
|
||||
messageId?: string;
|
||||
channelId?: string;
|
||||
}> = observer(({title, url, markdown, messageId, channelId}) => {
|
||||
if (title == null || title.length === 0) return null;
|
||||
const content = markdown ? (
|
||||
<SafeMarkdown
|
||||
content={title}
|
||||
options={{
|
||||
context: MarkdownContext.RESTRICTED_INLINE_REPLY,
|
||||
messageId,
|
||||
channelId,
|
||||
disableEmojiInteractions: Boolean(url),
|
||||
}}
|
||||
data-flx="channel.embeds.embed.embed-title.safe-markdown"
|
||||
/>
|
||||
) : (
|
||||
title
|
||||
);
|
||||
return (
|
||||
<div className={styles.embedTitle} data-flx="channel.embeds.embed.embed-title.embed-title">
|
||||
{url ? (
|
||||
<EmbedLink url={url} data-flx="channel.embeds.channel-embed.embed-parts.embed-title.embed-link">
|
||||
{content}
|
||||
</EmbedLink>
|
||||
) : (
|
||||
<span data-flx="channel.embeds.embed.embed-title.span">{content}</span>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
});
|
||||
export const EmbedDescription: FC<{
|
||||
messageId?: string;
|
||||
channelId?: string;
|
||||
description?: string;
|
||||
}> = observer(({messageId, channelId, description}) => {
|
||||
markdown: boolean;
|
||||
}> = observer(({messageId, channelId, description, markdown}) => {
|
||||
if (!description) return null;
|
||||
return (
|
||||
<div className={styles.embedDescription} data-flx="channel.embeds.embed.embed-description.embed-description">
|
||||
<SafeMarkdown
|
||||
content={description}
|
||||
options={{context: MarkdownContext.RESTRICTED_EMBED_DESCRIPTION, messageId, channelId}}
|
||||
data-flx="channel.embeds.embed.embed-description.safe-markdown"
|
||||
/>
|
||||
{markdown ? (
|
||||
<SafeMarkdown
|
||||
content={description}
|
||||
options={{context: MarkdownContext.RESTRICTED_EMBED_DESCRIPTION, messageId, channelId}}
|
||||
data-flx="channel.embeds.embed.embed-description.safe-markdown"
|
||||
/>
|
||||
) : (
|
||||
description
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
});
|
||||
@@ -182,9 +193,7 @@ export const EmbedFields: FC<{fields?: ReadonlyArray<EmbedField>; messageId?: st
|
||||
export const EmbedFooterComponent: FC<{
|
||||
timestamp?: Date;
|
||||
footer?: EmbedFooter;
|
||||
messageId?: string;
|
||||
channelId?: string;
|
||||
}> = observer(({timestamp, footer, messageId, channelId}) => {
|
||||
}> = observer(({timestamp, footer}) => {
|
||||
const {i18n} = useLingui();
|
||||
const allowIconMotion = useShouldAnimate({kind: 'gif'});
|
||||
const formattedTimestamp = timestamp ? DateUtils.getRelativeDateString(timestamp, i18n) : undefined;
|
||||
@@ -206,13 +215,7 @@ export const EmbedFooterComponent: FC<{
|
||||
/>
|
||||
)}
|
||||
<div className={styles.embedFooterText} data-flx="channel.embeds.embed.embed-footer-component.embed-footer-text">
|
||||
{footer?.text && (
|
||||
<SafeMarkdown
|
||||
content={footer.text}
|
||||
options={{context: MarkdownContext.RESTRICTED_INLINE_REPLY, messageId, channelId}}
|
||||
data-flx="channel.embeds.embed.embed-footer-component.safe-markdown"
|
||||
/>
|
||||
)}
|
||||
{footer?.text}
|
||||
{formattedTimestamp && (
|
||||
<>
|
||||
{footer?.text && (
|
||||
|
||||
@@ -25,6 +25,7 @@ import {
|
||||
} from '@app/features/channel/components/embeds/channel_embed/EmbedParts';
|
||||
import {
|
||||
EMBED_TEXT_OUTER_WIDTH,
|
||||
embedAllowsMarkdown,
|
||||
formatResponsiveEmbedWidth,
|
||||
} from '@app/features/channel/components/embeds/EmbedRenderUtils';
|
||||
import markupStyles from '@app/features/theme/styles/Markup.module.css';
|
||||
@@ -83,6 +84,7 @@ export const RichEmbed: FC<EmbedProps> = observer(
|
||||
<EmbedTitle
|
||||
title={embed.title}
|
||||
url={embed.url}
|
||||
markdown={embedAllowsMarkdown(embed)}
|
||||
messageId={message.id}
|
||||
channelId={message.channelId}
|
||||
data-flx="channel.embeds.channel-embed.rich-embed.embed-title"
|
||||
@@ -90,6 +92,7 @@ export const RichEmbed: FC<EmbedProps> = observer(
|
||||
{!isYouTubeEmbed && (
|
||||
<EmbedDescription
|
||||
description={embed.description}
|
||||
markdown={embedAllowsMarkdown(embed)}
|
||||
messageId={message.id}
|
||||
channelId={message.channelId}
|
||||
data-flx="channel.embeds.channel-embed.rich-embed.embed-description"
|
||||
@@ -127,8 +130,6 @@ export const RichEmbed: FC<EmbedProps> = observer(
|
||||
<EmbedFooterComponent
|
||||
footer={embed.footer}
|
||||
timestamp={embed.timestamp ? new Date(embed.timestamp) : undefined}
|
||||
messageId={message.id}
|
||||
channelId={message.channelId}
|
||||
data-flx="channel.embeds.channel-embed.rich-embed.embed-footer-component"
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
import {embedAllowsMarkdown} from '@app/features/channel/components/embeds/EmbedRenderUtils';
|
||||
import {MarkdownContext} from '@app/features/messaging/components/markdown/renderers/RendererTypes';
|
||||
import type {Message} from '@app/features/messaging/models/MessagingMessage';
|
||||
import {getParserFlagsForContext} from '@app/features/messaging/utils/markdown/MarkdownParserFlags';
|
||||
@@ -193,8 +194,13 @@ export function buildMessageEmbedCopyText(embed: MessageEmbed, options: EmbedCop
|
||||
const blocks: Array<string> = [];
|
||||
appendCopyBlock(blocks, embed.provider?.name);
|
||||
appendCopyBlock(blocks, embed.author?.name);
|
||||
appendCopyBlock(blocks, renderMarkdownCopyText(embed.title, EMBED_INLINE_COPY_PARSER_FLAGS, options));
|
||||
appendCopyBlock(blocks, renderMarkdownCopyText(embed.description, EMBED_DESCRIPTION_COPY_PARSER_FLAGS, options));
|
||||
if (embedAllowsMarkdown(embed)) {
|
||||
appendCopyBlock(blocks, renderMarkdownCopyText(embed.title, EMBED_INLINE_COPY_PARSER_FLAGS, options));
|
||||
appendCopyBlock(blocks, renderMarkdownCopyText(embed.description, EMBED_DESCRIPTION_COPY_PARSER_FLAGS, options));
|
||||
} else {
|
||||
appendCopyBlock(blocks, embed.title);
|
||||
appendCopyBlock(blocks, embed.description);
|
||||
}
|
||||
if (options.includeFields !== false && embed.type !== MessageEmbedTypes.BLUESKY) {
|
||||
for (const field of embed.fields ?? []) {
|
||||
const fieldName = renderMarkdownCopyText(field.name, EMBED_INLINE_COPY_PARSER_FLAGS, options);
|
||||
@@ -202,7 +208,7 @@ export function buildMessageEmbedCopyText(embed: MessageEmbed, options: EmbedCop
|
||||
appendCopyBlock(blocks, joinCopyBlocks([fieldName, fieldValue]));
|
||||
}
|
||||
}
|
||||
appendCopyBlock(blocks, renderMarkdownCopyText(embed.footer?.text, EMBED_INLINE_COPY_PARSER_FLAGS, options));
|
||||
appendCopyBlock(blocks, embed.footer?.text);
|
||||
appendCopyBlock(blocks, getFormattedEmbedTimestamp(embed.timestamp));
|
||||
appendCopyBlock(blocks, embed.image?.description);
|
||||
appendCopyBlock(blocks, embed.thumbnail?.description);
|
||||
|
||||
Reference in New Issue
Block a user