Improve design of the rich text editor (#9533)
New design for rich text composer
This commit is contained in:
parent
9101b42de8
commit
5ca9accce2
31 changed files with 668 additions and 270 deletions
|
@ -25,9 +25,8 @@ import { THREAD_RELATION_TYPE } from 'matrix-js-sdk/src/models/thread';
|
|||
import { _t } from '../../../languageHandler';
|
||||
import AccessibleTooltipButton from "../elements/AccessibleTooltipButton";
|
||||
import { CollapsibleButton } from './CollapsibleButton';
|
||||
import ContextMenu, { aboveLeftOf, AboveLeftOf, useContextMenu } from '../../structures/ContextMenu';
|
||||
import { AboveLeftOf } from '../../structures/ContextMenu';
|
||||
import dis from '../../../dispatcher/dispatcher';
|
||||
import EmojiPicker from '../emojipicker/EmojiPicker';
|
||||
import ErrorDialog from "../dialogs/ErrorDialog";
|
||||
import LocationButton from '../location/LocationButton';
|
||||
import Modal from "../../../Modal";
|
||||
|
@ -39,6 +38,8 @@ import RoomContext from '../../../contexts/RoomContext';
|
|||
import { useDispatcher } from "../../../hooks/useDispatcher";
|
||||
import { chromeFileInputFix } from "../../../utils/BrowserWorkarounds";
|
||||
import IconizedContextMenu, { IconizedContextMenuOptionList } from '../context_menus/IconizedContextMenu';
|
||||
import { EmojiButton } from './EmojiButton';
|
||||
import { useSettingValue } from '../../../hooks/useSettings';
|
||||
|
||||
interface IProps {
|
||||
addEmoji: (emoji: string) => boolean;
|
||||
|
@ -56,7 +57,6 @@ interface IProps {
|
|||
showVoiceBroadcastButton: boolean;
|
||||
onStartVoiceBroadcastClick: () => void;
|
||||
isRichTextEnabled: boolean;
|
||||
showComposerModeButton: boolean;
|
||||
onComposerModeClick: () => void;
|
||||
}
|
||||
|
||||
|
@ -67,6 +67,8 @@ const MessageComposerButtons: React.FC<IProps> = (props: IProps) => {
|
|||
const matrixClient: MatrixClient = useContext(MatrixClientContext);
|
||||
const { room, roomId, narrow } = useContext(RoomContext);
|
||||
|
||||
const isWysiwygLabEnabled = useSettingValue<boolean>('feature_wysiwyg_composer');
|
||||
|
||||
if (props.haveRecording) {
|
||||
return null;
|
||||
}
|
||||
|
@ -75,7 +77,9 @@ const MessageComposerButtons: React.FC<IProps> = (props: IProps) => {
|
|||
let moreButtons: ReactElement[];
|
||||
if (narrow) {
|
||||
mainButtons = [
|
||||
emojiButton(props),
|
||||
isWysiwygLabEnabled ?
|
||||
<ComposerModeButton key="composerModeButton" isRichTextEnabled={props.isRichTextEnabled} onClick={props.onComposerModeClick} /> :
|
||||
emojiButton(props),
|
||||
];
|
||||
moreButtons = [
|
||||
uploadButton(), // props passed via UploadButtonContext
|
||||
|
@ -87,9 +91,9 @@ const MessageComposerButtons: React.FC<IProps> = (props: IProps) => {
|
|||
];
|
||||
} else {
|
||||
mainButtons = [
|
||||
emojiButton(props),
|
||||
props.showComposerModeButton &&
|
||||
<ComposerModeButton key="composerModeButton" isRichTextEnabled={props.isRichTextEnabled} onClick={props.onComposerModeClick} />,
|
||||
isWysiwygLabEnabled ?
|
||||
<ComposerModeButton key="composerModeButton" isRichTextEnabled={props.isRichTextEnabled} onClick={props.onComposerModeClick} /> :
|
||||
emojiButton(props),
|
||||
uploadButton(), // props passed via UploadButtonContext
|
||||
];
|
||||
moreButtons = [
|
||||
|
@ -139,58 +143,10 @@ function emojiButton(props: IProps): ReactElement {
|
|||
key="emoji_button"
|
||||
addEmoji={props.addEmoji}
|
||||
menuPosition={props.menuPosition}
|
||||
className="mx_MessageComposer_button"
|
||||
/>;
|
||||
}
|
||||
|
||||
interface IEmojiButtonProps {
|
||||
addEmoji: (unicode: string) => boolean;
|
||||
menuPosition: AboveLeftOf;
|
||||
}
|
||||
|
||||
const EmojiButton: React.FC<IEmojiButtonProps> = ({ addEmoji, menuPosition }) => {
|
||||
const overflowMenuCloser = useContext(OverflowMenuContext);
|
||||
const [menuDisplayed, button, openMenu, closeMenu] = useContextMenu();
|
||||
|
||||
let contextMenu: React.ReactElement | null = null;
|
||||
if (menuDisplayed) {
|
||||
const position = (
|
||||
menuPosition ?? aboveLeftOf(button.current.getBoundingClientRect())
|
||||
);
|
||||
|
||||
contextMenu = <ContextMenu
|
||||
{...position}
|
||||
onFinished={() => {
|
||||
closeMenu();
|
||||
overflowMenuCloser?.();
|
||||
}}
|
||||
managed={false}
|
||||
>
|
||||
<EmojiPicker onChoose={addEmoji} showQuickReactions={true} />
|
||||
</ContextMenu>;
|
||||
}
|
||||
|
||||
const className = classNames(
|
||||
"mx_MessageComposer_button",
|
||||
{
|
||||
"mx_MessageComposer_button_highlight": menuDisplayed,
|
||||
},
|
||||
);
|
||||
|
||||
// TODO: replace ContextMenuTooltipButton with a unified representation of
|
||||
// the header buttons and the right panel buttons
|
||||
return <React.Fragment>
|
||||
<CollapsibleButton
|
||||
className={className}
|
||||
iconClassName="mx_MessageComposer_emoji"
|
||||
onClick={openMenu}
|
||||
title={_t("Emoji")}
|
||||
inputRef={button}
|
||||
/>
|
||||
|
||||
{ contextMenu }
|
||||
</React.Fragment>;
|
||||
};
|
||||
|
||||
function uploadButton(): ReactElement {
|
||||
return <UploadButton key="controls_upload" />;
|
||||
}
|
||||
|
@ -408,7 +364,7 @@ interface WysiwygToggleButtonProps {
|
|||
}
|
||||
|
||||
function ComposerModeButton({ isRichTextEnabled, onClick }: WysiwygToggleButtonProps) {
|
||||
const title = isRichTextEnabled ? _t("Show plain text") : _t("Show formatting");
|
||||
const title = isRichTextEnabled ? _t("Hide formatting") : _t("Show formatting");
|
||||
|
||||
return <CollapsibleButton
|
||||
className="mx_MessageComposer_button"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue