Replace emoji at the end of a message

Signed-off-by: Šimon Brandner <simon.bra.ag@gmail.com>
This commit is contained in:
Šimon Brandner 2021-04-18 08:43:00 +02:00
parent e91f4b7eb2
commit 3edf05d38d
No known key found for this signature in database
GPG key ID: 9760693FDD98A790
2 changed files with 16 additions and 6 deletions

View file

@ -51,6 +51,7 @@ import {replaceableComponent} from "../../../utils/replaceableComponent";
// matches emoticons which follow the start of a line or whitespace // matches emoticons which follow the start of a line or whitespace
const REGEX_EMOTICON_WHITESPACE = new RegExp('(?:^|\\s)(' + EMOTICON_REGEX.source + ')\\s$'); const REGEX_EMOTICON_WHITESPACE = new RegExp('(?:^|\\s)(' + EMOTICON_REGEX.source + ')\\s$');
export const REGEX_EMOTICON = new RegExp('(?:^|\\s)(' + EMOTICON_REGEX.source + ')$');
const IS_MAC = navigator.platform.indexOf("Mac") !== -1; const IS_MAC = navigator.platform.indexOf("Mac") !== -1;
@ -150,7 +151,7 @@ export default class BasicMessageEditor extends React.Component<IProps, IState>
} }
} }
private replaceEmoticon = (caretPosition: DocumentPosition) => { public replaceEmoticon(caretPosition: DocumentPosition, regex: RegExp) {
const {model} = this.props; const {model} = this.props;
const range = model.startRange(caretPosition); const range = model.startRange(caretPosition);
// expand range max 8 characters backwards from caretPosition, // expand range max 8 characters backwards from caretPosition,
@ -161,7 +162,7 @@ export default class BasicMessageEditor extends React.Component<IProps, IState>
n -= 1; n -= 1;
return n >= 0 && (part.type === "plain" || part.type === "pill-candidate"); return n >= 0 && (part.type === "plain" || part.type === "pill-candidate");
}); });
const emoticonMatch = REGEX_EMOTICON_WHITESPACE.exec(range.text); const emoticonMatch = regex.exec(range.text);
if (emoticonMatch) { if (emoticonMatch) {
const query = emoticonMatch[1].replace("-", ""); const query = emoticonMatch[1].replace("-", "");
// try both exact match and lower-case, this means that xd won't match xD but :P will match :p // try both exact match and lower-case, this means that xd won't match xD but :P will match :p
@ -180,7 +181,7 @@ export default class BasicMessageEditor extends React.Component<IProps, IState>
return range.replace([partCreator.plain(data.unicode + " ")]); return range.replace([partCreator.plain(data.unicode + " ")]);
} }
} }
}; }
private updateEditorState = (selection: Caret, inputType?: string, diff?: IDiff) => { private updateEditorState = (selection: Caret, inputType?: string, diff?: IDiff) => {
renderModel(this.editorRef.current, this.props.model); renderModel(this.editorRef.current, this.props.model);
@ -567,8 +568,7 @@ export default class BasicMessageEditor extends React.Component<IProps, IState>
}; };
private configureEmoticonAutoReplace = () => { private configureEmoticonAutoReplace = () => {
const shouldReplace = SettingsStore.getValue('MessageComposerInput.autoReplaceEmoji'); this.props.model.setTransformCallback(this.transform);
this.props.model.setTransformCallback(shouldReplace ? this.replaceEmoticon : null);
}; };
private configureShouldShowPillAvatar = () => { private configureShouldShowPillAvatar = () => {
@ -576,6 +576,11 @@ export default class BasicMessageEditor extends React.Component<IProps, IState>
this.setState({ showPillAvatar }); this.setState({ showPillAvatar });
}; };
private transform = (documentPosition: DocumentPosition) => {
const shouldReplace = SettingsStore.getValue('MessageComposerInput.autoReplaceEmoji');
if (shouldReplace) this.replaceEmoticon(documentPosition, REGEX_EMOTICON_WHITESPACE);
}
componentWillUnmount() { componentWillUnmount() {
document.removeEventListener("selectionchange", this.onSelectionChange); document.removeEventListener("selectionchange", this.onSelectionChange);
this.editorRef.current.removeEventListener("input", this.onInput, true); this.editorRef.current.removeEventListener("input", this.onInput, true);

View file

@ -28,7 +28,7 @@ import {
stripPrefix, stripPrefix,
} from '../../../editor/serialize'; } from '../../../editor/serialize';
import {CommandPartCreator} from '../../../editor/parts'; import {CommandPartCreator} from '../../../editor/parts';
import BasicMessageComposer from "./BasicMessageComposer"; import BasicMessageComposer, {REGEX_EMOTICON} from "./BasicMessageComposer";
import ReplyThread from "../elements/ReplyThread"; import ReplyThread from "../elements/ReplyThread";
import {parseEvent} from '../../../editor/deserialize'; import {parseEvent} from '../../../editor/deserialize';
import {findEditableEvent} from '../../../utils/EventUtils'; import {findEditableEvent} from '../../../utils/EventUtils';
@ -334,6 +334,11 @@ export default class SendMessageComposer extends React.Component {
return; return;
} }
// Replace emoticon at the end of the message
const caret = this._editorRef.getCaret();
const position = model.positionForOffset(caret.offset, caret.atNodeEnd);
this._editorRef.replaceEmoticon(position, REGEX_EMOTICON);
const replyToEvent = this.props.replyToEvent; const replyToEvent = this.props.replyToEvent;
let shouldSend = true; let shouldSend = true;
let content; let content;