Apply prettier formatting

This commit is contained in:
Michael Weimann 2022-12-12 12:24:14 +01:00
parent 1cac306093
commit 526645c791
No known key found for this signature in database
GPG key ID: 53F535A266BB9584
1576 changed files with 65385 additions and 62478 deletions

View file

@ -14,23 +14,27 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import classNames from 'classnames';
import React, { createRef, ClipboardEvent } from 'react';
import { Room } from 'matrix-js-sdk/src/models/room';
import { MatrixEvent } from 'matrix-js-sdk/src/models/event';
import EMOTICON_REGEX from 'emojibase-regex/emoticon';
import classNames from "classnames";
import React, { createRef, ClipboardEvent } from "react";
import { Room } from "matrix-js-sdk/src/models/room";
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
import EMOTICON_REGEX from "emojibase-regex/emoticon";
import { logger } from "matrix-js-sdk/src/logger";
import EditorModel from '../../../editor/model';
import HistoryManager from '../../../editor/history';
import { Caret, setSelection } from '../../../editor/caret';
import { formatRange, formatRangeAsLink, replaceRangeAndMoveCaret, toggleInlineFormat }
from '../../../editor/operations';
import { getCaretOffsetAndText, getRangeForSelection } from '../../../editor/dom';
import Autocomplete, { generateCompletionDomId } from '../rooms/Autocomplete';
import { getAutoCompleteCreator, Part, Type } from '../../../editor/parts';
import { parseEvent, parsePlainTextMessage } from '../../../editor/deserialize';
import { renderModel } from '../../../editor/render';
import EditorModel from "../../../editor/model";
import HistoryManager from "../../../editor/history";
import { Caret, setSelection } from "../../../editor/caret";
import {
formatRange,
formatRangeAsLink,
replaceRangeAndMoveCaret,
toggleInlineFormat,
} from "../../../editor/operations";
import { getCaretOffsetAndText, getRangeForSelection } from "../../../editor/dom";
import Autocomplete, { generateCompletionDomId } from "../rooms/Autocomplete";
import { getAutoCompleteCreator, Part, Type } from "../../../editor/parts";
import { parseEvent, parsePlainTextMessage } from "../../../editor/deserialize";
import { renderModel } from "../../../editor/render";
import SettingsStore from "../../../settings/SettingsStore";
import { IS_MAC, Key } from "../../../Keyboard";
import { EMOTICON_TO_EMOJI } from "../../../emoji";
@ -40,19 +44,19 @@ import MessageComposerFormatBar, { Formatting } from "./MessageComposerFormatBar
import DocumentOffset from "../../../editor/offset";
import { IDiff } from "../../../editor/diff";
import AutocompleteWrapperModel from "../../../editor/autocomplete";
import DocumentPosition from '../../../editor/position';
import DocumentPosition from "../../../editor/position";
import { ICompletion } from "../../../autocomplete/Autocompleter";
import { getKeyBindingsManager } from '../../../KeyBindingsManager';
import { ALTERNATE_KEY_NAME, KeyBindingAction } from '../../../accessibility/KeyboardShortcuts';
import { getKeyBindingsManager } from "../../../KeyBindingsManager";
import { ALTERNATE_KEY_NAME, KeyBindingAction } from "../../../accessibility/KeyboardShortcuts";
import { _t } from "../../../languageHandler";
import { linkify } from '../../../linkify-matrix';
import { SdkContextClass } from '../../../contexts/SDKContext';
import { linkify } from "../../../linkify-matrix";
import { SdkContextClass } from "../../../contexts/SDKContext";
// matches emoticons which follow the start of a line or whitespace
const REGEX_EMOTICON_WHITESPACE = new RegExp('(?:^|\\s)(' + EMOTICON_REGEX.source + ')\\s|:^$');
export const REGEX_EMOTICON = new RegExp('(?:^|\\s)(' + EMOTICON_REGEX.source + ')$');
const REGEX_EMOTICON_WHITESPACE = new RegExp("(?:^|\\s)(" + EMOTICON_REGEX.source + ")\\s|:^$");
export const REGEX_EMOTICON = new RegExp("(?:^|\\s)(" + EMOTICON_REGEX.source + ")$");
const SURROUND_WITH_CHARACTERS = ["\"", "_", "`", "'", "*", "~", "$"];
const SURROUND_WITH_CHARACTERS = ['"', "_", "`", "'", "*", "~", "$"];
const SURROUND_WITH_DOUBLE_CHARACTERS = new Map([
["(", ")"],
["[", "]"],
@ -61,10 +65,13 @@ const SURROUND_WITH_DOUBLE_CHARACTERS = new Map([
]);
function ctrlShortcutLabel(key: string, needsShift = false, needsAlt = false): string {
return (IS_MAC ? "⌘" : _t(ALTERNATE_KEY_NAME[Key.CONTROL])) +
(needsShift ? ("+" + _t(ALTERNATE_KEY_NAME[Key.SHIFT])) : "") +
(needsAlt ? ("+" + _t(ALTERNATE_KEY_NAME[Key.ALT])) : "") +
"+" + key;
return (
(IS_MAC ? "⌘" : _t(ALTERNATE_KEY_NAME[Key.CONTROL])) +
(needsShift ? "+" + _t(ALTERNATE_KEY_NAME[Key.SHIFT]) : "") +
(needsAlt ? "+" + _t(ALTERNATE_KEY_NAME[Key.ALT]) : "") +
"+" +
key
);
}
function cloneSelection(selection: Selection): Partial<Selection> {
@ -80,13 +87,15 @@ function cloneSelection(selection: Selection): Partial<Selection> {
}
function selectionEquals(a: Partial<Selection>, b: Selection): boolean {
return a.anchorNode === b.anchorNode &&
return (
a.anchorNode === b.anchorNode &&
a.anchorOffset === b.anchorOffset &&
a.focusNode === b.focusNode &&
a.focusOffset === b.focusOffset &&
a.isCollapsed === b.isCollapsed &&
a.rangeCount === b.rangeCount &&
a.type === b.type;
a.type === b.type
);
}
interface IProps {
@ -140,15 +149,27 @@ export default class BasicMessageEditor extends React.Component<IProps, IState>
showVisualBell: false,
};
this.useMarkdownHandle = SettingsStore.watchSetting('MessageComposerInput.useMarkdown', null,
this.configureUseMarkdown);
this.emoticonSettingHandle = SettingsStore.watchSetting('MessageComposerInput.autoReplaceEmoji', null,
this.configureEmoticonAutoReplace);
this.useMarkdownHandle = SettingsStore.watchSetting(
"MessageComposerInput.useMarkdown",
null,
this.configureUseMarkdown,
);
this.emoticonSettingHandle = SettingsStore.watchSetting(
"MessageComposerInput.autoReplaceEmoji",
null,
this.configureEmoticonAutoReplace,
);
this.configureEmoticonAutoReplace();
this.shouldShowPillAvatarSettingHandle = SettingsStore.watchSetting("Pill.shouldShowPillAvatar", null,
this.configureShouldShowPillAvatar);
this.surroundWithHandle = SettingsStore.watchSetting("MessageComposerInput.surroundWith", null,
this.surroundWithSettingChanged);
this.shouldShowPillAvatarSettingHandle = SettingsStore.watchSetting(
"Pill.shouldShowPillAvatar",
null,
this.configureShouldShowPillAvatar,
);
this.surroundWithHandle = SettingsStore.watchSetting(
"MessageComposerInput.surroundWith",
null,
this.surroundWithSettingChanged,
);
}
public componentDidUpdate(prevProps: IProps) {
@ -208,7 +229,8 @@ export default class BasicMessageEditor extends React.Component<IProps, IState>
private updateEditorState = (selection: Caret, inputType?: string, diff?: IDiff): void => {
renderModel(this.editorRef.current, this.props.model);
if (selection) { // set the caret/selection
if (selection) {
// set the caret/selection
try {
setSelection(this.editorRef.current, this.props.model, selection);
} catch (err) {
@ -246,11 +268,7 @@ export default class BasicMessageEditor extends React.Component<IProps, IState>
isTyping = false;
}
}
SdkContextClass.instance.typingStore.setSelfTyping(
this.props.room.roomId,
this.props.threadId,
isTyping,
);
SdkContextClass.instance.typingStore.setSelfTyping(this.props.room.roomId, this.props.threadId, isTyping);
if (this.props.onChange) {
this.props.onChange();
@ -259,7 +277,7 @@ export default class BasicMessageEditor extends React.Component<IProps, IState>
private showPlaceholder(): void {
// escape single quotes
const placeholder = this.props.placeholder.replace(/'/g, '\\\'');
const placeholder = this.props.placeholder.replace(/'/g, "\\'");
this.editorRef.current.style.setProperty("--placeholder", `'${placeholder}'`);
this.editorRef.current.classList.add("mx_BasicMessageComposer_inputEmpty");
}
@ -287,7 +305,7 @@ export default class BasicMessageEditor extends React.Component<IProps, IState>
// however, doing this async seems to break things in Safari for some reason, so browser sniff.
const ua = navigator.userAgent.toLowerCase();
const isSafari = ua.includes('safari/') && !ua.includes('chrome/');
const isSafari = ua.includes("safari/") && !ua.includes("chrome/");
if (isSafari) {
this.onInput({ inputType: "insertCompositionText" });
@ -311,7 +329,7 @@ export default class BasicMessageEditor extends React.Component<IProps, IState>
if (text) {
const { model } = this.props;
const range = getRangeForSelection(this.editorRef.current, model, selection);
const selectedParts = range.parts.map(p => p.serialize());
const selectedParts = range.parts.map((p) => p.serialize());
event.clipboardData.setData("application/x-element-composer", JSON.stringify(selectedParts));
event.clipboardData.setData("text/plain", text); // so plain copy/paste works
if (type === "cut") {
@ -346,7 +364,7 @@ export default class BasicMessageEditor extends React.Component<IProps, IState>
let parts: Part[];
if (partsText) {
const serializedTextParts = JSON.parse(partsText);
parts = serializedTextParts.map(p => partCreator.deserializePart(p));
parts = serializedTextParts.map((p) => partCreator.deserializePart(p));
} else {
parts = parsePlainTextMessage(plainText, partCreator, { shouldEscape: false });
}
@ -593,16 +611,16 @@ export default class BasicMessageEditor extends React.Component<IProps, IState>
private async tabCompleteName(): Promise<void> {
try {
await new Promise<void>(resolve => this.setState({ showVisualBell: false }, resolve));
await new Promise<void>((resolve) => this.setState({ showVisualBell: false }, resolve));
const { model } = this.props;
const caret = this.getCaret();
const position = model.positionForOffset(caret.offset, caret.atNodeEnd);
const range = model.startRange(position);
range.expandBackwardsWhile((index, offset, part) => {
return part.text[offset] !== " " && part.text[offset] !== "+" && (
part.type === Type.Plain ||
part.type === Type.PillCandidate ||
part.type === Type.Command
return (
part.text[offset] !== " " &&
part.text[offset] !== "+" &&
(part.type === Type.Plain || part.type === Type.PillCandidate || part.type === Type.Command)
);
});
const { partCreator } = model;
@ -664,7 +682,7 @@ export default class BasicMessageEditor extends React.Component<IProps, IState>
};
private transform = (documentPosition: DocumentPosition): void => {
const shouldReplace = SettingsStore.getValue('MessageComposerInput.autoReplaceEmoji');
const shouldReplace = SettingsStore.getValue("MessageComposerInput.autoReplaceEmoji");
if (shouldReplace) this.replaceEmoticon(documentPosition, REGEX_EMOTICON_WHITESPACE);
};
@ -685,10 +703,12 @@ export default class BasicMessageEditor extends React.Component<IProps, IState>
const partCreator = model.partCreator;
// TODO: does this allow us to get rid of EditorStateTransfer?
// not really, but we could not serialize the parts, and just change the autoCompleter
partCreator.setAutoCompleteCreator(getAutoCompleteCreator(
() => this.autocompleteRef.current,
query => new Promise(resolve => this.setState({ query }, resolve)),
));
partCreator.setAutoCompleteCreator(
getAutoCompleteCreator(
() => this.autocompleteRef.current,
(query) => new Promise((resolve) => this.setState({ query }, resolve)),
),
);
// initial render of model
this.updateEditorState(this.getInitialCaretPosition());
// attach input listener by hand so React doesn't proxy the events,
@ -731,23 +751,25 @@ export default class BasicMessageEditor extends React.Component<IProps, IState>
if (this.state.autoComplete) {
const query = this.state.query;
const queryLen = query.length;
autoComplete = (<div className="mx_BasicMessageComposer_AutoCompleteWrapper">
<Autocomplete
ref={this.autocompleteRef}
query={query}
onConfirm={this.onAutoCompleteConfirm}
onSelectionChange={this.onAutoCompleteSelectionChange}
selection={{ beginning: true, end: queryLen, start: queryLen }}
room={this.props.room}
/>
</div>);
autoComplete = (
<div className="mx_BasicMessageComposer_AutoCompleteWrapper">
<Autocomplete
ref={this.autocompleteRef}
query={query}
onConfirm={this.onAutoCompleteConfirm}
onSelectionChange={this.onAutoCompleteSelectionChange}
selection={{ beginning: true, end: queryLen, start: queryLen }}
room={this.props.room}
/>
</div>
);
}
const wrapperClasses = classNames("mx_BasicMessageComposer", {
"mx_BasicMessageComposer_input_error": this.state.showVisualBell,
mx_BasicMessageComposer_input_error: this.state.showVisualBell,
});
const classes = classNames("mx_BasicMessageComposer_input", {
"mx_BasicMessageComposer_input_shouldShowPillAvatar": this.state.showPillAvatar,
"mx_BasicMessageComposer_input_disabled": this.props.disabled,
mx_BasicMessageComposer_input_shouldShowPillAvatar: this.state.showPillAvatar,
mx_BasicMessageComposer_input_disabled: this.props.disabled,
});
const shortcuts = {
@ -765,33 +787,39 @@ export default class BasicMessageEditor extends React.Component<IProps, IState>
activeDescendant = generateCompletionDomId(completionIndex);
}
return (<div className={wrapperClasses}>
{ autoComplete }
<MessageComposerFormatBar ref={this.formatBarRef} onAction={this.onFormatAction} shortcuts={shortcuts} />
<div
className={classes}
contentEditable={this.props.disabled ? null : true}
tabIndex={0}
onBlur={this.onBlur}
onFocus={this.onFocus}
onCopy={this.onCopy}
onCut={this.onCut}
onPaste={this.onPaste}
onKeyDown={this.onKeyDown}
ref={this.editorRef}
aria-label={this.props.label}
role="textbox"
aria-multiline="true"
aria-autocomplete="list"
aria-haspopup="listbox"
aria-expanded={hasAutocomplete ? true : undefined}
aria-owns={hasAutocomplete ? "mx_Autocomplete" : undefined}
aria-activedescendant={activeDescendant}
dir="auto"
aria-disabled={this.props.disabled}
data-testid="basicmessagecomposer"
/>
</div>);
return (
<div className={wrapperClasses}>
{autoComplete}
<MessageComposerFormatBar
ref={this.formatBarRef}
onAction={this.onFormatAction}
shortcuts={shortcuts}
/>
<div
className={classes}
contentEditable={this.props.disabled ? null : true}
tabIndex={0}
onBlur={this.onBlur}
onFocus={this.onFocus}
onCopy={this.onCopy}
onCut={this.onCut}
onPaste={this.onPaste}
onKeyDown={this.onKeyDown}
ref={this.editorRef}
aria-label={this.props.label}
role="textbox"
aria-multiline="true"
aria-autocomplete="list"
aria-haspopup="listbox"
aria-expanded={hasAutocomplete ? true : undefined}
aria-owns={hasAutocomplete ? "mx_Autocomplete" : undefined}
aria-activedescendant={activeDescendant}
dir="auto"
aria-disabled={this.props.disabled}
data-testid="basicmessagecomposer"
/>
</div>
);
}
public focus(): void {
@ -803,8 +831,7 @@ export default class BasicMessageEditor extends React.Component<IProps, IState>
const { model } = this.props;
const { partCreator } = model;
const member = this.props.room.getMember(userId);
const displayName = member ?
member.rawDisplayName : userId;
const displayName = member ? member.rawDisplayName : userId;
const caret = this.getCaret();
const position = model.positionForOffset(caret.offset, caret.atNodeEnd);
// Insert suffix only if the caret is at the start of the composer