fix(embed): render forwarded embeds identically to real messages (#42)

This commit is contained in:
hampus-fluxer 2026-01-06 03:29:20 +01:00 committed by GitHub
parent 1ed066ca36
commit 73ce85f5a9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 31 additions and 10 deletions

View File

@ -56,7 +56,11 @@
} }
.attachmentsContainer { .attachmentsContainer {
margin-top: 0.5rem; display: flex;
flex-direction: column;
gap: 0.5rem;
align-items: flex-start;
margin-top: var(--message-container-gap, 0.25rem);
} }
.forwardedSourceButton { .forwardedSourceButton {

View File

@ -196,7 +196,14 @@ const ForwardedMessageContent = observer(({message, snapshot}: {message: Message
{snapshot.embeds && snapshot.embeds.length > 0 && UserSettingsStore.getRenderEmbeds() && ( {snapshot.embeds && snapshot.embeds.length > 0 && UserSettingsStore.getRenderEmbeds() && (
<div className={styles.attachmentsContainer}> <div className={styles.attachmentsContainer}>
{snapshot.embeds.map((embed: MessageEmbed, index: number) => ( {snapshot.embeds.map((embed: MessageEmbed, index: number) => (
<Embed embed={embed} key={embed.id} message={message} embedIndex={index} onDelete={() => {}} /> <Embed
embed={embed}
key={embed.id}
message={message}
embedIndex={index}
contextualEmbeds={snapshot.embeds}
onDelete={() => {}}
/>
))} ))}
</div> </div>
)} )}

View File

@ -73,6 +73,7 @@ interface EmbedProps {
message: MessageRecord; message: MessageRecord;
embedIndex?: number; embedIndex?: number;
onDelete?: (bypassConfirm?: boolean) => void; onDelete?: (bypassConfirm?: boolean) => void;
contextualEmbeds?: ReadonlyArray<MessageEmbed>;
} }
interface LinkComponentProps { interface LinkComponentProps {
@ -569,7 +570,8 @@ const EmbedMediaRenderer: FC<{
return null; return null;
}); });
const RichEmbed: FC<EmbedProps> = observer(({embed, message, embedIndex, onDelete}) => { const RichEmbed: FC<EmbedProps> = observer(({embed, message, embedIndex, contextualEmbeds, onDelete}) => {
const embedList = contextualEmbeds ?? message.embeds;
const hasVideo = isValidMedia(embed.video); const hasVideo = isValidMedia(embed.video);
const hasImage = isValidMedia(embed.image); const hasImage = isValidMedia(embed.image);
const hasThumbnail = isValidMedia(embed.thumbnail); const hasThumbnail = isValidMedia(embed.thumbnail);
@ -597,15 +599,15 @@ const RichEmbed: FC<EmbedProps> = observer(({embed, message, embedIndex, onDelet
collectMedia(embed); collectMedia(embed);
for (let i = embedIndex + 1; i < message.embeds.length && images.length < MAX_GALLERY_MEDIA; i++) { for (let i = embedIndex + 1; i < embedList.length && images.length < MAX_GALLERY_MEDIA; i++) {
const candidate = message.embeds[i]; const candidate = embedList[i];
if (!candidate) continue; if (!candidate) continue;
if (normalizeUrl(candidate.url) !== normalizedUrl) break; if (normalizeUrl(candidate.url) !== normalizedUrl) break;
collectMedia(candidate); collectMedia(candidate);
} }
return images; return images;
}, [embed, embedIndex, message.embeds, normalizedUrl]); }, [embed, embedIndex, contextualEmbeds, message.embeds, normalizedUrl]);
const showGallery = galleryImages.length > 1 || (!hasAnyMedia && galleryImages.length > 0); const showGallery = galleryImages.length > 1 || (!hasAnyMedia && galleryImages.length > 0);
const galleryAttachments = useMemo( const galleryAttachments = useMemo(
() => (showGallery ? buildGalleryAttachments(galleryImages, embed, embedIndex) : undefined), () => (showGallery ? buildGalleryAttachments(galleryImages, embed, embedIndex) : undefined),
@ -691,21 +693,23 @@ const RichEmbed: FC<EmbedProps> = observer(({embed, message, embedIndex, onDelet
); );
}); });
export const Embed: FC<EmbedProps> = observer(({embed, message, embedIndex, onDelete}) => { export const Embed: FC<EmbedProps> = observer(({embed, message, embedIndex, contextualEmbeds, onDelete}) => {
const {t} = useLingui(); const {t} = useLingui();
const {enabled: isMobile} = MobileLayoutStore; const {enabled: isMobile} = MobileLayoutStore;
const channel = ChannelStore.getChannel(message.channelId); const channel = ChannelStore.getChannel(message.channelId);
const embedList = contextualEmbeds ?? message.embeds;
const normalizedEmbedUrl = useMemo(() => normalizeUrl(embed.url), [embed.url]); const normalizedEmbedUrl = useMemo(() => normalizeUrl(embed.url), [embed.url]);
const isDuplicateEmbed = useMemo(() => { const isDuplicateEmbed = useMemo(() => {
if (embedIndex === undefined || !normalizedEmbedUrl) return false; if (embedIndex === undefined || !normalizedEmbedUrl) return false;
for (let i = 0; i < embedIndex; i++) { for (let i = 0; i < embedIndex; i++) {
if (normalizeUrl(message.embeds[i]?.url) === normalizedEmbedUrl) { if (normalizeUrl(embedList[i]?.url) === normalizedEmbedUrl) {
return true; return true;
} }
} }
return false; return false;
}, [embedIndex, message.embeds, normalizedEmbedUrl]); }, [embedIndex, contextualEmbeds, message.embeds, normalizedEmbedUrl]);
const canSuppressEmbeds = useCallback(() => { const canSuppressEmbeds = useCallback(() => {
const guild = channel?.guildId ? GuildStore.getGuild(channel.guildId) : null; const guild = channel?.guildId ? GuildStore.getGuild(channel.guildId) : null;
@ -1062,7 +1066,13 @@ export const Embed: FC<EmbedProps> = observer(({embed, message, embedIndex, onDe
<XIcon size={16} weight="bold" /> <XIcon size={16} weight="bold" />
</button> </button>
)} )}
<RichEmbed embed={embed} message={message} embedIndex={embedIndex} onDelete={onDelete} /> <RichEmbed
embed={embed}
message={message}
embedIndex={embedIndex}
contextualEmbeds={contextualEmbeds}
onDelete={onDelete}
/>
</div>, </div>,
); );
}); });