summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXavier Dubuc <xdu@odoo.com>2020-08-20 13:31:23 +0000
committerAlexandre Kühn <aku@odoo.com>2020-09-03 14:34:28 +0000
commit586496abcf802794bb9eaa70cae3654644e01f86 (patch)
tree1fe148ecee7a5611a0111cad9ccfb4398075f306
parent09d5386a373c5a37aa2273188b1038deeef79648 (diff)
[FIX] mail: allow composer text input to send message with ctrl+enter
Also allow meta+enter task-2296863 closes odoo/odoo#57045 X-original-commit: 6bad3666be3d3631eaadae409d0cabcdd02661a8 Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
-rw-r--r--addons/mail/static/src/components/chatter/chatter.xml2
-rw-r--r--addons/mail/static/src/components/chatter/chatter_tests.js105
-rw-r--r--addons/mail/static/src/components/composer/composer.js25
-rw-r--r--addons/mail/static/src/components/composer/composer.xml4
-rw-r--r--addons/mail/static/src/components/composer/composer_tests.js128
-rw-r--r--addons/mail/static/src/components/composer_text_input/composer_text_input.js63
-rw-r--r--addons/mail/static/src/components/discuss/discuss.xml1
-rw-r--r--addons/mail/static/src/components/discuss/tests/discuss_inbox_tests.js22
-rw-r--r--addons/mail/static/src/components/discuss/tests/discuss_tests.js201
-rw-r--r--addons/mail/static/src/components/thread_view/thread_view.xml2
10 files changed, 500 insertions, 53 deletions
diff --git a/addons/mail/static/src/components/chatter/chatter.xml b/addons/mail/static/src/components/chatter/chatter.xml
index a48396f813c..e5601dd7974 100644
--- a/addons/mail/static/src/components/chatter/chatter.xml
+++ b/addons/mail/static/src/components/chatter/chatter.xml
@@ -14,9 +14,9 @@
t-att-class="{ 'o-bordered': chatter.hasExternalBorder }"
composerLocalId="chatter.thread.composer.localId"
hasMentionSuggestionsBelowPosition="true"
- hasTextInputSendOnEnterEnabled="false"
isCompact="false"
isExpandable="true"
+ textInputSendShortcuts="['ctrl-enter', 'meta-enter']"
t-on-o-message-posted="_onComposerMessagePosted"
t-ref="composer"
/>
diff --git a/addons/mail/static/src/components/chatter/chatter_tests.js b/addons/mail/static/src/components/chatter/chatter_tests.js
index 73ff0eb2c38..d5c2932a6d7 100644
--- a/addons/mail/static/src/components/chatter/chatter_tests.js
+++ b/addons/mail/static/src/components/chatter/chatter_tests.js
@@ -342,6 +342,111 @@ QUnit.test('should not display user notification messages in chatter', async fun
);
});
+QUnit.test('post message with "CTRL-Enter" keyboard shortcut', async function (assert) {
+ assert.expect(2);
+
+ this.data['res.partner'].records.push({ id: 100 });
+ await this.start();
+ const chatter = this.env.models['mail.chatter'].create({
+ threadId: 100,
+ threadModel: 'res.partner',
+ });
+ await this.createChatterComponent({ chatter });
+ assert.containsNone(
+ document.body,
+ '.o_Message',
+ "should not have any message initially in chatter"
+ );
+
+ await afterNextRender(() =>
+ document.querySelector('.o_ChatterTopbar_buttonSendMessage').click()
+ );
+ await afterNextRender(() => {
+ document.querySelector(`.o_ComposerTextInput_textarea`).focus();
+ document.execCommand('insertText', false, "Test");
+ });
+ await afterNextRender(() => {
+ const kevt = new window.KeyboardEvent('keydown', { ctrlKey: true, key: "Enter" });
+ document.querySelector('.o_ComposerTextInput_textarea').dispatchEvent(kevt);
+ });
+ assert.containsOnce(
+ document.body,
+ '.o_Message',
+ "should now have single message in chatter after posting message from pressing 'CTRL-Enter' in text input of composer"
+ );
+});
+
+QUnit.test('post message with "META-Enter" keyboard shortcut', async function (assert) {
+ assert.expect(2);
+
+ this.data['res.partner'].records.push({ id: 100 });
+ await this.start();
+ const chatter = this.env.models['mail.chatter'].create({
+ threadId: 100,
+ threadModel: 'res.partner',
+ });
+ await this.createChatterComponent({ chatter });
+ assert.containsNone(
+ document.body,
+ '.o_Message',
+ "should not have any message initially in chatter"
+ );
+
+ await afterNextRender(() =>
+ document.querySelector('.o_ChatterTopbar_buttonSendMessage').click()
+ );
+ await afterNextRender(() => {
+ document.querySelector(`.o_ComposerTextInput_textarea`).focus();
+ document.execCommand('insertText', false, "Test");
+ });
+ await afterNextRender(() => {
+ const kevt = new window.KeyboardEvent('keydown', { key: "Enter", metaKey: true });
+ document.querySelector('.o_ComposerTextInput_textarea').dispatchEvent(kevt);
+ });
+ assert.containsOnce(
+ document.body,
+ '.o_Message',
+ "should now have single message in channel after posting message from pressing 'META-Enter' in text input of composer"
+ );
+});
+
+QUnit.test('do not post message with "Enter" keyboard shortcut', async function (assert) {
+ // Note that test doesn't assert Enter makes a newline, because this
+ // default browser cannot be simulated with just dispatching
+ // programmatically crafted events...
+ assert.expect(2);
+
+ this.data['res.partner'].records.push({ id: 100 });
+ await this.start();
+ const chatter = this.env.models['mail.chatter'].create({
+ threadId: 100,
+ threadModel: 'res.partner',
+ });
+ await this.createChatterComponent({ chatter });
+ assert.containsNone(
+ document.body,
+ '.o_Message',
+ "should not have any message initially in chatter"
+ );
+
+ await afterNextRender(() =>
+ document.querySelector('.o_ChatterTopbar_buttonSendMessage').click()
+ );
+ await afterNextRender(() => {
+ document.querySelector(`.o_ComposerTextInput_textarea`).focus();
+ document.execCommand('insertText', false, "Test");
+ });
+ await afterNextRender(() => {
+ const kevt = new window.KeyboardEvent('keydown', { key: "Enter" });
+ document.querySelector('.o_ComposerTextInput_textarea').dispatchEvent(kevt);
+ });
+ assert.containsNone(
+ document.body,
+ '.o_Message',
+ "should still not have any message in mailing channel after pressing 'Enter' in text input of composer"
+ );
+});
+
});
});
});
diff --git a/addons/mail/static/src/components/composer/composer.js b/addons/mail/static/src/components/composer/composer.js
index 0b23ee4ec22..510a5ac6038 100644
--- a/addons/mail/static/src/components/composer/composer.js
+++ b/addons/mail/static/src/components/composer/composer.js
@@ -262,6 +262,13 @@ class Composer extends Component {
}
/**
+ * @private
+ */
+ _onComposerTextInputSendShortcut() {
+ this._postMessage();
+ }
+
+ /**
* Called when some files have been dropped in the dropzone.
*
* @private
@@ -340,13 +347,6 @@ class Composer extends Component {
await this._fileUploaderRef.comp.uploadFiles(ev.clipboardData.files);
}
- /**
- * @private
- */
- _onTextInputKeydownEnter() {
- this._postMessage();
- }
-
}
Object.assign(Composer, {
@@ -357,7 +357,6 @@ Object.assign(Composer, {
hasDiscardButton: false,
hasFollowers: false,
hasSendButton: true,
- hasTextInputSendOnEnterEnabled: true,
hasThreadName: false,
hasThreadTyping: false,
isCompact: true,
@@ -381,7 +380,6 @@ Object.assign(Composer, {
optional: true,
},
hasSendButton: Boolean,
- hasTextInputSendOnEnterEnabled: Boolean,
hasThreadName: Boolean,
hasThreadTyping: Boolean,
showAttachmentsExtensions: {
@@ -403,6 +401,15 @@ Object.assign(Composer, {
},
isCompact: Boolean,
isExpandable: Boolean,
+ /**
+ * If set, keyboard shortcuts from text input to send message.
+ * If not set, will use default values from `ComposerTextInput`.
+ */
+ textInputSendShortcuts: {
+ type: Array,
+ element: String,
+ optional: true,
+ },
},
template: 'mail.Composer',
});
diff --git a/addons/mail/static/src/components/composer/composer.xml b/addons/mail/static/src/components/composer/composer.xml
index 30053cdd0f8..61694e5aaf1 100644
--- a/addons/mail/static/src/components/composer/composer.xml
+++ b/addons/mail/static/src/components/composer/composer.xml
@@ -75,9 +75,9 @@
}"
composerLocalId="composer.localId"
hasMentionSuggestionsBelowPosition="props.hasMentionSuggestionsBelowPosition"
- hasSendOnEnterEnabled="props.hasTextInputSendOnEnterEnabled"
isCompact="props.isCompact"
- t-on-o-keydown-enter="_onTextInputKeydownEnter"
+ sendShortcuts="props.textInputSendShortcuts"
+ t-on-o-composer-text-input-send-shortcut="_onComposerTextInputSendShortcut"
t-on-paste="_onPasteTextInput"
t-ref="textInput"
/>
diff --git a/addons/mail/static/src/components/composer/composer_tests.js b/addons/mail/static/src/components/composer/composer_tests.js
index 8e07affcccb..5d337e0ed0c 100644
--- a/addons/mail/static/src/components/composer/composer_tests.js
+++ b/addons/mail/static/src/components/composer/composer_tests.js
@@ -590,6 +590,116 @@ QUnit.test('composer: paste attachments', async function (assert) {
);
});
+QUnit.test('send message when enter is pressed while holding ctrl key (this shortcut is available)', async function (assert) {
+ // Note that test doesn't assert ENTER makes no newline, because this
+ // default browser cannot be simulated with just dispatching
+ // programmatically crafted events...
+ assert.expect(5);
+
+ this.data['mail.channel'].records.push({ id: 20 });
+ await this.start({
+ async mockRPC(route, args) {
+ if (args.method === 'message_post') {
+ assert.step('message_post');
+ }
+ return this._super(...arguments);
+ },
+ });
+ const thread = this.env.models['mail.thread'].find(thread =>
+ thread.id === 20 &&
+ thread.model === 'mail.channel'
+ );
+ await this.createComposerComponent(thread.composer, {
+ textInputSendShortcuts: ['ctrl-enter'],
+ });
+ // Type message
+ document.querySelector(`.o_ComposerTextInput_textarea`).focus();
+ document.execCommand('insertText', false, "test message");
+ assert.strictEqual(
+ document.querySelector(`.o_ComposerTextInput_textarea`).value,
+ "test message",
+ "should have inserted text content in editable"
+ );
+
+ await afterNextRender(() => {
+ const enterEvent = new window.KeyboardEvent('keydown', { key: 'Enter' });
+ document.querySelector(`.o_ComposerTextInput_textarea`)
+ .dispatchEvent(enterEvent);
+ });
+ assert.strictEqual(
+ document.querySelector(`.o_ComposerTextInput_textarea`).value,
+ "test message",
+ "should have inserted text content in editable as message has not been posted"
+ );
+
+ // Send message with ctrl+enter
+ await afterNextRender(() =>
+ document.querySelector(`.o_ComposerTextInput_textarea`)
+ .dispatchEvent(new window.KeyboardEvent('keydown', { ctrlKey: true, key: 'Enter' }))
+ );
+ assert.verifySteps(['message_post']);
+ assert.strictEqual(
+ document.querySelector(`.o_ComposerTextInput_textarea`).value,
+ "",
+ "should have no content in composer input as message has been posted"
+ );
+});
+
+QUnit.test('send message when enter is pressed while holding meta key (this shortcut is available)', async function (assert) {
+ // Note that test doesn't assert ENTER makes no newline, because this
+ // default browser cannot be simulated with just dispatching
+ // programmatically crafted events...
+ assert.expect(5);
+
+ this.data['mail.channel'].records.push({ id: 20 });
+ await this.start({
+ async mockRPC(route, args) {
+ if (args.method === 'message_post') {
+ assert.step('message_post');
+ }
+ return this._super(...arguments);
+ },
+ });
+ const thread = this.env.models['mail.thread'].find(thread =>
+ thread.id === 20 &&
+ thread.model === 'mail.channel'
+ );
+ await this.createComposerComponent(thread.composer, {
+ textInputSendShortcuts: ['meta-enter'],
+ });
+ // Type message
+ document.querySelector(`.o_ComposerTextInput_textarea`).focus();
+ document.execCommand('insertText', false, "test message");
+ assert.strictEqual(
+ document.querySelector(`.o_ComposerTextInput_textarea`).value,
+ "test message",
+ "should have inserted text content in editable"
+ );
+
+ await afterNextRender(() => {
+ const enterEvent = new window.KeyboardEvent('keydown', { key: 'Enter' });
+ document.querySelector(`.o_ComposerTextInput_textarea`)
+ .dispatchEvent(enterEvent);
+ });
+ assert.strictEqual(
+ document.querySelector(`.o_ComposerTextInput_textarea`).value,
+ "test message",
+ "should have inserted text content in editable as message has not been posted"
+ );
+
+ // Send message with meta+enter
+ await afterNextRender(() =>
+ document.querySelector(`.o_ComposerTextInput_textarea`)
+ .dispatchEvent(new window.KeyboardEvent('keydown', { key: 'Enter', metaKey: true }))
+ );
+ assert.verifySteps(['message_post']);
+ assert.strictEqual(
+ document.querySelector(`.o_ComposerTextInput_textarea`).value,
+ "",
+ "should have no content in composer input as message has been posted"
+ );
+});
+
QUnit.test('composer text input cleared on message post', async function (assert) {
assert.expect(4);
@@ -610,8 +720,10 @@ QUnit.test('composer text input cleared on message post', async function (assert
);
await this.createComposerComponent(thread.composer);
// Type message
- document.querySelector(`.o_ComposerTextInput_textarea`).focus();
- document.execCommand('insertText', false, "test message");
+ await afterNextRender(() => {
+ document.querySelector(`.o_ComposerTextInput_textarea`).focus();
+ document.execCommand('insertText', false, "test message");
+ });
assert.strictEqual(
document.querySelector(`.o_ComposerTextInput_textarea`).value,
"test message",
@@ -620,8 +732,7 @@ QUnit.test('composer text input cleared on message post', async function (assert
// Send message
await afterNextRender(() =>
- document.querySelector(`.o_ComposerTextInput_textarea`)
- .dispatchEvent(new window.KeyboardEvent('keydown', { key: 'Enter' }))
+ document.querySelector('.o_Composer_buttonSend').click()
);
assert.verifySteps(['message_post']);
assert.strictEqual(
@@ -691,8 +802,7 @@ QUnit.test('composer inputs cleared on message post in composer of a mailing cha
// Send message
await afterNextRender(() =>
- document.querySelector(`.o_ComposerTextInput_textarea`)
- .dispatchEvent(new window.KeyboardEvent('keydown', { key: 'Enter' }))
+ document.querySelector('.o_Composer_buttonSend').click()
);
assert.verifySteps(['message_post']);
assert.strictEqual(
@@ -956,7 +1066,7 @@ QUnit.test('composer: send button is disabled if attachment upload is not finish
);
});
-QUnit.test('warning when attempting to post message when attachments are still uploading', async function (assert) {
+QUnit.test('warning on send with shortcut when attempting to post message with still-uploading attachments', async function (assert) {
assert.expect(7);
await this.start({
@@ -991,7 +1101,9 @@ QUnit.test('warning when attempting to post message when attachments are still u
id: 20,
model: 'res.partner',
});
- await this.createComposerComponent(thread.composer);
+ await this.createComposerComponent(thread.composer, {
+ textInputSendShortcuts: ['enter'],
+ });
const file = await createFile({
content: 'hello, world',
contentType: 'text/plain',
diff --git a/addons/mail/static/src/components/composer_text_input/composer_text_input.js b/addons/mail/static/src/components/composer_text_input/composer_text_input.js
index 6a0943f9ca8..ef21d023cb5 100644
--- a/addons/mail/static/src/components/composer_text_input/composer_text_input.js
+++ b/addons/mail/static/src/components/composer_text_input/composer_text_input.js
@@ -241,18 +241,41 @@ class ComposerTextInput extends Component {
_onKeydownTextareaEnter(ev) {
if (this.composer.hasSuggestedPartners) {
ev.preventDefault();
- } else {
- if (!this.props.hasSendOnEnterEnabled) {
- return;
- }
- if (ev.shiftKey) {
- return;
- }
- if (this.env.messaging.device.isMobile) {
- return;
- }
- this.trigger('o-keydown-enter');
+ return;
+ }
+ if (
+ this.props.sendShortcuts.includes('ctrl-enter') &&
+ !ev.altKey &&
+ ev.ctrlKey &&
+ !ev.metaKey &&
+ !ev.shiftKey
+ ) {
+ this.trigger('o-composer-text-input-send-shortcut');
+ ev.preventDefault();
+ return;
+ }
+ if (
+ this.props.sendShortcuts.includes('enter') &&
+ !ev.altKey &&
+ !ev.ctrlKey &&
+ !ev.metaKey &&
+ !ev.shiftKey &&
+ !this.env.messaging.device.isMobile
+ ) {
+ this.trigger('o-composer-text-input-send-shortcut');
ev.preventDefault();
+ return;
+ }
+ if (
+ this.props.sendShortcuts.includes('meta-enter') &&
+ !ev.altKey &&
+ !ev.ctrlKey &&
+ ev.metaKey &&
+ !ev.shiftKey
+ ) {
+ this.trigger('o-composer-text-input-send-shortcut');
+ ev.preventDefault();
+ return;
}
}
@@ -341,13 +364,27 @@ Object.assign(ComposerTextInput, {
components,
defaultProps: {
hasMentionSuggestionsBelowPosition: false,
- hasSendOnEnterEnabled: true,
+ sendShortcuts: [],
},
props: {
composerLocalId: String,
hasMentionSuggestionsBelowPosition: Boolean,
- hasSendOnEnterEnabled: Boolean,
isCompact: Boolean,
+ /**
+ * Keyboard shortcuts from text input to send message.
+ */
+ sendShortcuts: {
+ type: Array,
+ element: String,
+ validate: prop => {
+ for (const shortcut of prop) {
+ if (!['ctrl-enter', 'enter', 'meta-enter'].includes(shortcut)) {
+ return false;
+ }
+ }
+ return true;
+ },
+ },
},
template: 'mail.ComposerTextInput',
});
diff --git a/addons/mail/static/src/components/discuss/discuss.xml b/addons/mail/static/src/components/discuss/discuss.xml
index d88b4796d9c..79838422f81 100644
--- a/addons/mail/static/src/components/discuss/discuss.xml
+++ b/addons/mail/static/src/components/discuss/discuss.xml
@@ -94,6 +94,7 @@
hasCurrentPartnerAvatar="!env.messaging.device.isMobile"
hasDiscardButton="true"
hasThreadName="true"
+ textInputSendShortcuts="['ctrl-enter', 'meta-enter']"
t-on-o-message-posted="_onReplyingToMessageMessagePosted"
t-ref="composer"
/>
diff --git a/addons/mail/static/src/components/discuss/tests/discuss_inbox_tests.js b/addons/mail/static/src/components/discuss/tests/discuss_inbox_tests.js
index 8ecc62e81b2..5f24acec192 100644
--- a/addons/mail/static/src/components/discuss/tests/discuss_inbox_tests.js
+++ b/addons/mail/static/src/components/discuss/tests/discuss_inbox_tests.js
@@ -312,11 +312,12 @@ QUnit.test('"reply to" composer should log note if message replied to is a note'
"Send button text should be 'Log'"
);
- await afterNextRender(() => {
- document.execCommand('insertText', false, "Test");
- document.querySelector(`.o_ComposerTextInput_textarea`)
- .dispatchEvent(new window.KeyboardEvent('keydown', { key: 'Enter' }));
- });
+ await afterNextRender(() =>
+ document.execCommand('insertText', false, "Test")
+ );
+ await afterNextRender(() =>
+ document.querySelector('.o_Composer_buttonSend').click()
+ );
assert.verifySteps(['message_post']);
});
@@ -363,11 +364,12 @@ QUnit.test('"reply to" composer should send message if message replied to is not
"Send button text should be 'Send'"
);
- await afterNextRender(() => {
- document.execCommand('insertText', false, "Test");
- document.querySelector(`.o_ComposerTextInput_textarea`)
- .dispatchEvent(new window.KeyboardEvent('keydown', { key: 'Enter' }));
- });
+ await afterNextRender(() =>
+ document.execCommand('insertText', false, "Test")
+ );
+ await afterNextRender(() =>
+ document.querySelector('.o_Composer_buttonSend').click()
+ );
assert.verifySteps(['message_post']);
});
diff --git a/addons/mail/static/src/components/discuss/tests/discuss_tests.js b/addons/mail/static/src/components/discuss/tests/discuss_tests.js
index 3f9e93d1de8..2983fcc11b2 100644
--- a/addons/mail/static/src/components/discuss/tests/discuss_tests.js
+++ b/addons/mail/static/src/components/discuss/tests/discuss_tests.js
@@ -2846,8 +2846,10 @@ QUnit.test('post a simple message', async function (assert) {
);
// insert some HTML in editable
- document.querySelector(`.o_ComposerTextInput_textarea`).focus();
- document.execCommand('insertText', false, "Test");
+ await afterNextRender(() => {
+ document.querySelector(`.o_ComposerTextInput_textarea`).focus();
+ document.execCommand('insertText', false, "Test");
+ });
assert.strictEqual(
document.querySelector(`.o_ComposerTextInput_textarea`).value,
"Test",
@@ -2855,8 +2857,7 @@ QUnit.test('post a simple message', async function (assert) {
);
await afterNextRender(() =>
- document.querySelector(`.o_ComposerTextInput_textarea`)
- .dispatchEvent(new window.KeyboardEvent('keydown', { key: 'Enter' }))
+ document.querySelector('.o_Composer_buttonSend').click()
);
assert.verifySteps(['message_post']);
assert.strictEqual(
@@ -2887,6 +2888,187 @@ QUnit.test('post a simple message', async function (assert) {
);
});
+QUnit.test('post message on non-mailing channel with "Enter" keyboard shortcut', async function (assert) {
+ assert.expect(2);
+
+ // channel expected to be found in the sidebar
+ // with a random unique id that will be referenced in the test
+ this.data['mail.channel'].records.push({ id: 20, mass_mailing: false });
+ await this.start({
+ discuss: {
+ params: {
+ default_active_id: 'mail.channel_20',
+ },
+ },
+ });
+ assert.containsNone(
+ document.body,
+ '.o_Message',
+ "should not have any message initially in channel"
+ );
+
+ // insert some HTML in editable
+ await afterNextRender(() => {
+ document.querySelector(`.o_ComposerTextInput_textarea`).focus();
+ document.execCommand('insertText', false, "Test");
+ });
+ await afterNextRender(() => {
+ const kevt = new window.KeyboardEvent('keydown', { key: "Enter" });
+ document.querySelector('.o_ComposerTextInput_textarea').dispatchEvent(kevt);
+ });
+ assert.containsOnce(
+ document.body,
+ '.o_Message',
+ "should now have single message in channel after posting message from pressing 'Enter' in text input of composer"
+ );
+});
+
+QUnit.test('do not post message on non-mailing channel with "SHIFT-Enter" keyboard shortcut', async function (assert) {
+ // Note that test doesn't assert SHIFT-Enter makes a newline, because this
+ // default browser cannot be simulated with just dispatching
+ // programmatically crafted events...
+ assert.expect(2);
+
+ // channel expected to be found in the sidebar
+ // with a random unique id that will be referenced in the test
+ this.data['mail.channel'].records.push({ id: 20, mass_mailing: true });
+ await this.start({
+ discuss: {
+ params: {
+ default_active_id: 'mail.channel_20',
+ },
+ },
+ });
+ assert.containsNone(
+ document.body,
+ '.o_Message',
+ "should not have any message initially in channel"
+ );
+
+ // insert some HTML in editable
+ await afterNextRender(() => {
+ document.querySelector(`.o_ComposerTextInput_textarea`).focus();
+ document.execCommand('insertText', false, "Test");
+ });
+ await afterNextRender(() => {
+ const kevt = new window.KeyboardEvent('keydown', { key: "Enter", shiftKey: true });
+ document.querySelector('.o_ComposerTextInput_textarea').dispatchEvent(kevt);
+ });
+ assert.containsNone(
+ document.body,
+ '.o_Message',
+ "should still not have any message in channel after pressing 'Shift-Enter' in text input of composer"
+ );
+});
+
+QUnit.test('post message on mailing channel with "CTRL-Enter" keyboard shortcut', async function (assert) {
+ assert.expect(2);
+
+ // channel expected to be found in the sidebar
+ // with a random unique id that will be referenced in the test
+ this.data['mail.channel'].records.push({ id: 20, mass_mailing: true });
+ await this.start({
+ discuss: {
+ params: {
+ default_active_id: 'mail.channel_20',
+ },
+ },
+ });
+ assert.containsNone(
+ document.body,
+ '.o_Message',
+ "should not have any message initially in channel"
+ );
+
+ // insert some HTML in editable
+ await afterNextRender(() => {
+ document.querySelector(`.o_ComposerTextInput_textarea`).focus();
+ document.execCommand('insertText', false, "Test");
+ });
+ await afterNextRender(() => {
+ const kevt = new window.KeyboardEvent('keydown', { ctrlKey: true, key: "Enter" });
+ document.querySelector('.o_ComposerTextInput_textarea').dispatchEvent(kevt);
+ });
+ assert.containsOnce(
+ document.body,
+ '.o_Message',
+ "should now have single message in channel after posting message from pressing 'CTRL-Enter' in text input of composer"
+ );
+});
+
+QUnit.test('post message on mailing channel with "META-Enter" keyboard shortcut', async function (assert) {
+ assert.expect(2);
+
+ // channel expected to be found in the sidebar
+ // with a random unique id that will be referenced in the test
+ this.data['mail.channel'].records.push({ id: 20, mass_mailing: true });
+ await this.start({
+ discuss: {
+ params: {
+ default_active_id: 'mail.channel_20',
+ },
+ },
+ });
+ assert.containsNone(
+ document.body,
+ '.o_Message',
+ "should not have any message initially in channel"
+ );
+
+ // insert some HTML in editable
+ await afterNextRender(() => {
+ document.querySelector(`.o_ComposerTextInput_textarea`).focus();
+ document.execCommand('insertText', false, "Test");
+ });
+ await afterNextRender(() => {
+ const kevt = new window.KeyboardEvent('keydown', { key: "Enter", metaKey: true });
+ document.querySelector('.o_ComposerTextInput_textarea').dispatchEvent(kevt);
+ });
+ assert.containsOnce(
+ document.body,
+ '.o_Message',
+ "should now have single message in channel after posting message from pressing 'META-Enter' in text input of composer"
+ );
+});
+
+QUnit.test('do not post message on mailing channel with "Enter" keyboard shortcut', async function (assert) {
+ // Note that test doesn't assert Enter makes a newline, because this
+ // default browser cannot be simulated with just dispatching
+ // programmatically crafted events...
+ assert.expect(2);
+
+ // channel expected to be found in the sidebar
+ // with a random unique id that will be referenced in the test
+ this.data['mail.channel'].records.push({ id: 20, mass_mailing: true });
+ await this.start({
+ discuss: {
+ params: {
+ default_active_id: 'mail.channel_20',
+ },
+ },
+ });
+ assert.containsNone(
+ document.body,
+ '.o_Message',
+ "should not have any message initially in mailing channel"
+ );
+
+ // insert some HTML in editable
+ await afterNextRender(() => {
+ document.querySelector(`.o_ComposerTextInput_textarea`).focus();
+ document.execCommand('insertText', false, "Test");
+ });
+ await afterNextRender(() => {
+ const kevt = new window.KeyboardEvent('keydown', { key: "Enter" });
+ document.querySelector('.o_ComposerTextInput_textarea').dispatchEvent(kevt);
+ });
+ assert.containsNone(
+ document.body,
+ '.o_Message',
+ "should still not have any message in mailing channel after pressing 'Enter' in text input of composer"
+ );
+});
+
QUnit.test('rendering of inbox message', async function (assert) {
// AKU TODO: kinda message specific test
assert.expect(7);
@@ -3205,11 +3387,12 @@ QUnit.test('reply to message from inbox (message linked to document)', async fun
"composer text input should be auto-focus"
);
- await afterNextRender(() => {
- document.execCommand('insertText', false, "Test");
- document.querySelector(`.o_ComposerTextInput_textarea`)
- .dispatchEvent(new window.KeyboardEvent('keydown', { key: 'Enter' }));
- });
+ await afterNextRender(() =>
+ document.execCommand('insertText', false, "Test")
+ );
+ await afterNextRender(() =>
+ document.querySelector('.o_Composer_buttonSend').click()
+ );
assert.verifySteps(['message_post']);
assert.notOk(
document.querySelector('.o_Composer'),
diff --git a/addons/mail/static/src/components/thread_view/thread_view.xml b/addons/mail/static/src/components/thread_view/thread_view.xml
index 12352f67fe5..e7dd82ccf43 100644
--- a/addons/mail/static/src/components/thread_view/thread_view.xml
+++ b/addons/mail/static/src/components/thread_view/thread_view.xml
@@ -30,11 +30,11 @@
composerLocalId="threadView.thread.composer.localId"
hasCurrentPartnerAvatar="props.hasComposerCurrentPartnerAvatar"
hasSendButton="props.hasComposerSendButton"
- hasTextInputSendOnEnterEnabled="(threadView.thread.model === 'mail.channel' and threadView.thread.mass_mailing) ? false : undefined"
hasThreadTyping="props.hasComposerThreadTyping"
isCompact="(threadView.thread.model === 'mail.channel' and threadView.thread.mass_mailing) ? false : undefined"
showAttachmentsExtensions="props.showComposerAttachmentsExtensions"
showAttachmentsFilenames="props.showComposerAttachmentsFilenames"
+ textInputSendShortcuts="(threadView.thread.model === 'mail.channel' and threadView.thread.mass_mailing) ? ['ctrl-enter', 'meta-enter'] : ['enter']"
t-ref="composer"
/>
</t>