Composer: Listen for compose start/end and apply proper styling

Co-authored-by: Scott Nonnenberg <scott@signal.org>
This commit is contained in:
automated-signal 2025-01-30 19:25:21 -06:00 committed by GitHub
parent f15d5049f8
commit 7cc07f99d6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 42 additions and 20 deletions

View file

@ -9,6 +9,7 @@ import {
matchNewline,
matchBreak,
} from '@signalapp/quill-cjs/modules/clipboard';
import Emitter from '@signalapp/quill-cjs/core/emitter';
import classNames from 'classnames';
import { Manager, Reference } from 'react-popper';
import type { Range as RangeStatic } from '@signalapp/quill-cjs';
@ -828,9 +829,16 @@ export function CompositionInput(props: Props): React.ReactElement {
quillRef.current = quill;
quill.on(Emitter.events.COMPOSITION_START, () => {
quill.root.classList.toggle('ql-blank', false);
});
quill.on(Emitter.events.COMPOSITION_END, () => {
quill.root.classList.toggle('ql-blank', quill.editor.isBlank());
});
// When loading a multi-line message out of a draft, the cursor
// position needs to be pushed to the end of the input manually.
quill.once('editor-change', () => {
quill.once(Emitter.events.EDITOR_CHANGE, () => {
setTimeout(() => {
quill.setSelection(quill.getLength(), 0);
quill.root.classList.add('ql-editor--loaded');
@ -838,7 +846,7 @@ export function CompositionInput(props: Props): React.ReactElement {
});
quill.on(
'selection-change',
Emitter.events.SELECTION_CHANGE,
(newRange: RangeStatic, oldRange: RangeStatic) => {
// If we lose focus, store the last edit point for emoji insertion
if (newRange == null) {

View file

@ -3,6 +3,7 @@
import React, { createRef } from 'react';
import Quill from '@signalapp/quill-cjs';
import Emitter from '@signalapp/quill-cjs/core/emitter';
import type { Delta } from '@signalapp/quill-cjs';
export type Props = {
@ -32,7 +33,7 @@ export class SimpleQuillWrapper extends React.Component<Props> {
);
}
this.quill.on('editor-change', this.props.onChange);
this.quill.on(Emitter.events.EDITOR_CHANGE, this.props.onChange);
const { defaultValue } = this.props;
if (defaultValue) {

View file

@ -1,8 +1,9 @@
// Copyright 2020 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import type Quill from '@signalapp/quill-cjs';
import { Delta } from '@signalapp/quill-cjs';
import Emitter from '@signalapp/quill-cjs/core/emitter';
import type Quill from '@signalapp/quill-cjs';
import * as log from '../../logging/log';
import type { EmojiData } from '../../components/emoji/lib';
@ -53,7 +54,7 @@ export class AutoSubstituteAsciiEmojis {
this.options = options;
this.quill = quill;
this.quill.on('text-change', (_now, _before, source) => {
this.quill.on(Emitter.events.TEXT_CHANGE, (_now, _before, source) => {
if (source !== 'user') {
return;
}

View file

@ -1,10 +1,11 @@
// Copyright 2020 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import type Quill from '@signalapp/quill-cjs';
import { Delta } from '@signalapp/quill-cjs';
import Emitter from '@signalapp/quill-cjs/core/emitter';
import React from 'react';
import _, { isNumber } from 'lodash';
import type Quill from '@signalapp/quill-cjs';
import { Popper } from 'react-popper';
import classNames from 'classnames';
@ -92,12 +93,15 @@ export class EmojiCompletion {
const debouncedOnTextChange = _.debounce(() => this.onTextChange(), 100);
this.quill.on('text-change', (_now, _before, source) => {
this.quill.on(Emitter.events.TEXT_CHANGE, (_now, _before, source) => {
if (source === 'user') {
debouncedOnTextChange();
}
});
this.quill.on('selection-change', this.onSelectionChange.bind(this));
this.quill.on(
Emitter.events.SELECTION_CHANGE,
this.onSelectionChange.bind(this)
);
}
destroy(): void {

View file

@ -1,15 +1,16 @@
// Copyright 2020 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import type Quill from '@signalapp/quill-cjs';
import type { Op } from '@signalapp/quill-cjs';
import type { Context as KeyboardContext } from '@signalapp/quill-cjs/modules/keyboard';
import React from 'react';
import classNames from 'classnames';
import { Popper } from 'react-popper';
import { createPortal } from 'react-dom';
import type { VirtualElement } from '@popperjs/core';
import { isString } from 'lodash';
import Emitter from '@signalapp/quill-cjs/core/emitter';
import type Quill from '@signalapp/quill-cjs';
import type { Op } from '@signalapp/quill-cjs';
import type { Context as KeyboardContext } from '@signalapp/quill-cjs/modules/keyboard';
import type { VirtualElement } from '@popperjs/core';
import * as log from '../../logging/log';
import * as Errors from '../../types/errors';
@ -89,7 +90,7 @@ export class FormattingMenu {
this.options = options;
this.root = document.body.appendChild(document.createElement('div'));
this.quill.on('editor-change', this.onEditorChange.bind(this));
this.quill.on(Emitter.events.EDITOR_CHANGE, this.onEditorChange.bind(this));
// We override these keybindings, which means that we need to move their priority
// above the built-in shortcuts, which don't exactly do what we want.

View file

@ -1,15 +1,16 @@
// Copyright 2020 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import _ from 'lodash';
import type Quill from '@signalapp/quill-cjs';
import { Delta } from '@signalapp/quill-cjs';
import type { RefObject } from 'react';
import React from 'react';
import _ from 'lodash';
import { Delta } from '@signalapp/quill-cjs';
import Emitter from '@signalapp/quill-cjs/core/emitter';
import type Quill from '@signalapp/quill-cjs';
import type { RefObject } from 'react';
import { Popper } from 'react-popper';
import classNames from 'classnames';
import { createPortal } from 'react-dom';
import { Avatar, AvatarSize } from '../../components/Avatar';
import type { LocalizerType, ThemeType } from '../../types/Util';
import type { MemberType, MemberRepository } from '../memberRepository';
@ -76,8 +77,14 @@ export class MentionCompletion {
this.quill.keyboard.addBinding({ key: 39 }, clearResults); // Right Arrow
this.quill.keyboard.addBinding({ key: 40 }, changeIndex(1)); // Down Arrow
this.quill.on('text-change', _.debounce(this.onTextChange.bind(this), 0));
this.quill.on('selection-change', this.onSelectionChange.bind(this));
this.quill.on(
Emitter.events.TEXT_CHANGE,
_.debounce(this.onTextChange.bind(this), 0)
);
this.quill.on(
Emitter.events.SELECTION_CHANGE,
this.onSelectionChange.bind(this)
);
}
destroy(): void {