Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/messageComposer/attachmentManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,14 @@ export class AttachmentManager {
this.composer.updateConfig({ attachments: { fileUploadFilter } });
}

get maxNumberOfFilesPerMessage() {
return this.config.maxNumberOfFilesPerMessage;
}

set maxNumberOfFilesPerMessage(
maxNumberOfFilesPerMessage: AttachmentManagerConfig['maxNumberOfFilesPerMessage'],
) {
if (maxNumberOfFilesPerMessage === this.maxNumberOfFilesPerMessage) return;
this.composer.updateConfig({ attachments: { maxNumberOfFilesPerMessage } });
}

Expand Down
1 change: 1 addition & 0 deletions src/messageComposer/linkPreviewsManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ export class LinkPreviewsManager implements ILinkPreviewsManager {
}

set enabled(enabled: LinkPreviewsManagerConfig['enabled']) {
if (enabled === this.enabled) return;
this.composer.updateConfig({ linkPreviews: { enabled } });
}

Expand Down
2 changes: 1 addition & 1 deletion src/messageComposer/middleware/textComposer/mentions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ export const createMentionsMiddleware = (
trigger: finalOptions.trigger,
},
},
stop: true, // Stop other middleware from processing '@' character
status: 'complete', // Stop other middleware from processing '@' character
});
},
onSuggestionItemSelect: ({
Expand Down
38 changes: 29 additions & 9 deletions src/messageComposer/textComposer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,22 +78,43 @@ export class TextComposer {
}

set enabled(enabled: boolean) {
if (enabled === this.enabled) return;
this.composer.updateConfig({ text: { enabled } });
}

set defaultValue(defaultValue: string) {
get defaultValue() {
return this.composer.config.text.defaultValue;
}

set defaultValue(defaultValue: string | undefined) {
if (defaultValue === this.defaultValue) return;
this.composer.updateConfig({ text: { defaultValue } });
}

set maxLengthOnEdit(maxLengthOnEdit: number) {
get maxLengthOnEdit() {
return this.composer.config.text.maxLengthOnEdit;
}

set maxLengthOnEdit(maxLengthOnEdit: number | undefined) {
if (maxLengthOnEdit === this.maxLengthOnEdit) return;
this.composer.updateConfig({ text: { maxLengthOnEdit } });
}

set maxLengthOnSend(maxLengthOnSend: number) {
get maxLengthOnSend() {
return this.composer.config.text.maxLengthOnSend;
}

set maxLengthOnSend(maxLengthOnSend: number | undefined) {
if (maxLengthOnSend === this.maxLengthOnSend) return;
this.composer.updateConfig({ text: { maxLengthOnSend } });
}

get publishTypingEvents() {
return this.composer.config.text.publishTypingEvents;
}

set publishTypingEvents(publishTypingEvents: boolean) {
if (publishTypingEvents === this.publishTypingEvents) return;
this.composer.updateConfig({ text: { publishTypingEvents } });
}

Expand Down Expand Up @@ -151,22 +172,21 @@ export class TextComposer {
};

setText = (text: string) => {
if (!this.enabled) return;
if (!this.enabled || text === this.text) return;
this.state.partialNext({ text });
};

setSelection = (selection: TextSelection) => {
if (!this.enabled) return;
const selectionChanged =
selection.start !== this.selection.start || selection.end !== this.selection.end;
if (!this.enabled || !selectionChanged) return;
this.state.partialNext({ selection });
};

insertText = ({ text, selection }: { text: string; selection?: TextSelection }) => {
if (!this.enabled) return;

const finalSelection: TextSelection = selection ?? {
start: this.text.length,
end: this.text.length,
};
const finalSelection: TextSelection = selection ?? this.selection;
const { maxLengthOnEdit } = this.composer.config.text ?? {};
const currentText = this.text;
const textBeforeTrim = [
Expand Down
89 changes: 89 additions & 0 deletions test/unit/MessageComposer/textComposer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { textIsEmpty } from '../../../src/messageComposer/textComposer';
import { DraftResponse, LocalMessage } from '../../../src/types';
import { logChatPromiseExecution } from '../../../src/utils';
import { TextComposerConfig } from '../../../src/messageComposer/configuration';
import { TextComposerState } from '../../../src';

const textComposerMiddlewareExecuteOutput = {
state: {
Expand Down Expand Up @@ -393,6 +394,94 @@ describe('TextComposer', () => {
textComposer.setText('New text');
expect(textComposer.text).toBe(message.text);
});
it('should not update the text when setting the same value', () => {
const message: LocalMessage = {
id: 'test-message',
type: 'regular',
text: 'Hello world',
};
const {
messageComposer: { textComposer },
} = setup({ composition: message, config: { enabled: false } });
const subscriber = vi.fn();
const originalText = textComposer.text;
textComposer.state.subscribeWithSelector(({ text }) => ({ text }), subscriber);
expect(subscriber).toHaveBeenCalledWith({ text: originalText }, undefined);
textComposer.setText(originalText);
expect(textComposer.text).toBe(originalText);
expect(subscriber).toHaveBeenCalledTimes(1);
});
});

describe('setSelection', () => {
const message: LocalMessage = {
id: 'test-message',
type: 'regular',
text: 'Hello world',
};
it('should update the selection', () => {
const {
messageComposer: { textComposer },
} = setup({ composition: message });
const subscriber = vi.fn();
textComposer.state.subscribeWithSelector(
({ selection }) => ({ selection }),
subscriber,
);
expect(subscriber).toHaveBeenCalledWith(
{ selection: { end: message.text!.length, start: message.text!.length } },
undefined,
);
expect(textComposer.selection).toEqual({
end: message.text!.length,
start: message.text!.length,
});
textComposer.setSelection({ end: 2, start: 2 });
expect(textComposer.selection).toEqual({ end: 2, start: 2 });
expect(subscriber).toHaveBeenCalledWith(
{ selection: { end: 2, start: 2 } },
{ selection: { end: message.text!.length, start: message.text!.length } },
);
expect(subscriber).toHaveBeenCalledTimes(2);
});

it('should not update the selection with the same value', () => {
const {
messageComposer: { textComposer },
} = setup({ composition: message });
const originalSelection = textComposer.selection;
const subscriber = vi.fn();
textComposer.state.subscribeWithSelector(
({ selection }) => ({ ...selection }),
subscriber,
);
expect(subscriber).toHaveBeenCalledWith(originalSelection, undefined);
expect(textComposer.selection).toEqual(originalSelection);
textComposer.setSelection(originalSelection);
expect(textComposer.selection).toEqual(originalSelection);
expect(subscriber).toHaveBeenCalledTimes(1);
});

it('should not update the selection when text composer disabled', () => {
const {
messageComposer: { textComposer },
} = setup({ composition: message, config: { enabled: false } });
const originalSelection = textComposer.selection;
const subscriber = vi.fn();
textComposer.state.subscribeWithSelector(
({ selection }) => ({ selection }),
subscriber,
);
expect(subscriber).toHaveBeenCalledWith(
{ selection: { end: message.text!.length, start: message.text!.length } },
undefined,
);

expect(textComposer.selection).toEqual(originalSelection);
textComposer.setSelection({ end: 2, start: 2 });
expect(textComposer.selection).toEqual(originalSelection);
expect(subscriber).toHaveBeenCalledTimes(1);
});
});

describe('insertText', () => {
Expand Down
Loading