mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-17 13:05:32 +09:00
fix(app): stop rewriting message emoji urls to toggle animation (#1897)
This commit is contained in:
1 parent
3a6bc4bc7b
commit
7a938c85f6
3 files changed
+324
-389
No files matched your search
@@ -281,304 +281,295 @@ const ForwardedFromSource = observer(({message}: {message: Message}) => {
|
|||||||
interface ForwardedMessageContentProps {
|
interface ForwardedMessageContentProps {
|
||||||
message: Message;
|
message: Message;
|
||||||
snapshot: MessageSnapshot;
|
snapshot: MessageSnapshot;
|
||||||
shouldAnimate: boolean;
|
|
||||||
interactionHandlers: Record<string, unknown>;
|
|
||||||
onDelete?: (bypassConfirm?: boolean) => void;
|
onDelete?: (bypassConfirm?: boolean) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ForwardedMessageContent = observer(
|
export const ForwardedMessageContent = observer(({message, snapshot, onDelete}: ForwardedMessageContentProps) => {
|
||||||
({message, snapshot, shouldAnimate, interactionHandlers, onDelete}: ForwardedMessageContentProps) => {
|
const {i18n} = useLingui();
|
||||||
const {i18n} = useLingui();
|
const snapshotIndex = 0;
|
||||||
const snapshotIndex = 0;
|
const snapshotEditedTimestamp = snapshot.edited_timestamp ? new Date(snapshot.edited_timestamp) : null;
|
||||||
const snapshotEditedTimestamp = snapshot.edited_timestamp ? new Date(snapshot.edited_timestamp) : null;
|
const copyText = useMemo(
|
||||||
const copyText = useMemo(
|
() =>
|
||||||
() =>
|
buildMessageSnapshotCopyText(snapshot, {
|
||||||
buildMessageSnapshotCopyText(snapshot, {
|
channelId: message.channelId,
|
||||||
channelId: message.channelId,
|
messageId: message.id,
|
||||||
messageId: message.id,
|
i18n,
|
||||||
i18n,
|
}),
|
||||||
}),
|
[i18n.locale, message.channelId, message.id, snapshot],
|
||||||
[i18n.locale, message.channelId, message.id, snapshot],
|
);
|
||||||
);
|
return (
|
||||||
return (
|
<div
|
||||||
|
className={styles.forwardedContainer}
|
||||||
|
data-message-copy-block={copyText ? 'true' : undefined}
|
||||||
|
data-message-copy-text={copyText || undefined}
|
||||||
|
data-flx="channel.message-attachments.forwarded-message-content.forwarded-container"
|
||||||
|
>
|
||||||
<div
|
<div
|
||||||
className={styles.forwardedContainer}
|
className={styles.forwardedBar}
|
||||||
data-message-copy-block={copyText ? 'true' : undefined}
|
data-flx="channel.message-attachments.forwarded-message-content.forwarded-bar"
|
||||||
data-message-copy-text={copyText || undefined}
|
/>
|
||||||
data-flx="channel.message-attachments.forwarded-message-content.forwarded-container"
|
<div
|
||||||
|
className={styles.forwardedContent}
|
||||||
|
data-flx="channel.message-attachments.forwarded-message-content.forwarded-content"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className={styles.forwardedBar}
|
className={styles.forwardedHeader}
|
||||||
data-flx="channel.message-attachments.forwarded-message-content.forwarded-bar"
|
data-flx="channel.message-attachments.forwarded-message-content.forwarded-header"
|
||||||
/>
|
|
||||||
<div
|
|
||||||
className={styles.forwardedContent}
|
|
||||||
data-flx="channel.message-attachments.forwarded-message-content.forwarded-content"
|
|
||||||
>
|
>
|
||||||
<div
|
<ArrowBendUpRightIcon
|
||||||
className={styles.forwardedHeader}
|
className={styles.forwardedIcon}
|
||||||
data-flx="channel.message-attachments.forwarded-message-content.forwarded-header"
|
weight="bold"
|
||||||
>
|
data-flx="channel.message-attachments.forwarded-message-content.forwarded-icon"
|
||||||
<ArrowBendUpRightIcon
|
|
||||||
className={styles.forwardedIcon}
|
|
||||||
weight="bold"
|
|
||||||
data-flx="channel.message-attachments.forwarded-message-content.forwarded-icon"
|
|
||||||
/>
|
|
||||||
<span
|
|
||||||
className={styles.forwardedLabel}
|
|
||||||
data-flx="channel.message-attachments.forwarded-message-content.forwarded-label"
|
|
||||||
>
|
|
||||||
<Trans>Forwarded</Trans>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
{snapshot.content && (
|
|
||||||
<div
|
|
||||||
className={clsx(markupStyles.markup)}
|
|
||||||
data-search-highlight-scope="message"
|
|
||||||
data-flx="channel.message-attachments.forwarded-message-content.div"
|
|
||||||
>
|
|
||||||
<SafeMarkdown
|
|
||||||
content={snapshot.content}
|
|
||||||
options={{
|
|
||||||
context: MarkdownContext.STANDARD_WITH_JUMBO,
|
|
||||||
messageId: message.id,
|
|
||||||
channelId: message.channelId,
|
|
||||||
mentionChannels: snapshot.mention_channels,
|
|
||||||
}}
|
|
||||||
data-flx="channel.message-attachments.forwarded-message-content.safe-markdown"
|
|
||||||
/>
|
|
||||||
{snapshotEditedTimestamp && (
|
|
||||||
<TimestampWithTooltip
|
|
||||||
date={snapshotEditedTimestamp}
|
|
||||||
className={messageStyles.editedTimestamp}
|
|
||||||
data-flx="channel.message-attachments.forwarded-message-content.timestamp-with-tooltip"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
className={messageStyles.editedLabel}
|
|
||||||
data-flx="channel.message-attachments.forwarded-message-content.span"
|
|
||||||
>
|
|
||||||
{' '}
|
|
||||||
<Trans>(edited)</Trans>
|
|
||||||
</span>
|
|
||||||
</TimestampWithTooltip>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{snapshot.attachments && snapshot.attachments.length > 0 && (
|
|
||||||
<div
|
|
||||||
className={styles.attachmentsContainer}
|
|
||||||
data-flx="channel.message-attachments.forwarded-message-content.attachments-container"
|
|
||||||
>
|
|
||||||
{(() => {
|
|
||||||
const {enrichedAttachments, mediaAttachments, shouldUseMosaic} = getAttachmentRenderingState(
|
|
||||||
snapshot.attachments,
|
|
||||||
);
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
{shouldUseMosaic && (
|
|
||||||
<AttachmentMosaic
|
|
||||||
attachments={mediaAttachments}
|
|
||||||
message={message}
|
|
||||||
snapshotIndex={snapshotIndex}
|
|
||||||
onDelete={onDelete}
|
|
||||||
data-flx="channel.message-attachments.forwarded-message-content.attachment-mosaic"
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
{enrichedAttachments.map((attachment: MessageAttachment) => (
|
|
||||||
<Attachment
|
|
||||||
key={attachment.id}
|
|
||||||
attachment={attachment}
|
|
||||||
snapshotIndex={snapshotIndex}
|
|
||||||
message={message}
|
|
||||||
renderInMosaic={shouldUseMosaic}
|
|
||||||
onDelete={onDelete}
|
|
||||||
data-flx="channel.message-attachments.forwarded-message-content.attachment"
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
})()}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{snapshot.embeds && snapshot.embeds.length > 0 && UserSettings.getRenderEmbeds() && (
|
|
||||||
<div
|
|
||||||
className={styles.attachmentsContainer}
|
|
||||||
data-flx="channel.message-attachments.forwarded-message-content.attachments-container--2"
|
|
||||||
>
|
|
||||||
{snapshot.embeds.map((embed: MessageEmbed, index: number) => {
|
|
||||||
const embedKey = `${embed.id}-${index}`;
|
|
||||||
return (
|
|
||||||
<Embed
|
|
||||||
embed={embed}
|
|
||||||
key={embedKey}
|
|
||||||
message={message}
|
|
||||||
embedIndex={index}
|
|
||||||
contextualEmbeds={snapshot.embeds}
|
|
||||||
onDelete={onDelete}
|
|
||||||
isPreview={true}
|
|
||||||
data-flx="channel.message-attachments.forwarded-message-content.embed"
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{snapshot.stickers && snapshot.stickers.length > 0 && (
|
|
||||||
<div
|
|
||||||
className={styles.stickersContainer}
|
|
||||||
data-flx="channel.message-attachments.forwarded-message-content.stickers-container"
|
|
||||||
>
|
|
||||||
{snapshot.stickers.map((sticker: MessageStickerItem) => (
|
|
||||||
<StickerItem
|
|
||||||
key={sticker.id}
|
|
||||||
sticker={sticker}
|
|
||||||
message={message}
|
|
||||||
shouldAnimate={shouldAnimate}
|
|
||||||
interactionHandlers={interactionHandlers}
|
|
||||||
handleDelete={onDelete}
|
|
||||||
data-flx="channel.message-attachments.forwarded-message-content.sticker-item"
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
<ForwardedFromSource
|
|
||||||
message={message}
|
|
||||||
data-flx="channel.message-attachments.forwarded-message-content.forwarded-from-source"
|
|
||||||
/>
|
/>
|
||||||
|
<span
|
||||||
|
className={styles.forwardedLabel}
|
||||||
|
data-flx="channel.message-attachments.forwarded-message-content.forwarded-label"
|
||||||
|
>
|
||||||
|
<Trans>Forwarded</Trans>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
{snapshot.content && (
|
||||||
|
<div
|
||||||
|
className={clsx(markupStyles.markup)}
|
||||||
|
data-search-highlight-scope="message"
|
||||||
|
data-flx="channel.message-attachments.forwarded-message-content.div"
|
||||||
|
>
|
||||||
|
<SafeMarkdown
|
||||||
|
content={snapshot.content}
|
||||||
|
options={{
|
||||||
|
context: MarkdownContext.STANDARD_WITH_JUMBO,
|
||||||
|
messageId: message.id,
|
||||||
|
channelId: message.channelId,
|
||||||
|
mentionChannels: snapshot.mention_channels,
|
||||||
|
}}
|
||||||
|
data-flx="channel.message-attachments.forwarded-message-content.safe-markdown"
|
||||||
|
/>
|
||||||
|
{snapshotEditedTimestamp && (
|
||||||
|
<TimestampWithTooltip
|
||||||
|
date={snapshotEditedTimestamp}
|
||||||
|
className={messageStyles.editedTimestamp}
|
||||||
|
data-flx="channel.message-attachments.forwarded-message-content.timestamp-with-tooltip"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
className={messageStyles.editedLabel}
|
||||||
|
data-flx="channel.message-attachments.forwarded-message-content.span"
|
||||||
|
>
|
||||||
|
{' '}
|
||||||
|
<Trans>(edited)</Trans>
|
||||||
|
</span>
|
||||||
|
</TimestampWithTooltip>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{snapshot.attachments && snapshot.attachments.length > 0 && (
|
||||||
|
<div
|
||||||
|
className={styles.attachmentsContainer}
|
||||||
|
data-flx="channel.message-attachments.forwarded-message-content.attachments-container"
|
||||||
|
>
|
||||||
|
{(() => {
|
||||||
|
const {enrichedAttachments, mediaAttachments, shouldUseMosaic} = getAttachmentRenderingState(
|
||||||
|
snapshot.attachments,
|
||||||
|
);
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{shouldUseMosaic && (
|
||||||
|
<AttachmentMosaic
|
||||||
|
attachments={mediaAttachments}
|
||||||
|
message={message}
|
||||||
|
snapshotIndex={snapshotIndex}
|
||||||
|
onDelete={onDelete}
|
||||||
|
data-flx="channel.message-attachments.forwarded-message-content.attachment-mosaic"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{enrichedAttachments.map((attachment: MessageAttachment) => (
|
||||||
|
<Attachment
|
||||||
|
key={attachment.id}
|
||||||
|
attachment={attachment}
|
||||||
|
snapshotIndex={snapshotIndex}
|
||||||
|
message={message}
|
||||||
|
renderInMosaic={shouldUseMosaic}
|
||||||
|
onDelete={onDelete}
|
||||||
|
data-flx="channel.message-attachments.forwarded-message-content.attachment"
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
})()}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{snapshot.embeds && snapshot.embeds.length > 0 && UserSettings.getRenderEmbeds() && (
|
||||||
|
<div
|
||||||
|
className={styles.attachmentsContainer}
|
||||||
|
data-flx="channel.message-attachments.forwarded-message-content.attachments-container--2"
|
||||||
|
>
|
||||||
|
{snapshot.embeds.map((embed: MessageEmbed, index: number) => {
|
||||||
|
const embedKey = `${embed.id}-${index}`;
|
||||||
|
return (
|
||||||
|
<Embed
|
||||||
|
embed={embed}
|
||||||
|
key={embedKey}
|
||||||
|
message={message}
|
||||||
|
embedIndex={index}
|
||||||
|
contextualEmbeds={snapshot.embeds}
|
||||||
|
onDelete={onDelete}
|
||||||
|
isPreview={true}
|
||||||
|
data-flx="channel.message-attachments.forwarded-message-content.embed"
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{snapshot.stickers && snapshot.stickers.length > 0 && (
|
||||||
|
<div
|
||||||
|
className={styles.stickersContainer}
|
||||||
|
data-flx="channel.message-attachments.forwarded-message-content.stickers-container"
|
||||||
|
>
|
||||||
|
{snapshot.stickers.map((sticker: MessageStickerItem) => (
|
||||||
|
<StickerItem
|
||||||
|
key={sticker.id}
|
||||||
|
sticker={sticker}
|
||||||
|
message={message}
|
||||||
|
handleDelete={onDelete}
|
||||||
|
data-flx="channel.message-attachments.forwarded-message-content.sticker-item"
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<ForwardedFromSource
|
||||||
|
message={message}
|
||||||
|
data-flx="channel.message-attachments.forwarded-message-content.forwarded-from-source"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
</div>
|
||||||
},
|
);
|
||||||
);
|
});
|
||||||
|
|
||||||
interface StickerItemProps {
|
interface StickerItemProps {
|
||||||
sticker: MessageStickerItem;
|
sticker: MessageStickerItem;
|
||||||
message: Message;
|
message: Message;
|
||||||
shouldAnimate: boolean;
|
|
||||||
interactionHandlers: Record<string, unknown>;
|
|
||||||
sourceChannel?: Channel | null;
|
sourceChannel?: Channel | null;
|
||||||
handleDelete?: (bypassConfirm?: boolean) => void;
|
handleDelete?: (bypassConfirm?: boolean) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const StickerItem = observer(
|
const StickerItem = observer(({sticker, message, sourceChannel, handleDelete}: StickerItemProps) => {
|
||||||
({sticker, message, shouldAnimate, interactionHandlers, sourceChannel, handleDelete}: StickerItemProps) => {
|
const {shouldAnimate, interactionHandlers} = useStickerAnimation({isAnimated: sticker.animated});
|
||||||
const stickerUrl = AvatarUtils.getStickerURL({
|
const stickerUrl = AvatarUtils.getStickerURL({
|
||||||
|
id: sticker.id,
|
||||||
|
animated: shouldAnimate,
|
||||||
|
isAnimatable: sticker.animated,
|
||||||
|
size: 320,
|
||||||
|
});
|
||||||
|
const stickerRecord = Sticker.getStickerById(sticker.id);
|
||||||
|
const guild = stickerRecord?.guildId ? Guilds.getGuild(stickerRecord.guildId) : null;
|
||||||
|
const isMature = !!stickerRecord?.nsfw || !!sticker.nsfw;
|
||||||
|
const {shouldBlur, shouldBlock, canReveal, reveal} = useMatureMedia(isMature, message.channelId);
|
||||||
|
const tooltipContent = () => (
|
||||||
|
<div className={styles.stickerTooltip} data-flx="channel.message-attachments.tooltip-content.sticker-tooltip">
|
||||||
|
<span className={styles.stickerName} data-flx="channel.message-attachments.tooltip-content.sticker-name">
|
||||||
|
{sticker.name}
|
||||||
|
</span>
|
||||||
|
{guild && (
|
||||||
|
<div
|
||||||
|
className={styles.stickerGuildInfo}
|
||||||
|
data-flx="channel.message-attachments.tooltip-content.sticker-guild-info"
|
||||||
|
>
|
||||||
|
<GuildIcon
|
||||||
|
id={guild.id}
|
||||||
|
name={guild.name}
|
||||||
|
icon={guild.icon}
|
||||||
|
className={styles.stickerGuildIcon}
|
||||||
|
sizePx={16}
|
||||||
|
data-flx="channel.message-attachments.tooltip-content.sticker-guild-icon"
|
||||||
|
/>
|
||||||
|
<span
|
||||||
|
className={styles.stickerGuildName}
|
||||||
|
data-flx="channel.message-attachments.tooltip-content.sticker-guild-name"
|
||||||
|
>
|
||||||
|
{guild.name}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
const handleContextMenu = (e: React.MouseEvent) => {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
const stickerForMenu = stickerRecord ?? {
|
||||||
id: sticker.id,
|
id: sticker.id,
|
||||||
animated: shouldAnimate,
|
guildId: '',
|
||||||
size: 320,
|
name: sticker.name,
|
||||||
});
|
description: '',
|
||||||
const stickerRecord = Sticker.getStickerById(sticker.id);
|
tags: [],
|
||||||
const guild = stickerRecord?.guildId ? Guilds.getGuild(stickerRecord.guildId) : null;
|
url: stickerUrl,
|
||||||
const isMature = !!stickerRecord?.nsfw || !!sticker.nsfw;
|
animated: sticker.animated,
|
||||||
const {shouldBlur, shouldBlock, canReveal, reveal} = useMatureMedia(isMature, message.channelId);
|
nsfw: Boolean(sticker.nsfw),
|
||||||
const tooltipContent = () => (
|
user: undefined,
|
||||||
<div className={styles.stickerTooltip} data-flx="channel.message-attachments.tooltip-content.sticker-tooltip">
|
|
||||||
<span className={styles.stickerName} data-flx="channel.message-attachments.tooltip-content.sticker-name">
|
|
||||||
{sticker.name}
|
|
||||||
</span>
|
|
||||||
{guild && (
|
|
||||||
<div
|
|
||||||
className={styles.stickerGuildInfo}
|
|
||||||
data-flx="channel.message-attachments.tooltip-content.sticker-guild-info"
|
|
||||||
>
|
|
||||||
<GuildIcon
|
|
||||||
id={guild.id}
|
|
||||||
name={guild.name}
|
|
||||||
icon={guild.icon}
|
|
||||||
className={styles.stickerGuildIcon}
|
|
||||||
sizePx={16}
|
|
||||||
data-flx="channel.message-attachments.tooltip-content.sticker-guild-icon"
|
|
||||||
/>
|
|
||||||
<span
|
|
||||||
className={styles.stickerGuildName}
|
|
||||||
data-flx="channel.message-attachments.tooltip-content.sticker-guild-name"
|
|
||||||
>
|
|
||||||
{guild.name}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
const handleContextMenu = (e: React.MouseEvent) => {
|
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
const stickerForMenu = stickerRecord ?? {
|
|
||||||
id: sticker.id,
|
|
||||||
guildId: '',
|
|
||||||
name: sticker.name,
|
|
||||||
description: '',
|
|
||||||
tags: [],
|
|
||||||
url: stickerUrl,
|
|
||||||
animated: sticker.animated,
|
|
||||||
nsfw: Boolean(sticker.nsfw),
|
|
||||||
user: undefined,
|
|
||||||
};
|
|
||||||
ContextMenuCommands.openFromEvent(e, ({onClose}) => (
|
|
||||||
<MessageContextMenu
|
|
||||||
message={message}
|
|
||||||
sourceChannel={sourceChannel}
|
|
||||||
onClose={onClose}
|
|
||||||
onDelete={handleDelete!}
|
|
||||||
inlineStickerOrEmojiItems={
|
|
||||||
<StickerInlineMenuItems
|
|
||||||
sticker={stickerForMenu}
|
|
||||||
onClose={onClose}
|
|
||||||
data-flx="channel.message-attachments.handle-context-menu.sticker-inline-menu-items"
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
data-flx="channel.message-attachments.handle-context-menu.message-context-menu"
|
|
||||||
/>
|
|
||||||
));
|
|
||||||
};
|
};
|
||||||
const handleRevealClick = useCallback(
|
ContextMenuCommands.openFromEvent(e, ({onClose}) => (
|
||||||
(e: React.MouseEvent) => {
|
<MessageContextMenu
|
||||||
if (shouldBlur && canReveal) {
|
message={message}
|
||||||
e.preventDefault();
|
sourceChannel={sourceChannel}
|
||||||
e.stopPropagation();
|
onClose={onClose}
|
||||||
reveal();
|
onDelete={handleDelete!}
|
||||||
|
inlineStickerOrEmojiItems={
|
||||||
|
<StickerInlineMenuItems
|
||||||
|
sticker={stickerForMenu}
|
||||||
|
onClose={onClose}
|
||||||
|
data-flx="channel.message-attachments.handle-context-menu.sticker-inline-menu-items"
|
||||||
|
/>
|
||||||
}
|
}
|
||||||
},
|
data-flx="channel.message-attachments.handle-context-menu.message-context-menu"
|
||||||
[shouldBlur, canReveal, reveal],
|
|
||||||
);
|
|
||||||
if (shouldBlock) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
const stickerImage = (
|
|
||||||
<img
|
|
||||||
src={stickerUrl}
|
|
||||||
alt={stickerRecord?.description || sticker.name}
|
|
||||||
className={clsx(styles.stickerImage, shouldBlur && matureStyles.matureStickerBlurred)}
|
|
||||||
width="160"
|
|
||||||
height="160"
|
|
||||||
data-flx="channel.message-attachments.sticker-item.sticker-image"
|
|
||||||
/>
|
/>
|
||||||
);
|
));
|
||||||
return (
|
};
|
||||||
<Tooltip key={sticker.id} text={tooltipContent} data-flx="channel.message-attachments.sticker-item.tooltip">
|
const handleRevealClick = useCallback(
|
||||||
<FocusRing data-flx="channel.message-attachments.sticker-item.focus-ring">
|
(e: React.MouseEvent) => {
|
||||||
<button
|
if (shouldBlur && canReveal) {
|
||||||
type="button"
|
e.preventDefault();
|
||||||
aria-label={stickerRecord?.description || sticker.name}
|
e.stopPropagation();
|
||||||
className={styles.stickerWrapper}
|
reveal();
|
||||||
data-message-sticker="true"
|
}
|
||||||
onContextMenu={handleContextMenu}
|
},
|
||||||
onClick={handleRevealClick}
|
[shouldBlur, canReveal, reveal],
|
||||||
data-flx="channel.message-attachments.sticker-item.sticker-wrapper.reveal-click"
|
);
|
||||||
{...interactionHandlers}
|
if (shouldBlock) {
|
||||||
>
|
return null;
|
||||||
{stickerImage}
|
}
|
||||||
</button>
|
const stickerImage = (
|
||||||
</FocusRing>
|
<img
|
||||||
</Tooltip>
|
src={stickerUrl}
|
||||||
);
|
alt={stickerRecord?.description || sticker.name}
|
||||||
},
|
className={clsx(styles.stickerImage, shouldBlur && matureStyles.matureStickerBlurred)}
|
||||||
);
|
width="160"
|
||||||
|
height="160"
|
||||||
|
data-flx="channel.message-attachments.sticker-item.sticker-image"
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
return (
|
||||||
|
<Tooltip key={sticker.id} text={tooltipContent} data-flx="channel.message-attachments.sticker-item.tooltip">
|
||||||
|
<FocusRing data-flx="channel.message-attachments.sticker-item.focus-ring">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
aria-label={stickerRecord?.description || sticker.name}
|
||||||
|
className={styles.stickerWrapper}
|
||||||
|
data-message-sticker="true"
|
||||||
|
onContextMenu={handleContextMenu}
|
||||||
|
onClick={handleRevealClick}
|
||||||
|
data-flx="channel.message-attachments.sticker-item.sticker-wrapper.reveal-click"
|
||||||
|
{...interactionHandlers}
|
||||||
|
>
|
||||||
|
{stickerImage}
|
||||||
|
</button>
|
||||||
|
</FocusRing>
|
||||||
|
</Tooltip>
|
||||||
|
);
|
||||||
|
});
|
||||||
export const MessageAttachments = observer(() => {
|
export const MessageAttachments = observer(() => {
|
||||||
const {channel, message, handleDelete, previewContext, onPopoutToggle, suppressMessageActions} =
|
const {channel, message, handleDelete, previewContext, onPopoutToggle, suppressMessageActions} =
|
||||||
useMessageViewContext();
|
useMessageViewContext();
|
||||||
const isPreview = Boolean(previewContext);
|
const isPreview = Boolean(previewContext);
|
||||||
const reactionsIsPreview = isPreview || Boolean(suppressMessageActions);
|
const reactionsIsPreview = isPreview || Boolean(suppressMessageActions);
|
||||||
const reactions = useMessageReactionsSnapshot(message.id);
|
const reactions = useMessageReactionsSnapshot(message.id);
|
||||||
const {shouldAnimate, interactionHandlers} = useStickerAnimation();
|
|
||||||
const spoileredUrlEmbeds = useMemo(() => {
|
const spoileredUrlEmbeds = useMemo(() => {
|
||||||
const embeddableCodeLinkContent = extractEmbeddableCodeLinkContent(message.content);
|
const embeddableCodeLinkContent = extractEmbeddableCodeLinkContent(message.content);
|
||||||
return {
|
return {
|
||||||
@@ -593,8 +584,6 @@ export const MessageAttachments = observer(() => {
|
|||||||
<ForwardedMessageContent
|
<ForwardedMessageContent
|
||||||
message={message}
|
message={message}
|
||||||
snapshot={message.messageSnapshots[0]}
|
snapshot={message.messageSnapshots[0]}
|
||||||
shouldAnimate={shouldAnimate}
|
|
||||||
interactionHandlers={interactionHandlers}
|
|
||||||
onDelete={handleDelete}
|
onDelete={handleDelete}
|
||||||
data-flx="channel.message-attachments.forwarded-message-content"
|
data-flx="channel.message-attachments.forwarded-message-content"
|
||||||
/>
|
/>
|
||||||
@@ -648,8 +637,6 @@ export const MessageAttachments = observer(() => {
|
|||||||
key={sticker.id}
|
key={sticker.id}
|
||||||
sticker={sticker}
|
sticker={sticker}
|
||||||
message={message}
|
message={message}
|
||||||
shouldAnimate={shouldAnimate}
|
|
||||||
interactionHandlers={interactionHandlers}
|
|
||||||
sourceChannel={channel}
|
sourceChannel={channel}
|
||||||
handleDelete={handleDelete}
|
handleDelete={handleDelete}
|
||||||
data-flx="channel.message-attachments.sticker-item"
|
data-flx="channel.message-attachments.sticker-item"
|
||||||
|
|||||||
@@ -47,13 +47,11 @@ export const ReplyPreview = observer(
|
|||||||
message,
|
message,
|
||||||
channelId,
|
channelId,
|
||||||
guildId,
|
guildId,
|
||||||
animateEmoji,
|
|
||||||
messageDisplayCompact,
|
messageDisplayCompact,
|
||||||
}: {
|
}: {
|
||||||
message: Message;
|
message: Message;
|
||||||
channelId: string;
|
channelId: string;
|
||||||
guildId?: string;
|
guildId?: string;
|
||||||
animateEmoji: boolean;
|
|
||||||
messageDisplayCompact: boolean;
|
messageDisplayCompact: boolean;
|
||||||
}) => {
|
}) => {
|
||||||
const {i18n} = useLingui();
|
const {i18n} = useLingui();
|
||||||
@@ -63,14 +61,15 @@ export const ReplyPreview = observer(
|
|||||||
);
|
);
|
||||||
const {isMessageRevealed} = useCollapsedMessageVisibility();
|
const {isMessageRevealed} = useCollapsedMessageVisibility();
|
||||||
const resolvedGuildId = guildId ?? message.guildId ?? message.messageReference?.guild_id;
|
const resolvedGuildId = guildId ?? message.guildId ?? message.messageReference?.guild_id;
|
||||||
|
const referenceChannelId = message.messageReference?.channel_id ?? message.channelId;
|
||||||
const jumpToRepliedMessage = useCallback(() => {
|
const jumpToRepliedMessage = useCallback(() => {
|
||||||
if (message.messageReference?.message_id) {
|
if (message.messageReference?.message_id) {
|
||||||
goToMessage(message.channelId, message.messageReference.message_id, {
|
goToMessage(referenceChannelId, message.messageReference.message_id, {
|
||||||
returnToMessageId: message.id,
|
returnToMessageId: message.id,
|
||||||
returnChannelId: message.channelId,
|
returnChannelId: message.channelId,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, [message.channelId, message.id, message.messageReference]);
|
}, [referenceChannelId, message.channelId, message.id, message.messageReference]);
|
||||||
if (!message.messageReference) return null;
|
if (!message.messageReference) return null;
|
||||||
if (resolution.state !== MessageReferenceState.LOADED) {
|
if (resolution.state !== MessageReferenceState.LOADED) {
|
||||||
const isDeleted = resolution.state === MessageReferenceState.DELETED;
|
const isDeleted = resolution.state === MessageReferenceState.DELETED;
|
||||||
@@ -253,7 +252,6 @@ export const ReplyPreview = observer(
|
|||||||
context: MarkdownContext.RESTRICTED_INLINE_REPLY,
|
context: MarkdownContext.RESTRICTED_INLINE_REPLY,
|
||||||
messageId: referencedMessage.id,
|
messageId: referencedMessage.id,
|
||||||
channelId,
|
channelId,
|
||||||
disableAnimatedEmoji: !animateEmoji,
|
|
||||||
mentionChannels: referencedMessage.mentionChannels,
|
mentionChannels: referencedMessage.mentionChannels,
|
||||||
}}
|
}}
|
||||||
data-flx="channel.reply-preview.safe-markdown"
|
data-flx="channel.reply-preview.safe-markdown"
|
||||||
|
|||||||
@@ -2,11 +2,6 @@
|
|||||||
|
|
||||||
import Accessibility from '@app/features/accessibility/state/Accessibility';
|
import Accessibility from '@app/features/accessibility/state/Accessibility';
|
||||||
import {SILENT_MENTION} from '@app/features/app/config/I18nDisplayConstants';
|
import {SILENT_MENTION} from '@app/features/app/config/I18nDisplayConstants';
|
||||||
import {
|
|
||||||
getAnimatedMediaPlaybackAllowed,
|
|
||||||
subscribeAnimatedMediaPlaybackChange,
|
|
||||||
useAnimatedMediaPlaybackAllowed,
|
|
||||||
} from '@app/features/app/hooks/useAnimatedMediaPlayback';
|
|
||||||
import {UserTag} from '@app/features/channel/components/ChannelUserTag';
|
import {UserTag} from '@app/features/channel/components/ChannelUserTag';
|
||||||
import {CompactAuthorPrefix, CompactMessageLayout} from '@app/features/channel/components/CompactMessageLayout';
|
import {CompactAuthorPrefix, CompactMessageLayout} from '@app/features/channel/components/CompactMessageLayout';
|
||||||
import {EditingMessageInput} from '@app/features/channel/components/EditingMessageInput';
|
import {EditingMessageInput} from '@app/features/channel/components/EditingMessageInput';
|
||||||
@@ -14,7 +9,6 @@ import {isMediaOnlyEmbed} from '@app/features/channel/components/embeds/EmbedRen
|
|||||||
import {MessageAttachments} from '@app/features/channel/components/MessageAttachments';
|
import {MessageAttachments} from '@app/features/channel/components/MessageAttachments';
|
||||||
import {MessageAuthorInfo} from '@app/features/channel/components/MessageAuthorInfo';
|
import {MessageAuthorInfo} from '@app/features/channel/components/MessageAuthorInfo';
|
||||||
import {MessageAvatar} from '@app/features/channel/components/MessageAvatar';
|
import {MessageAvatar} from '@app/features/channel/components/MessageAvatar';
|
||||||
import {shouldAnimateMessageEmojiByDefault} from '@app/features/channel/components/MessageEmojiAnimationUtils';
|
|
||||||
import {MessageTimeoutIndicator} from '@app/features/channel/components/MessageTimeoutIndicator';
|
import {MessageTimeoutIndicator} from '@app/features/channel/components/MessageTimeoutIndicator';
|
||||||
import {MessageUsername} from '@app/features/channel/components/MessageUsername';
|
import {MessageUsername} from '@app/features/channel/components/MessageUsername';
|
||||||
import {useMessageViewContext} from '@app/features/channel/components/MessageViewContext';
|
import {useMessageViewContext} from '@app/features/channel/components/MessageViewContext';
|
||||||
@@ -55,9 +49,8 @@ import {msg} from '@lingui/core/macro';
|
|||||||
import {Trans, useLingui} from '@lingui/react/macro';
|
import {Trans, useLingui} from '@lingui/react/macro';
|
||||||
import {ArrowsClockwiseIcon, BellSlashIcon, EyeIcon, WarningCircleIcon} from '@phosphor-icons/react';
|
import {ArrowsClockwiseIcon, BellSlashIcon, EyeIcon, WarningCircleIcon} from '@phosphor-icons/react';
|
||||||
import {clsx} from 'clsx';
|
import {clsx} from 'clsx';
|
||||||
import {autorun} from 'mobx';
|
|
||||||
import {observer} from 'mobx-react-lite';
|
import {observer} from 'mobx-react-lite';
|
||||||
import {type MouseEvent, useCallback, useEffect, useMemo, useState} from 'react';
|
import {type MouseEvent, useCallback, useMemo} from 'react';
|
||||||
|
|
||||||
const JUMP_TO_MESSAGE_FROM_SENT_DESCRIPTOR = msg({
|
const JUMP_TO_MESSAGE_FROM_SENT_DESCRIPTOR = msg({
|
||||||
message: 'Jump to message from {displayName}, sent {formattedDate}',
|
message: 'Jump to message from {displayName}, sent {formattedDate}',
|
||||||
@@ -86,22 +79,6 @@ const MessageStateToClassName: Record<string, string> = {
|
|||||||
[MessageStates.FAILED]: styles.messageFailed,
|
[MessageStates.FAILED]: styles.messageFailed,
|
||||||
};
|
};
|
||||||
const CUSTOM_EMOJI_MARKDOWN_PATTERN = /<a?:[a-zA-Z0-9_+-]{2,}:([0-9]+)>/g;
|
const CUSTOM_EMOJI_MARKDOWN_PATTERN = /<a?:[a-zA-Z0-9_+-]{2,}:([0-9]+)>/g;
|
||||||
const getDefaultMessageEmojiAnimationAllowed = (): boolean =>
|
|
||||||
shouldAnimateMessageEmojiByDefault({
|
|
||||||
animateEmojiSetting: UserSettings.getAnimateEmoji(),
|
|
||||||
animatedMediaPlaybackAllowed: getAnimatedMediaPlaybackAllowed(),
|
|
||||||
});
|
|
||||||
const setMessageEmojiImagesAnimated = (messageId: string, shouldAnimate: boolean): void => {
|
|
||||||
const emojiImgs = document.querySelectorAll(
|
|
||||||
`img[data-message-id="${messageId}"][data-animated="true"]`,
|
|
||||||
) as NodeListOf<HTMLImageElement>;
|
|
||||||
for (const img of emojiImgs) {
|
|
||||||
const url = new URL(img.src, window.location.origin);
|
|
||||||
url.searchParams.set('animated', shouldAnimate.toString());
|
|
||||||
img.src = url.toString();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function messageContentCopyBlockProps(content: string): {
|
function messageContentCopyBlockProps(content: string): {
|
||||||
'data-message-copy-block'?: 'true';
|
'data-message-copy-block'?: 'true';
|
||||||
'data-message-copy-text'?: string;
|
'data-message-copy-text'?: string;
|
||||||
@@ -122,8 +99,6 @@ export const UserMessage = observer(() => {
|
|||||||
previewOverrides,
|
previewOverrides,
|
||||||
onHeadingActivate,
|
onHeadingActivate,
|
||||||
} = useMessageViewContext();
|
} = useMessageViewContext();
|
||||||
const [animateEmoji, setAnimateEmoji] = useState(getDefaultMessageEmojiAnimationAllowed);
|
|
||||||
const animatedMediaPlaybackAllowed = useAnimatedMediaPlaybackAllowed();
|
|
||||||
const isEditing = MessageEdit.isEditing(message.channelId, message.id);
|
const isEditing = MessageEdit.isEditing(message.channelId, message.id);
|
||||||
const userAuthor = Users.getUser(message.author.id);
|
const userAuthor = Users.getUser(message.author.id);
|
||||||
const author = message.webhookId != null ? message.author : (userAuthor ?? message.author);
|
const author = message.webhookId != null ? message.author : (userAuthor ?? message.author);
|
||||||
@@ -155,6 +130,15 @@ export const UserMessage = observer(() => {
|
|||||||
}),
|
}),
|
||||||
[message.content],
|
[message.content],
|
||||||
);
|
);
|
||||||
|
const markdownOptions = useMemo(
|
||||||
|
() => ({
|
||||||
|
context: MarkdownContext.STANDARD_WITH_JUMBO,
|
||||||
|
messageId: message.id,
|
||||||
|
channelId: message.channelId,
|
||||||
|
mentionChannels: message.mentionChannels,
|
||||||
|
}),
|
||||||
|
[message.id, message.channelId, message.mentionChannels],
|
||||||
|
);
|
||||||
const shouldHideContent =
|
const shouldHideContent =
|
||||||
UserSettings.getRenderEmbeds() &&
|
UserSettings.getRenderEmbeds() &&
|
||||||
message.embeds.length > 0 &&
|
message.embeds.length > 0 &&
|
||||||
@@ -312,12 +296,7 @@ export const UserMessage = observer(() => {
|
|||||||
>
|
>
|
||||||
<SafeMarkdown
|
<SafeMarkdown
|
||||||
content={message.content}
|
content={message.content}
|
||||||
options={{
|
options={markdownOptions}
|
||||||
context: MarkdownContext.STANDARD_WITH_JUMBO,
|
|
||||||
messageId: message.id,
|
|
||||||
channelId: message.channelId,
|
|
||||||
mentionChannels: message.mentionChannels,
|
|
||||||
}}
|
|
||||||
data-flx="channel.user-message.render-message-content.safe-markdown"
|
data-flx="channel.user-message.render-message-content.safe-markdown"
|
||||||
/>
|
/>
|
||||||
{(message.editedTimestamp || message.isEditing) &&
|
{(message.editedTimestamp || message.isEditing) &&
|
||||||
@@ -346,6 +325,7 @@ export const UserMessage = observer(() => {
|
|||||||
}, [
|
}, [
|
||||||
shouldShowEditingInput,
|
shouldShowEditingInput,
|
||||||
shouldHideContent,
|
shouldHideContent,
|
||||||
|
markdownOptions,
|
||||||
message,
|
message,
|
||||||
message.content,
|
message.content,
|
||||||
message.id,
|
message.id,
|
||||||
@@ -357,25 +337,6 @@ export const UserMessage = observer(() => {
|
|||||||
onSubmit,
|
onSubmit,
|
||||||
i18n,
|
i18n,
|
||||||
]);
|
]);
|
||||||
useEffect(() => {
|
|
||||||
if (animateEmoji) return;
|
|
||||||
setMessageEmojiImagesAnimated(message.id, animatedMediaPlaybackAllowed && isHovering);
|
|
||||||
}, [animateEmoji, animatedMediaPlaybackAllowed, isHovering, message.id]);
|
|
||||||
useEffect(() => {
|
|
||||||
const updateDefaultEmojiAnimation = () => {
|
|
||||||
const shouldAnimate = getDefaultMessageEmojiAnimationAllowed();
|
|
||||||
setAnimateEmoji(shouldAnimate);
|
|
||||||
setMessageEmojiImagesAnimated(message.id, shouldAnimate);
|
|
||||||
};
|
|
||||||
const disposer = autorun(() => {
|
|
||||||
updateDefaultEmojiAnimation();
|
|
||||||
});
|
|
||||||
const unsubscribePlayback = subscribeAnimatedMediaPlaybackChange(updateDefaultEmojiAnimation);
|
|
||||||
return () => {
|
|
||||||
disposer();
|
|
||||||
unsubscribePlayback();
|
|
||||||
};
|
|
||||||
}, [message.id]);
|
|
||||||
const renderFailedFooter = useCallback(() => {
|
const renderFailedFooter = useCallback(() => {
|
||||||
if (!shouldShowFailedFooter) {
|
if (!shouldShowFailedFooter) {
|
||||||
return null;
|
return null;
|
||||||
@@ -469,12 +430,7 @@ export const UserMessage = observer(() => {
|
|||||||
>
|
>
|
||||||
<SafeMarkdown
|
<SafeMarkdown
|
||||||
content={message.content}
|
content={message.content}
|
||||||
options={{
|
options={markdownOptions}
|
||||||
context: MarkdownContext.STANDARD_WITH_JUMBO,
|
|
||||||
messageId: message.id,
|
|
||||||
channelId: message.channelId,
|
|
||||||
mentionChannels: message.mentionChannels,
|
|
||||||
}}
|
|
||||||
data-flx="channel.user-message.safe-markdown"
|
data-flx="channel.user-message.safe-markdown"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -523,7 +479,6 @@ export const UserMessage = observer(() => {
|
|||||||
message={message}
|
message={message}
|
||||||
channelId={channel.id}
|
channelId={channel.id}
|
||||||
guildId={channel.guildId}
|
guildId={channel.guildId}
|
||||||
animateEmoji={animateEmoji}
|
|
||||||
messageDisplayCompact={messageDisplayCompact}
|
messageDisplayCompact={messageDisplayCompact}
|
||||||
data-flx="channel.user-message.reply-preview"
|
data-flx="channel.user-message.reply-preview"
|
||||||
/>
|
/>
|
||||||
@@ -559,37 +514,30 @@ export const UserMessage = observer(() => {
|
|||||||
>
|
>
|
||||||
{showMetadata && compactAuthorPrefix}
|
{showMetadata && compactAuthorPrefix}
|
||||||
{!shouldHideContent && (
|
{!shouldHideContent && (
|
||||||
<>
|
<SafeMarkdown
|
||||||
<SafeMarkdown
|
content={message.content}
|
||||||
content={message.content}
|
options={markdownOptions}
|
||||||
options={{
|
data-flx="channel.user-message.safe-markdown--2"
|
||||||
context: MarkdownContext.STANDARD_WITH_JUMBO,
|
/>
|
||||||
messageId: message.id,
|
|
||||||
channelId: message.channelId,
|
|
||||||
mentionChannels: message.mentionChannels,
|
|
||||||
}}
|
|
||||||
data-flx="channel.user-message.safe-markdown--2"
|
|
||||||
/>
|
|
||||||
{(message.editedTimestamp || message.isEditing) &&
|
|
||||||
(message.isEditing ? (
|
|
||||||
<span className={styles.editedLabel} data-flx="channel.user-message.edited-label">
|
|
||||||
{' '}
|
|
||||||
{i18n._(EDITED_DESCRIPTOR)}
|
|
||||||
</span>
|
|
||||||
) : (
|
|
||||||
<TimestampWithTooltip
|
|
||||||
date={message.editedTimestamp!}
|
|
||||||
className={styles.editedTimestamp}
|
|
||||||
data-flx="channel.user-message.edited-timestamp"
|
|
||||||
>
|
|
||||||
<span className={styles.editedLabel} data-flx="channel.user-message.edited-label--2">
|
|
||||||
{' '}
|
|
||||||
{i18n._(EDITED_DESCRIPTOR)}
|
|
||||||
</span>
|
|
||||||
</TimestampWithTooltip>
|
|
||||||
))}
|
|
||||||
</>
|
|
||||||
)}
|
)}
|
||||||
|
{(message.editedTimestamp || message.isEditing) &&
|
||||||
|
(message.isEditing ? (
|
||||||
|
<span className={styles.editedLabel} data-flx="channel.user-message.edited-label">
|
||||||
|
{' '}
|
||||||
|
{i18n._(EDITED_DESCRIPTOR)}
|
||||||
|
</span>
|
||||||
|
) : (
|
||||||
|
<TimestampWithTooltip
|
||||||
|
date={message.editedTimestamp!}
|
||||||
|
className={styles.editedTimestamp}
|
||||||
|
data-flx="channel.user-message.edited-timestamp"
|
||||||
|
>
|
||||||
|
<span className={styles.editedLabel} data-flx="channel.user-message.edited-label--2">
|
||||||
|
{' '}
|
||||||
|
{i18n._(EDITED_DESCRIPTOR)}
|
||||||
|
</span>
|
||||||
|
</TimestampWithTooltip>
|
||||||
|
))}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -608,7 +556,6 @@ export const UserMessage = observer(() => {
|
|||||||
message={message}
|
message={message}
|
||||||
channelId={channel.id}
|
channelId={channel.id}
|
||||||
guildId={channel.guildId}
|
guildId={channel.guildId}
|
||||||
animateEmoji={animateEmoji}
|
|
||||||
messageDisplayCompact={messageDisplayCompact}
|
messageDisplayCompact={messageDisplayCompact}
|
||||||
data-flx="channel.user-message.reply-preview--2"
|
data-flx="channel.user-message.reply-preview--2"
|
||||||
/>
|
/>
|
||||||
@@ -770,28 +717,32 @@ export const UserMessage = observer(() => {
|
|||||||
/>
|
/>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
)}
|
)}
|
||||||
{(message.editedTimestamp || message.isEditing) &&
|
|
||||||
(message.isEditing ? (
|
|
||||||
<span className={styles.editedLabel} data-flx="channel.user-message.edited-label--3">
|
|
||||||
{' '}
|
|
||||||
{i18n._(EDITED_DESCRIPTOR)}
|
|
||||||
</span>
|
|
||||||
) : (
|
|
||||||
<TimestampWithTooltip
|
|
||||||
date={message.editedTimestamp!}
|
|
||||||
className={styles.editedTimestamp}
|
|
||||||
data-flx="channel.user-message.edited-timestamp--2"
|
|
||||||
>
|
|
||||||
<span className={styles.editedLabel} data-flx="channel.user-message.edited-label--4">
|
|
||||||
{' '}
|
|
||||||
{i18n._(EDITED_DESCRIPTOR)}
|
|
||||||
</span>
|
|
||||||
</TimestampWithTooltip>
|
|
||||||
))}
|
|
||||||
</AuthorHeading>
|
</AuthorHeading>
|
||||||
)}
|
)}
|
||||||
{((!message.content && !isEditing) || (shouldHideContent && !isEditing)) &&
|
{shouldHideContent &&
|
||||||
shouldGroup &&
|
!isEditing &&
|
||||||
|
message.content.length > 0 &&
|
||||||
|
(message.editedTimestamp || message.isEditing) &&
|
||||||
|
(message.isEditing ? (
|
||||||
|
<span className={styles.editedLabel} data-flx="channel.user-message.edited-label--3">
|
||||||
|
{' '}
|
||||||
|
{i18n._(EDITED_DESCRIPTOR)}
|
||||||
|
</span>
|
||||||
|
) : (
|
||||||
|
<TimestampWithTooltip
|
||||||
|
date={message.editedTimestamp!}
|
||||||
|
className={styles.editedTimestamp}
|
||||||
|
data-flx="channel.user-message.edited-timestamp--2"
|
||||||
|
>
|
||||||
|
<span className={styles.editedLabel} data-flx="channel.user-message.edited-label--4">
|
||||||
|
{' '}
|
||||||
|
{i18n._(EDITED_DESCRIPTOR)}
|
||||||
|
</span>
|
||||||
|
</TimestampWithTooltip>
|
||||||
|
))}
|
||||||
|
<MessageAttachments data-flx="channel.user-message.message-attachments--3" />
|
||||||
|
{message.content.length === 0 &&
|
||||||
|
!isEditing &&
|
||||||
(message.editedTimestamp || message.isEditing) &&
|
(message.editedTimestamp || message.isEditing) &&
|
||||||
(message.isEditing ? (
|
(message.isEditing ? (
|
||||||
<span className={styles.editedLabel} data-flx="channel.user-message.edited-label--5">
|
<span className={styles.editedLabel} data-flx="channel.user-message.edited-label--5">
|
||||||
@@ -810,7 +761,6 @@ export const UserMessage = observer(() => {
|
|||||||
</span>
|
</span>
|
||||||
</TimestampWithTooltip>
|
</TimestampWithTooltip>
|
||||||
))}
|
))}
|
||||||
<MessageAttachments data-flx="channel.user-message.message-attachments--3" />
|
|
||||||
{renderFailedFooter()}
|
{renderFailedFooter()}
|
||||||
</div>
|
</div>
|
||||||
</SpoilerSyncProvider>
|
</SpoilerSyncProvider>
|
||||||
|
|||||||
Reference in new issue
Block a user