mirror of
https://github.com/vector-im/element-web.git
synced 2024-11-16 21:24:59 +08:00
Fix focus and toggling issues in formatting bar
This commit is contained in:
parent
8974442084
commit
c11232742b
@ -22,6 +22,7 @@ const MARKDOWN_REGEX = {
|
|||||||
BOLD: /([\*_])\1([\w\s]+?)\1\1/g,
|
BOLD: /([\*_])\1([\w\s]+?)\1\1/g,
|
||||||
HR: /(\n|^)((-|\*|_) *){3,}(\n|$)/g,
|
HR: /(\n|^)((-|\*|_) *){3,}(\n|$)/g,
|
||||||
CODE: /`[^`]*`/g,
|
CODE: /`[^`]*`/g,
|
||||||
|
STRIKETHROUGH: /~{2}[^~]*~{2}/g,
|
||||||
};
|
};
|
||||||
|
|
||||||
const USERNAME_REGEX = /@\S+:\S+/g;
|
const USERNAME_REGEX = /@\S+:\S+/g;
|
||||||
@ -121,7 +122,7 @@ export function getScopedRTDecorators(scope: any): CompositeDecorator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function getScopedMDDecorators(scope: any): CompositeDecorator {
|
export function getScopedMDDecorators(scope: any): CompositeDecorator {
|
||||||
let markdownDecorators = ['HR', 'BOLD', 'ITALIC', 'CODE'].map(
|
let markdownDecorators = ['HR', 'BOLD', 'ITALIC', 'CODE', 'STRIKETHROUGH'].map(
|
||||||
(style) => ({
|
(style) => ({
|
||||||
strategy: (contentBlock, callback) => {
|
strategy: (contentBlock, callback) => {
|
||||||
return findWithRegex(MARKDOWN_REGEX[style], contentBlock, callback);
|
return findWithRegex(MARKDOWN_REGEX[style], contentBlock, callback);
|
||||||
|
@ -178,12 +178,11 @@ export default class MessageComposer extends React.Component {
|
|||||||
onToggleFormattingClicked() {
|
onToggleFormattingClicked() {
|
||||||
UserSettingsStore.setSyncedSetting('MessageComposer.showFormatting', !this.state.showFormatting);
|
UserSettingsStore.setSyncedSetting('MessageComposer.showFormatting', !this.state.showFormatting);
|
||||||
this.setState({showFormatting: !this.state.showFormatting});
|
this.setState({showFormatting: !this.state.showFormatting});
|
||||||
this.messageComposerInput.focus();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onToggleMarkdownClicked() {
|
onToggleMarkdownClicked(e) {
|
||||||
|
e.preventDefault(); // don't steal focus from the editor!
|
||||||
this.messageComposerInput.enableRichtext(!this.state.inputState.isRichtextEnabled);
|
this.messageComposerInput.enableRichtext(!this.state.inputState.isRichtextEnabled);
|
||||||
this.messageComposerInput.focus();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@ -292,13 +291,13 @@ export default class MessageComposer extends React.Component {
|
|||||||
const active = style.includes(name) || blockType === name;
|
const active = style.includes(name) || blockType === name;
|
||||||
const suffix = active ? '-o-n' : '';
|
const suffix = active ? '-o-n' : '';
|
||||||
const onFormatButtonClicked = this.onFormatButtonClicked.bind(this, name);
|
const onFormatButtonClicked = this.onFormatButtonClicked.bind(this, name);
|
||||||
const disabled = !this.state.inputState.isRichtextEnabled && ['strike', 'underline'].includes(name);
|
const disabled = !this.state.inputState.isRichtextEnabled && 'underline' === name;
|
||||||
const className = classNames("mx_MessageComposer_format_button", {
|
const className = classNames("mx_MessageComposer_format_button", {
|
||||||
mx_MessageComposer_format_button_disabled: disabled,
|
mx_MessageComposer_format_button_disabled: disabled,
|
||||||
});
|
});
|
||||||
return <img className={className}
|
return <img className={className}
|
||||||
title={name}
|
title={name}
|
||||||
onClick={disabled ? null : onFormatButtonClicked}
|
onMouseDown={disabled ? null : onFormatButtonClicked}
|
||||||
key={name}
|
key={name}
|
||||||
src={`img/button-text-${name}${suffix}.svg`}
|
src={`img/button-text-${name}${suffix}.svg`}
|
||||||
height="17" />;
|
height="17" />;
|
||||||
@ -319,7 +318,7 @@ export default class MessageComposer extends React.Component {
|
|||||||
{formatButtons}
|
{formatButtons}
|
||||||
<div style={{flex: 1}}></div>
|
<div style={{flex: 1}}></div>
|
||||||
<img title={`Turn Markdown ${this.state.inputState.isRichtextEnabled ? 'on' : 'off'}`}
|
<img title={`Turn Markdown ${this.state.inputState.isRichtextEnabled ? 'on' : 'off'}`}
|
||||||
onClick={this.onToggleMarkdownClicked}
|
onMouseDown={this.onToggleMarkdownClicked}
|
||||||
className="mx_MessageComposer_formatbar_markdown"
|
className="mx_MessageComposer_formatbar_markdown"
|
||||||
src={`img/button-md-${!this.state.inputState.isRichtextEnabled}.png`} />
|
src={`img/button-md-${!this.state.inputState.isRichtextEnabled}.png`} />
|
||||||
<img title="Hide Text Formatting Toolbar"
|
<img title="Hide Text Formatting Toolbar"
|
||||||
|
@ -83,7 +83,6 @@ export default class MessageComposerInput extends React.Component {
|
|||||||
constructor(props, context) {
|
constructor(props, context) {
|
||||||
super(props, context);
|
super(props, context);
|
||||||
this.onAction = this.onAction.bind(this);
|
this.onAction = this.onAction.bind(this);
|
||||||
this.focus = this.focus.bind(this);
|
|
||||||
this.handleReturn = this.handleReturn.bind(this);
|
this.handleReturn = this.handleReturn.bind(this);
|
||||||
this.handleKeyCommand = this.handleKeyCommand.bind(this);
|
this.handleKeyCommand = this.handleKeyCommand.bind(this);
|
||||||
this.setEditorState = this.setEditorState.bind(this);
|
this.setEditorState = this.setEditorState.bind(this);
|
||||||
@ -378,13 +377,10 @@ export default class MessageComposerInput extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
focus(ev) {
|
|
||||||
this.refs.editor.focus();
|
|
||||||
}
|
|
||||||
|
|
||||||
setEditorState(editorState: EditorState) {
|
setEditorState(editorState: EditorState, cb = () => null) {
|
||||||
editorState = RichText.attachImmutableEntitiesToEmoji(editorState);
|
editorState = RichText.attachImmutableEntitiesToEmoji(editorState);
|
||||||
this.setState({editorState});
|
this.setState({editorState}, cb);
|
||||||
|
|
||||||
if (editorState.getCurrentContent().hasText()) {
|
if (editorState.getCurrentContent().hasText()) {
|
||||||
this.onTypingActivity();
|
this.onTypingActivity();
|
||||||
@ -402,19 +398,20 @@ export default class MessageComposerInput extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
enableRichtext(enabled: boolean) {
|
enableRichtext(enabled: boolean) {
|
||||||
|
let contentState = null;
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
const html = mdownToHtml(this.state.editorState.getCurrentContent().getPlainText());
|
const html = mdownToHtml(this.state.editorState.getCurrentContent().getPlainText());
|
||||||
const contentState = RichText.HTMLtoContentState(html);
|
contentState = RichText.HTMLtoContentState(html);
|
||||||
this.setEditorState(this.createEditorState(enabled, contentState));
|
|
||||||
} else {
|
} else {
|
||||||
let markdown = stateToMarkdown(this.state.editorState.getCurrentContent());
|
let markdown = stateToMarkdown(this.state.editorState.getCurrentContent());
|
||||||
markdown = markdown.substring(0, markdown.length - 1); // stateToMarkdown tacks on an extra newline (?!?)
|
markdown = markdown.substring(0, markdown.length - 1); // stateToMarkdown tacks on an extra newline (?!?)
|
||||||
const contentState = ContentState.createFromText(markdown);
|
contentState = ContentState.createFromText(markdown);
|
||||||
this.setEditorState(this.createEditorState(enabled, contentState));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setState({
|
this.setEditorState(this.createEditorState(enabled, contentState), () => {
|
||||||
isRichtextEnabled: enabled,
|
this.setState({
|
||||||
|
isRichtextEnabled: enabled,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
UserSettingsStore.setSyncedSetting('MessageComposerInput.isRichTextEnabled', enabled);
|
UserSettingsStore.setSyncedSetting('MessageComposerInput.isRichTextEnabled', enabled);
|
||||||
@ -447,6 +444,7 @@ export default class MessageComposerInput extends React.Component {
|
|||||||
bold: text => `**${text}**`,
|
bold: text => `**${text}**`,
|
||||||
italic: text => `*${text}*`,
|
italic: text => `*${text}*`,
|
||||||
underline: text => `_${text}_`, // there's actually no valid underline in Markdown, but *shrug*
|
underline: text => `_${text}_`, // there's actually no valid underline in Markdown, but *shrug*
|
||||||
|
strike: text => `~~${text}~~`,
|
||||||
code: text => `\`${text}\``,
|
code: text => `\`${text}\``,
|
||||||
blockquote: text => text.split('\n').map(line => `> ${line}\n`).join(''),
|
blockquote: text => text.split('\n').map(line => `> ${line}\n`).join(''),
|
||||||
'unordered-list-item': text => text.split('\n').map(line => `- ${line}\n`).join(''),
|
'unordered-list-item': text => text.split('\n').map(line => `- ${line}\n`).join(''),
|
||||||
@ -590,6 +588,7 @@ export default class MessageComposerInput extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onFormatButtonClicked(name: "bold" | "italic" | "strike" | "code" | "underline" | "quote" | "bullet" | "numbullet", e) {
|
onFormatButtonClicked(name: "bold" | "italic" | "strike" | "code" | "underline" | "quote" | "bullet" | "numbullet", e) {
|
||||||
|
e.preventDefault(); // don't steal focus from the editor!
|
||||||
const command = {
|
const command = {
|
||||||
code: 'code-block',
|
code: 'code-block',
|
||||||
quote: 'blockquote',
|
quote: 'blockquote',
|
||||||
@ -631,8 +630,9 @@ export default class MessageComposerInput extends React.Component {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
onMarkdownToggleClicked() {
|
onMarkdownToggleClicked(e) {
|
||||||
this.enableRichtext(!this.state.isRichtextEnabled);
|
e.preventDefault(); // don't steal focus from the editor!
|
||||||
|
this.handleKeyCommand('toggle-mode');
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@ -654,10 +654,9 @@ export default class MessageComposerInput extends React.Component {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={className}
|
<div className={className}>
|
||||||
onClick={ this.focus }>
|
|
||||||
<img className="mx_MessageComposer_input_markdownIndicator"
|
<img className="mx_MessageComposer_input_markdownIndicator"
|
||||||
onClick={this.onMarkdownToggleClicked}
|
onMouseDown={this.onMarkdownToggleClicked}
|
||||||
title={`Markdown is ${this.state.isRichtextEnabled ? 'disabled' : 'enabled'}`}
|
title={`Markdown is ${this.state.isRichtextEnabled ? 'disabled' : 'enabled'}`}
|
||||||
src={`img/button-md-${!this.state.isRichtextEnabled}.png`} />
|
src={`img/button-md-${!this.state.isRichtextEnabled}.png`} />
|
||||||
<Editor ref="editor"
|
<Editor ref="editor"
|
||||||
|
Loading…
Reference in New Issue
Block a user