From 5f5ffc746b09bc06a8c61c73a2d6927c75f62fc2 Mon Sep 17 00:00:00 2001 From: Mohamad Jaara <9083456+MohamadJaara@users.noreply.github.com> Date: Sat, 9 May 2026 10:26:50 +0200 Subject: [PATCH 1/5] feat: add option to disable message preprocessing in the internal app configuration --- .gitignore | 1 + .../ConfigToolbar/ConfigToolbar.tsx | 24 ++++++++ .../script/components/InputBar/InputBar.tsx | 25 +++++++-- .../InputBarEditor/InputBarEditor.tsx | 3 + .../RichTextEditor/RichTextEditor.tsx | 28 ++++++---- .../PlainTextPastePlugin.tsx | 55 +++++++++++++++++++ .../plugins/PlainTextPastePlugin/index.ts | 20 +++++++ .../RichTextEditor/utils/transformMessage.ts | 9 +++ .../utils/useEditorDraftState.ts | 18 ++++-- .../useMessageHandling/useMessageHandling.ts | 3 + .../useMessageSend/useMessageSend.ts | 6 +- .../util/debugMessagePreprocessingUtil.ts | 34 ++++++++++++ apps/webapp/src/script/util/debugUtil.ts | 9 +++ 13 files changed, 214 insertions(+), 21 deletions(-) create mode 100644 apps/webapp/src/script/components/InputBar/InputBarEditor/RichTextEditor/plugins/PlainTextPastePlugin/PlainTextPastePlugin.tsx create mode 100644 apps/webapp/src/script/components/InputBar/InputBarEditor/RichTextEditor/plugins/PlainTextPastePlugin/index.ts create mode 100644 apps/webapp/src/script/util/debugMessagePreprocessingUtil.ts diff --git a/.gitignore b/.gitignore index c5585e1d744..07a8203ce4e 100644 --- a/.gitignore +++ b/.gitignore @@ -44,3 +44,4 @@ dist/ lib/ plans/ +/.codex/ diff --git a/apps/webapp/src/script/components/ConfigToolbar/ConfigToolbar.tsx b/apps/webapp/src/script/components/ConfigToolbar/ConfigToolbar.tsx index 6bd16cb0957..3e92236190b 100644 --- a/apps/webapp/src/script/components/ConfigToolbar/ConfigToolbar.tsx +++ b/apps/webapp/src/script/components/ConfigToolbar/ConfigToolbar.tsx @@ -48,6 +48,9 @@ export function ConfigToolbar() { const [videoBackgroundEffectsFeatureEnabled, setVideoBackgroundEffectsFeatureEnabled] = useState( window.wire?.app?.debug?.isVideoBackgroundEffectsFeatureEnabled() ?? false, ); + const [isMessagePreprocessingDisabled, setIsMessagePreprocessingDisabled] = useState( + window.wire?.app?.debug?.isMessagePreprocessingDisabled() ?? false, + ); const [coreCryptoLevel, setCoreCryptoLevel] = useState(CoreCryptoLogLevel.Info); // Toggle config tool on 'cmd/ctrl + shift + 2' @@ -264,6 +267,23 @@ export function ConfigToolbar() { ); }; + const renderMessagePreprocessingSwitch = () => { + return ( +
+ + { + setIsMessagePreprocessingDisabled(window.wire?.app?.debug?.disableMessagePreprocessing(isChecked) === true); + }} + /> +
+ ); + }; + const renderCoreCryptoLogLevelSelect = () => { const options: Array<{label: string; value: CoreCryptoLogLevel}> = [ {label: 'Off', value: CoreCryptoLogLevel.Off}, @@ -351,6 +371,10 @@ export function ConfigToolbar() {
+
{renderMessagePreprocessingSwitch()}
+ +
+
{renderCoreCryptoLogLevelSelect()}

diff --git a/apps/webapp/src/script/components/InputBar/InputBar.tsx b/apps/webapp/src/script/components/InputBar/InputBar.tsx index a09c77aab91..632b28ed3a6 100644 --- a/apps/webapp/src/script/components/InputBar/InputBar.tsx +++ b/apps/webapp/src/script/components/InputBar/InputBar.tsx @@ -17,7 +17,7 @@ * */ -import {useCallback, useRef, useState} from 'react'; +import {useCallback, useEffect, useRef, useState} from 'react'; import {amplify} from 'amplify'; import cx from 'classnames'; @@ -45,6 +45,7 @@ import {TeamState} from 'Repositories/team/TeamState'; import {EventName} from 'Repositories/tracking/EventName'; import {CONVERSATION_TYPING_INDICATOR_MODE} from 'Repositories/user/TypingIndicatorMode'; import {useKoSubscribableChildren} from 'Util/componentUtil'; +import {DISABLE_MESSAGE_PREPROCESSING_EVENT, isMessagePreprocessingDisabled} from 'Util/debugMessagePreprocessingUtil'; import {t} from 'Util/localizerUtil'; import {TIME_IN_MILLIS} from 'Util/timeUtil'; @@ -148,6 +149,7 @@ export const InputBar = ({ * It's directly derived from the editor state */ const [messageContent, setMessageContent] = useState({text: ''}); + const [disableMessagePreprocessing, setDisableMessagePreprocessing] = useState(isMessagePreprocessingDisabled); const formatToolbar = useFormatToolbar(); @@ -206,6 +208,19 @@ export const InputBar = ({ () => propertiesRepository.getPreference(PROPERTIES_TYPE.INTERFACE.MARKDOWN_PREVIEW), WebAppEvents.PROPERTIES.UPDATE.INTERFACE.MARKDOWN_PREVIEW, ); + const effectiveShowMarkdownPreview = showMarkdownPreview && !disableMessagePreprocessing; + + useEffect(() => { + const handleMessagePreprocessingChange = (event: Event) => { + setDisableMessagePreprocessing((event as CustomEvent).detail ?? isMessagePreprocessingDisabled()); + }; + + window.addEventListener(DISABLE_MESSAGE_PREPROCESSING_EVENT, handleMessagePreprocessingChange); + + return () => { + window.removeEventListener(DISABLE_MESSAGE_PREPROCESSING_EVENT, handleMessagePreprocessingChange); + }; + }, []); const { editedMessage, @@ -232,6 +247,7 @@ export const InputBar = ({ editorRef, pastedFile: fileHandling.pastedFile, sendPastedFile: fileHandling.sendPastedFile, + disableMessagePreprocessing, }); if (fileHandling.pastedFile && !!isCellsEnabled) { @@ -281,7 +297,7 @@ export const InputBar = ({
@@ -303,7 +319,7 @@ export const InputBar = ({ editedMessage={editedMessage} inputPlaceholder={inputPlaceholder} hasLocalEphemeralTimer={hasLocalEphemeralTimer} - showMarkdownPreview={showMarkdownPreview} + showMarkdownPreview={effectiveShowMarkdownPreview} formatToolbar={formatToolbar} onSetup={editor => { editorRef.current = editor; @@ -321,6 +337,7 @@ export const InputBar = ({ getMentionCandidates={getMentionCandidates} saveDraftState={draftState.save} loadDraftState={draftState.load} + disableMessagePreprocessing={disableMessagePreprocessing} replaceEmojis={shouldReplaceEmoji} > {!!files.length && } @@ -332,7 +349,7 @@ export const InputBar = ({ messageContent={messageContent} isEditing={isEditing} isSendingDisabled={isSendingDisabled} - showMarkdownPreview={showMarkdownPreview} + showMarkdownPreview={effectiveShowMarkdownPreview} showGiphyButton={giphy.showGiphyButton} formatToolbar={formatToolbar} emojiPicker={emojiPicker} diff --git a/apps/webapp/src/script/components/InputBar/InputBarEditor/InputBarEditor.tsx b/apps/webapp/src/script/components/InputBar/InputBarEditor/InputBarEditor.tsx index 879e3e24416..1c3a9dfed35 100644 --- a/apps/webapp/src/script/components/InputBar/InputBarEditor/InputBarEditor.tsx +++ b/apps/webapp/src/script/components/InputBar/InputBarEditor/InputBarEditor.tsx @@ -49,6 +49,7 @@ interface InputBarEditorProps { getMentionCandidates: (search?: string | null) => User[]; saveDraftState: (editorState: string, plainMessage: string, replyId?: string) => void; loadDraftState: () => Promise; + disableMessagePreprocessing: boolean; replaceEmojis: boolean; children: React.ReactNode; } @@ -70,6 +71,7 @@ export const InputBarEditor = ({ getMentionCandidates, saveDraftState, loadDraftState, + disableMessagePreprocessing, replaceEmojis, children, }: InputBarEditorProps) => { @@ -83,6 +85,7 @@ export const InputBarEditor = ({ onEscape={onEscape} onArrowUp={onArrowUp} getMentionCandidates={getMentionCandidates} + disableMessagePreprocessing={disableMessagePreprocessing} replaceEmojis={replaceEmojis} placeholder={inputPlaceholder} onUpdate={onUpdate} diff --git a/apps/webapp/src/script/components/InputBar/InputBarEditor/RichTextEditor/RichTextEditor.tsx b/apps/webapp/src/script/components/InputBar/InputBarEditor/RichTextEditor/RichTextEditor.tsx index a7ef923fcf0..af01a09ccad 100644 --- a/apps/webapp/src/script/components/InputBar/InputBarEditor/RichTextEditor/RichTextEditor.tsx +++ b/apps/webapp/src/script/components/InputBar/InputBarEditor/RichTextEditor/RichTextEditor.tsx @@ -54,11 +54,12 @@ import {ListItemTabIndentationPlugin} from './plugins/ListIndentationPlugin/List import {ListMaxIndentLevelPlugin} from './plugins/ListMaxIndentLevelPlugin/ListMaxIndentLevelPlugin'; import {MentionsPlugin} from './plugins/MentionsPlugin'; import {PastePlugin} from './plugins/PastePlugin/PastePlugin'; +import {PlainTextPastePlugin} from './plugins/PlainTextPastePlugin'; import {ReplaceCarriageReturnPlugin} from './plugins/ReplaceCarriageReturnPlugin/ReplaceCarriageReturnPlugin'; import {SendPlugin} from './plugins/SendPlugin/SendPlugin'; import {markdownTransformers} from './utils/markdownTransformers'; import {parseMentions} from './utils/parseMentions'; -import {transformMessage} from './utils/transformMessage'; +import {getRawMessageText, transformMessage} from './utils/transformMessage'; import {useEditorDraftState} from './utils/useEditorDraftState'; interface RichTextEditorProps { @@ -69,6 +70,7 @@ interface RichTextEditorProps { hasLocalEphemeralTimer: boolean; showFormatToolbar: boolean; showMarkdownPreview: boolean; + disableMessagePreprocessing: boolean; getMentionCandidates: (search?: string | null) => User[]; saveDraftState: (editor: string, plainMessage: string, replyId?: string) => void; loadDraftState: () => Promise; @@ -89,6 +91,7 @@ export const RichTextEditor = ({ editedMessage, showFormatToolbar, showMarkdownPreview, + disableMessagePreprocessing, onUpdate, saveDraftState, loadDraftState, @@ -108,6 +111,7 @@ export const RichTextEditor = ({ editorRef, saveDraftState, replaceEmojis, + disableMessagePreprocessing, }); const handleChange = (editorState: EditorState) => { @@ -116,13 +120,14 @@ export const RichTextEditor = ({ return; } - const markdown = $convertToMarkdownString(markdownTransformers, undefined, true); - - const text = transformMessage({replaceEmojis, markdown}); + const markdown = disableMessagePreprocessing + ? '' + : $convertToMarkdownString(markdownTransformers, undefined, true); + const text = disableMessagePreprocessing ? getRawMessageText() : transformMessage({replaceEmojis, markdown}); onUpdate({ text, - mentions: parseMentions(editorRef.current, markdown, getMentionCandidates()), + mentions: parseMentions(editorRef.current, text, getMentionCandidates()), }); saveDraft(); @@ -145,11 +150,11 @@ export const RichTextEditor = ({ /> - + {!disableMessagePreprocessing && } - {replaceEmojis && } - + {replaceEmojis && !disableMessagePreprocessing && } + {!disableMessagePreprocessing && } {showMarkdownPreview && ( <> @@ -177,12 +182,15 @@ export const RichTextEditor = ({ { - if (!mentionsOpen.current && !emojiPickerOpen.current) { + if (!mentionsOpen.current && (disableMessagePreprocessing || !emojiPickerOpen.current)) { onSend(); } }} /> - + {!disableMessagePreprocessing && ( + + )} + {disableMessagePreprocessing && }
{showFormatToolbar && showMarkdownPreview && ( diff --git a/apps/webapp/src/script/components/InputBar/InputBarEditor/RichTextEditor/plugins/PlainTextPastePlugin/PlainTextPastePlugin.tsx b/apps/webapp/src/script/components/InputBar/InputBarEditor/RichTextEditor/plugins/PlainTextPastePlugin/PlainTextPastePlugin.tsx new file mode 100644 index 00000000000..038fc6e42b1 --- /dev/null +++ b/apps/webapp/src/script/components/InputBar/InputBarEditor/RichTextEditor/plugins/PlainTextPastePlugin/PlainTextPastePlugin.tsx @@ -0,0 +1,55 @@ +/* + * Wire + * Copyright (C) 2026 Wire Swiss GmbH + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + * + */ + +import {useCallback, useEffect} from 'react'; + +import {useLexicalComposerContext} from '@lexical/react/LexicalComposerContext'; +import {$getSelection, $isRangeSelection, COMMAND_PRIORITY_HIGH, PASTE_COMMAND} from 'lexical'; + +export const PlainTextPastePlugin = (): null => { + const [editor] = useLexicalComposerContext(); + + const handlePaste = useCallback( + (event: ClipboardEvent) => { + const plainText = event.clipboardData?.getData('text/plain'); + + if (plainText === undefined) { + return false; + } + + editor.update(() => { + const selection = $getSelection(); + + if ($isRangeSelection(selection)) { + selection.insertText(plainText); + } + }); + + event.preventDefault(); + return true; + }, + [editor], + ); + + useEffect(() => { + return editor.registerCommand(PASTE_COMMAND, handlePaste, COMMAND_PRIORITY_HIGH); + }, [editor, handlePaste]); + + return null; +}; diff --git a/apps/webapp/src/script/components/InputBar/InputBarEditor/RichTextEditor/plugins/PlainTextPastePlugin/index.ts b/apps/webapp/src/script/components/InputBar/InputBarEditor/RichTextEditor/plugins/PlainTextPastePlugin/index.ts new file mode 100644 index 00000000000..5cf0db90727 --- /dev/null +++ b/apps/webapp/src/script/components/InputBar/InputBarEditor/RichTextEditor/plugins/PlainTextPastePlugin/index.ts @@ -0,0 +1,20 @@ +/* + * Wire + * Copyright (C) 2026 Wire Swiss GmbH + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + * + */ + +export * from './PlainTextPastePlugin'; diff --git a/apps/webapp/src/script/components/InputBar/InputBarEditor/RichTextEditor/utils/transformMessage.ts b/apps/webapp/src/script/components/InputBar/InputBarEditor/RichTextEditor/utils/transformMessage.ts index 2984b10c42a..536093f3404 100644 --- a/apps/webapp/src/script/components/InputBar/InputBarEditor/RichTextEditor/utils/transformMessage.ts +++ b/apps/webapp/src/script/components/InputBar/InputBarEditor/RichTextEditor/utils/transformMessage.ts @@ -17,8 +17,17 @@ * */ +import {$getRoot} from 'lexical'; + import {findAndTransformEmoji} from '../plugins/InlineEmojiReplacementPlugin'; export const transformMessage = ({replaceEmojis, markdown}: {replaceEmojis: boolean; markdown: string}) => { return replaceEmojis ? findAndTransformEmoji(markdown) : markdown; }; + +export const getRawMessageText = () => { + return $getRoot() + .getChildren() + .map(node => node.getTextContent()) + .join('\n'); +}; diff --git a/apps/webapp/src/script/components/InputBar/InputBarEditor/RichTextEditor/utils/useEditorDraftState.ts b/apps/webapp/src/script/components/InputBar/InputBarEditor/RichTextEditor/utils/useEditorDraftState.ts index 8254277de64..ee1860b83af 100644 --- a/apps/webapp/src/script/components/InputBar/InputBarEditor/RichTextEditor/utils/useEditorDraftState.ts +++ b/apps/webapp/src/script/components/InputBar/InputBarEditor/RichTextEditor/utils/useEditorDraftState.ts @@ -24,7 +24,7 @@ import {LexicalEditor} from 'lexical'; import {useDebouncedCallback} from 'use-debounce'; import {markdownTransformers} from './markdownTransformers'; -import {transformMessage} from './transformMessage'; +import {getRawMessageText, transformMessage} from './transformMessage'; const DRAFT_SAVE_DELAY = 800; @@ -32,9 +32,15 @@ interface UseEditorDraftStateProps { editorRef: RefObject; saveDraftState: (editorState: string, plainMessage: string, replyId?: string) => void; replaceEmojis: boolean; + disableMessagePreprocessing: boolean; } -export const useEditorDraftState = ({editorRef, saveDraftState, replaceEmojis}: UseEditorDraftStateProps) => { +export const useEditorDraftState = ({ + editorRef, + saveDraftState, + replaceEmojis, + disableMessagePreprocessing, +}: UseEditorDraftStateProps) => { const saveDraft = useCallback(() => { const editor = editorRef.current; if (!editor) { @@ -42,14 +48,16 @@ export const useEditorDraftState = ({editorRef, saveDraftState, replaceEmojis}: } editor.getEditorState().read(() => { - const markdown = $convertToMarkdownString(markdownTransformers, undefined, true); + const markdown = disableMessagePreprocessing + ? '' + : $convertToMarkdownString(markdownTransformers, undefined, true); saveDraftState( JSON.stringify(editor.getEditorState().toJSON()), - transformMessage({replaceEmojis, markdown}), + disableMessagePreprocessing ? getRawMessageText() : transformMessage({replaceEmojis, markdown}), undefined, ); }); - }, [editorRef, saveDraftState, replaceEmojis]); + }, [editorRef, saveDraftState, replaceEmojis, disableMessagePreprocessing]); const debouncedSaveDraftState = useDebouncedCallback(saveDraft, DRAFT_SAVE_DELAY); diff --git a/apps/webapp/src/script/components/InputBar/useMessageHandling/useMessageHandling.ts b/apps/webapp/src/script/components/InputBar/useMessageHandling/useMessageHandling.ts index 3e81649a649..5762a890571 100644 --- a/apps/webapp/src/script/components/InputBar/useMessageHandling/useMessageHandling.ts +++ b/apps/webapp/src/script/components/InputBar/useMessageHandling/useMessageHandling.ts @@ -51,6 +51,7 @@ interface UseMessageHandlingProps { editorRef: React.RefObject; pastedFile: File | null; sendPastedFile: () => void; + disableMessagePreprocessing: boolean; } export const useMessageHandling = ({ @@ -64,6 +65,7 @@ export const useMessageHandling = ({ editorRef, pastedFile, sendPastedFile, + disableMessagePreprocessing, }: UseMessageHandlingProps) => { const {isEditing, editedMessage, editMessage: editMessageCallback, cancelMessageEditing} = useMessageEditing(); @@ -132,6 +134,7 @@ export const useMessageHandling = ({ pastedFile, sendPastedFile, messageContent, + disableMessagePreprocessing, }); const editMessage = useCallback( diff --git a/apps/webapp/src/script/components/InputBar/useMessageHandling/useMessageSend/useMessageSend.ts b/apps/webapp/src/script/components/InputBar/useMessageHandling/useMessageSend/useMessageSend.ts index 703a3f8e9d3..521cc777526 100644 --- a/apps/webapp/src/script/components/InputBar/useMessageHandling/useMessageSend/useMessageSend.ts +++ b/apps/webapp/src/script/components/InputBar/useMessageHandling/useMessageSend/useMessageSend.ts @@ -62,6 +62,7 @@ interface UseMessageSendProps { pastedFile: File | null; sendPastedFile: () => void; messageContent: MessageContent; + disableMessagePreprocessing: boolean; } export const useMessageSend = ({ @@ -80,6 +81,7 @@ export const useMessageSend = ({ pastedFile, sendPastedFile, messageContent, + disableMessagePreprocessing, }: UseMessageSendProps) => { const {getFiles, clearAll} = useFileUploadState(); const files = getFiles({conversationId: conversation.id}); @@ -206,8 +208,7 @@ export const useMessageSend = ({ const text = messageContent.text; const mentions = messageContent.mentions ?? []; - const messageTrimmedStart = text.trimStart(); - const messageText = messageTrimmedStart.trimEnd(); + const messageText = disableMessagePreprocessing ? text : text.trimStart().trimEnd(); const config = Config.getConfig(); @@ -245,6 +246,7 @@ export const useMessageSend = ({ isSendingDisabled, sendFiles, clearFiles, + disableMessagePreprocessing, ]); const handleSendMessage = useCallback(async () => { diff --git a/apps/webapp/src/script/util/debugMessagePreprocessingUtil.ts b/apps/webapp/src/script/util/debugMessagePreprocessingUtil.ts new file mode 100644 index 00000000000..c87a81c33bb --- /dev/null +++ b/apps/webapp/src/script/util/debugMessagePreprocessingUtil.ts @@ -0,0 +1,34 @@ +/* + * Wire + * Copyright (C) 2026 Wire Swiss GmbH + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + * + */ + +import {getStorage} from 'Util/localStorage'; + +const DISABLE_MESSAGE_PREPROCESSING_STORAGE_KEY = 'disable-message-preprocessing'; + +export const DISABLE_MESSAGE_PREPROCESSING_EVENT = 'wire:disable-message-preprocessing-change'; + +export const isMessagePreprocessingDisabled = (): boolean => { + return getStorage()?.getItem(DISABLE_MESSAGE_PREPROCESSING_STORAGE_KEY) === 'true'; +}; + +export const setMessagePreprocessingDisabled = (disable: boolean): boolean => { + getStorage()?.setItem(DISABLE_MESSAGE_PREPROCESSING_STORAGE_KEY, `${disable}`); + window.dispatchEvent(new CustomEvent(DISABLE_MESSAGE_PREPROCESSING_EVENT, {detail: disable})); + return disable; +}; diff --git a/apps/webapp/src/script/util/debugUtil.ts b/apps/webapp/src/script/util/debugUtil.ts index 0bca6aa9c9d..88254f44128 100644 --- a/apps/webapp/src/script/util/debugUtil.ts +++ b/apps/webapp/src/script/util/debugUtil.ts @@ -62,6 +62,7 @@ import {UserState} from 'Repositories/user/UserState'; import {getStorage} from 'Util/localStorage'; import {getLogger, Logger} from 'Util/logger'; +import {isMessagePreprocessingDisabled, setMessagePreprocessingDisabled} from './debugMessagePreprocessingUtil'; import {TIME_IN_MILLIS} from './timeUtil'; import {createUuid} from './uuid'; @@ -295,6 +296,14 @@ export class DebugUtil { return this.callingRepository.getBackgroundEffectsHandler().saveFeatureEnabledStateInStore(flag); } + isMessagePreprocessingDisabled(): boolean { + return isMessagePreprocessingDisabled(); + } + + disableMessagePreprocessing(disable: boolean): boolean { + return setMessagePreprocessingDisabled(disable); + } + setupAvsDebugger() { if (this.isEnabledAvsDebugger()) { this.enableAvsDebugger(true); From c7661c96358850cf4a390d205b030d0ea7a7f312 Mon Sep 17 00:00:00 2001 From: Mohamad Jaara <9083456+MohamadJaara@users.noreply.github.com> Date: Tue, 2 Jun 2026 00:01:49 +0200 Subject: [PATCH 2/5] Update apps/webapp/src/script/components/InputBar/InputBarEditor/RichTextEditor/RichTextEditor.tsx Co-authored-by: Zafar Saeed Khan --- .../InputBar/InputBarEditor/RichTextEditor/RichTextEditor.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/webapp/src/script/components/InputBar/InputBarEditor/RichTextEditor/RichTextEditor.tsx b/apps/webapp/src/script/components/InputBar/InputBarEditor/RichTextEditor/RichTextEditor.tsx index af01a09ccad..b495554b1d0 100644 --- a/apps/webapp/src/script/components/InputBar/InputBarEditor/RichTextEditor/RichTextEditor.tsx +++ b/apps/webapp/src/script/components/InputBar/InputBarEditor/RichTextEditor/RichTextEditor.tsx @@ -190,7 +190,9 @@ export const RichTextEditor = ({ {!disableMessagePreprocessing && ( )} - {disableMessagePreprocessing && } + {disableMessagePreprocessing ? () : ( + + )} {showFormatToolbar && showMarkdownPreview && ( From 9dd7a9abc5897ab89d7dfc6f8a1c641c062a3dd1 Mon Sep 17 00:00:00 2001 From: Mohamad Jaara <9083456+MohamadJaara@users.noreply.github.com> Date: Tue, 2 Jun 2026 00:01:58 +0200 Subject: [PATCH 3/5] Update apps/webapp/src/script/components/InputBar/InputBar.tsx Co-authored-by: Zafar Saeed Khan --- apps/webapp/src/script/components/InputBar/InputBar.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/apps/webapp/src/script/components/InputBar/InputBar.tsx b/apps/webapp/src/script/components/InputBar/InputBar.tsx index 632b28ed3a6..b7ccb9863d3 100644 --- a/apps/webapp/src/script/components/InputBar/InputBar.tsx +++ b/apps/webapp/src/script/components/InputBar/InputBar.tsx @@ -212,7 +212,12 @@ export const InputBar = ({ useEffect(() => { const handleMessagePreprocessingChange = (event: Event) => { - setDisableMessagePreprocessing((event as CustomEvent).detail ?? isMessagePreprocessingDisabled()); + const isDisabled = + event instanceof CustomEvent && is.boolean(event.detail) + ? event.detail + : isMessagePreprocessingDisabled(); + + setDisableMessagePreprocessing(isDisabled); }; window.addEventListener(DISABLE_MESSAGE_PREPROCESSING_EVENT, handleMessagePreprocessingChange); From 3e99b3cc6a6cec4a4c3429a0bb4509b59780ec10 Mon Sep 17 00:00:00 2001 From: Mohamad Jaara <9083456+MohamadJaara@users.noreply.github.com> Date: Tue, 2 Jun 2026 00:17:02 +0200 Subject: [PATCH 4/5] address PR comment --- .../components/ConfigToolbar/ConfigToolbar.styles.tsx | 4 ++++ .../src/script/components/ConfigToolbar/ConfigToolbar.tsx | 4 ++-- apps/webapp/src/script/components/InputBar/InputBar.tsx | 7 +++---- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/apps/webapp/src/script/components/ConfigToolbar/ConfigToolbar.styles.tsx b/apps/webapp/src/script/components/ConfigToolbar/ConfigToolbar.styles.tsx index 758bea4dade..5dd7dccc252 100644 --- a/apps/webapp/src/script/components/ConfigToolbar/ConfigToolbar.styles.tsx +++ b/apps/webapp/src/script/components/ConfigToolbar/ConfigToolbar.styles.tsx @@ -31,3 +31,7 @@ export const wrapperStyles: CSSObject = { zIndex: 100000000, boxShadow: '3px 1px 6px 1px #000', }; + +export const messagePreprocessingSwitchStyles: CSSObject = { + marginBottom: '10px', +}; diff --git a/apps/webapp/src/script/components/ConfigToolbar/ConfigToolbar.tsx b/apps/webapp/src/script/components/ConfigToolbar/ConfigToolbar.tsx index 3e92236190b..b028885887b 100644 --- a/apps/webapp/src/script/components/ConfigToolbar/ConfigToolbar.tsx +++ b/apps/webapp/src/script/components/ConfigToolbar/ConfigToolbar.tsx @@ -29,7 +29,7 @@ import {Config, Configuration} from 'src/script/Config'; import {useClickOutside} from 'src/script/hooks/useClickOutside'; import {CoreCryptoLogLevel} from 'Util/debugUtil'; -import {wrapperStyles} from './ConfigToolbar.styles'; +import {messagePreprocessingSwitchStyles, wrapperStyles} from './ConfigToolbar.styles'; export function ConfigToolbar() { const [showConfig, setShowConfig] = useState(false); @@ -269,7 +269,7 @@ export function ConfigToolbar() { const renderMessagePreprocessingSwitch = () => { return ( -
+
diff --git a/apps/webapp/src/script/components/InputBar/InputBar.tsx b/apps/webapp/src/script/components/InputBar/InputBar.tsx index b7ccb9863d3..357d259c479 100644 --- a/apps/webapp/src/script/components/InputBar/InputBar.tsx +++ b/apps/webapp/src/script/components/InputBar/InputBar.tsx @@ -19,6 +19,7 @@ import {useCallback, useEffect, useRef, useState} from 'react'; +import is from '@sindresorhus/is'; import {amplify} from 'amplify'; import cx from 'classnames'; import {LexicalEditor, $createTextNode, $insertNodes} from 'lexical'; @@ -213,11 +214,9 @@ export const InputBar = ({ useEffect(() => { const handleMessagePreprocessingChange = (event: Event) => { const isDisabled = - event instanceof CustomEvent && is.boolean(event.detail) - ? event.detail - : isMessagePreprocessingDisabled(); + event instanceof CustomEvent && is.boolean(event.detail) ? event.detail : isMessagePreprocessingDisabled(); - setDisableMessagePreprocessing(isDisabled); + setDisableMessagePreprocessing(isDisabled); }; window.addEventListener(DISABLE_MESSAGE_PREPROCESSING_EVENT, handleMessagePreprocessingChange); From 7031fbc26ec01f408618933effd970c335a1436a Mon Sep 17 00:00:00 2001 From: Mohamad Jaara <9083456+MohamadJaara@users.noreply.github.com> Date: Tue, 2 Jun 2026 09:20:26 +0200 Subject: [PATCH 5/5] lint --- .../InputBarEditor/RichTextEditor/RichTextEditor.tsx | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/apps/webapp/src/script/components/InputBar/InputBarEditor/RichTextEditor/RichTextEditor.tsx b/apps/webapp/src/script/components/InputBar/InputBarEditor/RichTextEditor/RichTextEditor.tsx index b495554b1d0..0d1d94e6d26 100644 --- a/apps/webapp/src/script/components/InputBar/InputBarEditor/RichTextEditor/RichTextEditor.tsx +++ b/apps/webapp/src/script/components/InputBar/InputBarEditor/RichTextEditor/RichTextEditor.tsx @@ -187,10 +187,9 @@ export const RichTextEditor = ({ } }} /> - {!disableMessagePreprocessing && ( - - )} - {disableMessagePreprocessing ? () : ( + {disableMessagePreprocessing ? ( + + ) : ( )}