[FIX] mail: fix keyboard shortcut issue for small screen

Current behavior before PR:
When having a small screen, the composer in a chat window has no actual
shortcut to send the message.

Desired behavior after PR is merged:
'CTRL-Enter' keyboard shortcut will work for small screen size.

LINKS:
PR https://github.com//pull/65241
Task-2446076

closes odoo/odoo#67724

X-original-commit: 2542f731c5b06c3b451ecde7992d3bb45adb2c60
Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
This commit is contained in:
Priyanka Kakadiya
2021-03-11 18:14:20 +00:00
parent ab7b5af3e8
commit a004143a0c
5 changed files with 115 additions and 4 deletions
@@ -1892,6 +1892,42 @@ QUnit.test('chat window should scroll to the newly posted message just after pos
);
});
QUnit.test('chat window: post message on non-mailing channel with "CTRL-Enter" keyboard shortcut for small screen size', async function (assert) {
assert.expect(1);
this.data['mail.channel'].records.push({
id: 20,
is_minimized: true,
mass_mailing: false,
});
await this.start({
env: {
device: {
isMobile: true, // here isMobile is used for the small screen size, not actually for the mobile devices
},
},
});
await afterNextRender(() => document.querySelector(`.o_MessagingMenu_toggler`).click());
await afterNextRender(() =>
document.querySelector(`.o_MessagingMenu_dropdownMenu .o_NotificationList_preview`).click()
);
// 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 for small screen"
);
});
QUnit.test('[technical] chat window: composer state conservation on toggle home menu when folded', async function (assert) {
// technical as show/hide home menu simulation are involved and home menu implementation
// have side-effects on DOM that may make chat window components not work
@@ -289,8 +289,7 @@ class ComposerTextInput extends Component {
!ev.altKey &&
!ev.ctrlKey &&
!ev.metaKey &&
!ev.shiftKey &&
!this.env.messaging.device.isMobile
!ev.shiftKey
) {
this.trigger('o-composer-text-input-send-shortcut');
ev.preventDefault();
@@ -20,7 +20,11 @@ class ThreadView extends Component {
constructor(...args) {
super(...args);
useShouldUpdateBasedOnProps();
useStore((...args) => this._useStoreSelector(...args));
useStore((...args) => this._useStoreSelector(...args), {
compareDepth: {
threadTextInputSendShortcuts: 1,
},
});
useUpdate({ func: () => this._update() });
/**
* Reference of the composer. Useful to set focus on composer when
@@ -134,6 +138,7 @@ class ThreadView extends Component {
threadIsTemporary: thread && thread.isTemporary,
threadMassMailing: thread && thread.mass_mailing,
threadModel: thread && thread.model,
threadTextInputSendShortcuts: thread && thread.textInputSendShortcuts || [],
threadView,
threadViewIsLoading: threadView && threadView.isLoading,
};
@@ -47,7 +47,7 @@
isDoFocus="props.isDoFocus"
showAttachmentsExtensions="props.showComposerAttachmentsExtensions"
showAttachmentsFilenames="props.showComposerAttachmentsFilenames"
textInputSendShortcuts="(threadView.thread.model === 'mail.channel' and threadView.thread.mass_mailing) ? ['ctrl-enter', 'meta-enter'] : ['enter']"
textInputSendShortcuts="threadView.textInputSendShortcuts"
t-ref="composer"
/>
</t>
@@ -67,6 +67,33 @@ function factory(dependencies) {
// Private
//----------------------------------------------------------------------
/**
* @private
* @returns {mail.messaging}
*/
_computeMessaging() {
return [['link', this.env.messaging]];
}
/**
* @private
* @returns {string[]}
*/
_computeTextInputSendShortcuts() {
if (!this.thread) {
return;
}
const isMailingList = this.thread.model === 'mail.channel' && this.thread.mass_mailing;
// Actually in mobile there is a send button, so we need there 'enter' to allow new line.
// Hence, we want to use a different shortcut 'ctrl/meta enter' to send for small screen
// size with a non-mailing channel.
// here send will be done on clicking the button or using the 'ctrl/meta enter' shortcut.
if (this.env.messaging.device.isMobile || isMailingList) {
return ['ctrl-enter', 'meta-enter'];
}
return ['enter'];
}
/**
* @private
* @returns {integer|undefined}
@@ -199,6 +226,18 @@ function factory(dependencies) {
composer: many2one('mail.composer', {
related: 'thread.composer',
}),
/**
* Serves as compute dependency.
*/
device: one2one('mail.device', {
related: 'messaging.device',
}),
/**
* Serves as compute dependency.
*/
deviceIsMobile: attr({
related: 'device.isMobile',
}),
hasComposerFocus: attr({
related: 'composer.hasFocus',
}),
@@ -255,6 +294,12 @@ function factory(dependencies) {
messages: many2many('mail.message', {
related: 'threadCache.messages',
}),
/**
* Serves as compute dependency.
*/
messaging: many2one('mail.messaging', {
compute: '_computeMessaging',
}),
nonEmptyMessages: many2many('mail.message', {
related: 'threadCache.nonEmptyMessages',
}),
@@ -287,6 +332,20 @@ function factory(dependencies) {
stringifiedDomain: attr({
related: 'threadViewer.stringifiedDomain',
}),
/**
* Determines the keyboard shortcuts that are available to send a message
* from the composer of this thread viewer.
*/
textInputSendShortcuts: attr({
compute: '_computeTextInputSendShortcuts',
dependencies: [
'device',
'deviceIsMobile',
'thread',
'threadMassMailing',
'threadModel',
],
}),
/**
* Determines the `mail.thread` currently displayed by `this`.
*/
@@ -337,6 +396,18 @@ function factory(dependencies) {
default: {},
related: 'threadViewer.threadCacheInitialScrollPositions',
}),
/**
* Serves as compute dependency.
*/
threadMassMailing: attr({
related: 'thread.mass_mailing',
}),
/**
* Serves as compute dependency.
*/
threadModel: attr({
related: 'thread.model',
}),
/**
* Not a real field, used to trigger `thread.markAsSeen` when one of
* the dependencies changes.