Skip to content

Commit c82a64f

Browse files
authored
feat: introduce contentIsEmpty flag for messageComposer (#1705)
## CLA - [ ] I have signed the [Stream CLA](https://docs.google.com/forms/d/e/1FAIpQLScFKsKkAJI7mhCr7K9rEIOpqIDThrWxuvxnwUq2XkHyG154vQ/viewform) (required). - [ ] Code changes are tested ## Description of the changes, What, Why and How? https://linear.app/stream/issue/REACT-891/user-should-be-able-to-quote-a-message-with-a-voice-message - `compositionIsEmpty` -> used to track if draft can be discarded - `contentIsEmpty` -> used to track if message has any content ## Changelog -
1 parent 2e23a5c commit c82a64f

2 files changed

Lines changed: 65 additions & 1 deletion

File tree

src/messageComposer/messageComposer.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -344,8 +344,11 @@ export class MessageComposer extends WithSubscriptions {
344344
}
345345

346346
get compositionIsEmpty() {
347+
return !this.quotedMessage && this.contentIsEmpty;
348+
}
349+
350+
get contentIsEmpty() {
347351
return (
348-
!this.quotedMessage &&
349352
this.textComposer.textIsEmpty &&
350353
!this.attachmentManager.attachments.length &&
351354
!this.pollId &&

test/unit/MessageComposer/messageComposer.test.ts

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,67 @@ describe('MessageComposer', () => {
624624

625625
expect(messageComposer.compositionIsEmpty).toBe(true);
626626
});
627+
628+
describe('contentIsEmpty', () => {
629+
it('is true when text, attachments, poll, and location are empty', () => {
630+
const { messageComposer } = setup();
631+
messageComposer.textComposer.state.partialNext({
632+
text: '',
633+
mentionedUsers: [],
634+
selection: { start: 0, end: 0 },
635+
});
636+
expect(messageComposer.contentIsEmpty).toBe(true);
637+
});
638+
639+
it('is false when text, attachments, poll, or valid location is set', () => {
640+
const { messageComposer } = setup();
641+
messageComposer.textComposer.state.partialNext({
642+
text: '',
643+
mentionedUsers: [],
644+
selection: { start: 0, end: 0 },
645+
});
646+
647+
messageComposer.textComposer.state.partialNext({ text: 'hi' });
648+
expect(messageComposer.contentIsEmpty).toBe(false);
649+
messageComposer.textComposer.state.partialNext({ text: '' });
650+
651+
messageComposer.attachmentManager.state.partialNext({
652+
attachments: [
653+
{ type: 'x', localMetadata: { id: 'x', uploadState: 'finished', file: {} } },
654+
],
655+
});
656+
expect(messageComposer.contentIsEmpty).toBe(false);
657+
messageComposer.attachmentManager.state.partialNext({ attachments: [] });
658+
659+
messageComposer.state.partialNext({ pollId: 'poll-id' });
660+
expect(messageComposer.contentIsEmpty).toBe(false);
661+
messageComposer.state.partialNext({ pollId: null });
662+
663+
messageComposer.updateConfig({ location: { enabled: true } });
664+
messageComposer.locationComposer.setData({ latitude: 1, longitude: 1 });
665+
expect(messageComposer.contentIsEmpty).toBe(false);
666+
});
667+
668+
it('is unaffected by quoted message (unlike compositionIsEmpty)', () => {
669+
const { messageComposer } = setup();
670+
messageComposer.textComposer.state.partialNext({
671+
text: '',
672+
mentionedUsers: [],
673+
selection: { start: 0, end: 0 },
674+
});
675+
messageComposer.setQuotedMessage({
676+
id: 'id',
677+
type: 'regular',
678+
status: 'delivered',
679+
created_at: new Date(),
680+
updated_at: new Date(),
681+
deleted_at: null,
682+
pinned_at: null,
683+
});
684+
expect(messageComposer.contentIsEmpty).toBe(true);
685+
expect(messageComposer.compositionIsEmpty).toBe(false);
686+
});
687+
});
627688
});
628689

629690
describe('offlineDB enabled', () => {

0 commit comments

Comments
 (0)