From 2663f31de304f3b8e052766a5849655ec7e2e402 Mon Sep 17 00:00:00 2001 From: Nico de Haen Date: Mon, 25 Nov 2024 21:49:29 +0100 Subject: [PATCH] Keep line breaks in quoted messages resolves #4345 --- CHANGELOG.md | 1 + .../src/components/message/Message.tsx | 1 + .../src/components/message/MessageBody.tsx | 4 +- .../components/message/MessageMarkdown.tsx | 75 ++++++++++++++++++- 4 files changed, 76 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 014102185a..3295562c7f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ - "Disappearing Messages" dialog not reflecting the actual current value #4327 - accessibility: make settings keyboard-navigable #4319 - Fix documentation for --allow-unsafe-core-replacement #4341 +- fix missing linebreaks in quotes #4345 diff --git a/packages/frontend/src/components/message/Message.tsx b/packages/frontend/src/components/message/Message.tsx index 36807cb350..2a13da5e9b 100644 --- a/packages/frontend/src/components/message/Message.tsx +++ b/packages/frontend/src/components/message/Message.tsx @@ -806,6 +806,7 @@ export const Quote = ({ } disableJumbomoji nonInteractiveContent + isQuote={true} /> diff --git a/packages/frontend/src/components/message/MessageBody.tsx b/packages/frontend/src/components/message/MessageBody.tsx index c798b3b19a..75a3b0b570 100644 --- a/packages/frontend/src/components/message/MessageBody.tsx +++ b/packages/frontend/src/components/message/MessageBody.tsx @@ -10,6 +10,7 @@ function MessageBody({ text, disableJumbomoji, nonInteractiveContent = false, + isQuote = false, }: { text: string disableJumbomoji?: boolean @@ -18,6 +19,7 @@ function MessageBody({ * display them as regular text. */ nonInteractiveContent?: boolean + isQuote?: boolean }): JSX.Element { if (text.length >= UPPER_LIMIT_FOR_PARSED_MESSAGES) { return <>{text} @@ -34,7 +36,7 @@ function MessageBody({ ) } } - return message2React(emojifiedText, nonInteractiveContent) + return message2React(emojifiedText, nonInteractiveContent, isQuote) } const trimRegex = /^[\s\uFEFF\xA0\n\t]+|[\s\uFEFF\xA0\n\t]+$/g diff --git a/packages/frontend/src/components/message/MessageMarkdown.tsx b/packages/frontend/src/components/message/MessageMarkdown.tsx index a2cbdfb613..ec27000e63 100644 --- a/packages/frontend/src/components/message/MessageMarkdown.tsx +++ b/packages/frontend/src/components/message/MessageMarkdown.tsx @@ -30,6 +30,9 @@ SettingsStoreInstance.subscribe(newState => { } }) +/** + * convert elements to HTML elements + */ function renderElement(elm: ParsedElement, key?: number): JSX.Element { switch (elm.t) { case 'CodeBlock': @@ -98,8 +101,11 @@ function renderElement(elm: ParsedElement, key?: number): JSX.Element { } } -/** render in preview mode for ChatListItem summary and for quoted messages, - * not interactive (links can not be clicked) just looks more similar to the message in the chatview/message-list */ +/** + * render in preview mode for ChatListItem summary, + * not interactive (links can not be clicked) just + * looks more similar to the message in the chatview/message-list + */ function renderElementPreview(elm: ParsedElement, key?: number): JSX.Element { switch (elm.t) { case 'CodeBlock': @@ -144,10 +150,71 @@ function renderElementPreview(elm: ParsedElement, key?: number): JSX.Element { } } -export function message2React(message: string, preview: boolean): JSX.Element { +/** + * render in preview mode for quoted messages + * + * not interactive (links can not be clicked), + * but line breaks are preserved + */ +function renderElementQuotePreview( + elm: ParsedElement, + key?: number +): JSX.Element { + switch (elm.t) { + case 'CodeBlock': + case 'InlineCode': + return ( + + {elm.c.content} + + ) + + case 'StrikeThrough': + return {elm.c.map(renderElementQuotePreview)} + + case 'Italics': + return {elm.c.map(renderElementQuotePreview)} + + case 'Bold': + return {elm.c.map(renderElementQuotePreview)} + + case 'Link': + return {elm.c.destination.target} + + case 'LabeledLink': + return ( + {elm.c.label.map(renderElementQuotePreview)} + ) + + case 'Linebreak': + return {'\n'} + + case 'Tag': + case 'EmailAddress': + case 'BotCommandSuggestion': + case 'Text': + return {elm.c} + default: + //@ts-ignore + log.error(`type ${elm.t} not known/implemented yet`, elm) + return ( +
+ {JSON.stringify(elm)} +
+ ) + } +} + +export function message2React( + message: string, + preview: boolean, + quoteView: boolean = false +): JSX.Element { try { const elements = parseMessage(message) - return preview ? ( + return quoteView ? ( +
{elements.map(renderElementQuotePreview)}
+ ) : preview ? (
{elements.map(renderElementPreview)}
) : ( <>{elements.map(renderElement)}