Keep content when switching between rich text and plain text mode

This commit is contained in:
Florian Duros 2022-10-25 18:33:25 +02:00
parent 50279c8870
commit c7dbb5947f
No known key found for this signature in database
GPG key ID: 9700AA5870258A0B
7 changed files with 43 additions and 10 deletions

View file

@ -60,6 +60,7 @@ import {
} from '../../../voice-broadcast';
import { SendWysiwygComposer, sendMessage } from './wysiwyg_composer/';
import { MatrixClientProps, withMatrixClientHOC } from '../../../contexts/MatrixClientContext';
import { htmlToPlainText } from '../../../utils/room/htmlToPlaintext';
let instanceCount = 0;
@ -102,6 +103,7 @@ interface IState {
showVoiceBroadcastButton: boolean;
isWysiwygLabEnabled: boolean;
isRichTextEnabled: boolean;
initialComposerContent: string;
}
export class MessageComposer extends React.Component<IProps, IState> {
@ -138,6 +140,7 @@ export class MessageComposer extends React.Component<IProps, IState> {
showVoiceBroadcastButton: SettingsStore.getValue(Features.VoiceBroadcast),
isWysiwygLabEnabled: SettingsStore.getValue<boolean>("feature_wysiwyg_composer"),
isRichTextEnabled: true,
initialComposerContent: '',
};
this.instanceId = instanceCount++;
@ -355,6 +358,10 @@ export class MessageComposer extends React.Component<IProps, IState> {
private onRichTextToggle = () => {
this.setState(state => ({
isRichTextEnabled: !state.isRichTextEnabled,
initialComposerContent: !state.isRichTextEnabled ?
state.composerContent :
// TODO when available use rust model plain text
htmlToPlainText(state.composerContent),
}));
};
@ -434,6 +441,7 @@ export class MessageComposer extends React.Component<IProps, IState> {
onChange={this.onWysiwygChange}
onSend={this.sendMessage}
isRichTextEnabled={this.state.isRichTextEnabled}
initialContent={this.state.initialComposerContent}
/>,
);
} else {

View file

@ -34,6 +34,7 @@ const Content = forwardRef<HTMLElement, ContentProps>(
);
interface SendWysiwygComposerProps {
initialContent: string;
isRichTextEnabled: boolean;
disabled?: boolean;
onChange: (content: string) => void;

View file

@ -14,11 +14,11 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import React, { MutableRefObject, ReactNode } from 'react';
import React, { MutableRefObject, ReactNode, useEffect } from 'react';
import { useComposerFunctions } from '../hooks/useComposerFunctions';
import { usePlainTextListeners } from '../hooks/usePlainTextListeners';
import { ComposerFunctions } from '../types';
import { Editor } from "./Editor";
interface PlainTextComposerProps {
@ -33,12 +33,20 @@ interface PlainTextComposerProps {
) => ReactNode;
}
export function PlainTextComposer({ className, disabled, onSend, onChange, children }: PlainTextComposerProps) {
const {ref, onInput, onPaste, onKeyDown} = usePlainTextListeners(onChange, onSend)
const composerFunctions = useComposerFunctions(ref)
export function PlainTextComposer({
className, disabled, onSend, onChange, children, initialContent }: PlainTextComposerProps,
) {
const { ref, onInput, onPaste, onKeyDown } = usePlainTextListeners(onChange, onSend);
const composerFunctions = useComposerFunctions(ref);
useEffect(() => {
if (ref.current) {
ref.current.innerText = initialContent;
}
}, [ref, initialContent]);
return <div className={className} onInput={onInput} onPaste={onPaste} onKeyDown={onKeyDown}>
<Editor ref={ref} disabled={disabled} />
{children?.(ref, composerFunctions)}
{ children?.(ref, composerFunctions) }
</div>;
}

View file

@ -20,6 +20,7 @@ import { htmlSerializeFromMdIfNeeded } from "../../../../../editor/serialize";
import SettingsStore from "../../../../../settings/SettingsStore";
import { RoomPermalinkCreator } from "../../../../../utils/permalinks/Permalinks";
import { addReplyToMessageContent } from "../../../../../utils/Reply";
import { htmlToPlainText } from "../../../../../utils/room/htmlToPlaintext";
// Merges favouring the given relation
function attachRelation(content: IContent, relation?: IEventRelation): void {
@ -50,10 +51,6 @@ function getTextReplyFallback(mxEvent: MatrixEvent): string {
return "";
}
function htmlToPlainText(html: string) {
return new DOMParser().parseFromString(html, 'text/html').documentElement.textContent;
}
interface CreateMessageContentParams {
relation?: IEventRelation;
replyToEvent?: MatrixEvent;