fix: Reject keyboard shortcut listeners if input box is active (#3019)

Reject keyboard shortcut listeners if input box is active
This commit is contained in:
Pranav Raj S 2021-09-15 20:15:06 +05:30 committed by GitHub
parent a14f4ede87
commit 3abcadb5cb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 84 additions and 37 deletions

View file

@ -194,7 +194,7 @@ export default {
}); });
}, },
methods: { methods: {
handleKeyEvents(e) { getKeyboardListenerParams() {
const allConversations = this.$refs.activeConversation.querySelectorAll( const allConversations = this.$refs.activeConversation.querySelectorAll(
'div.conversations-list div.conversation' 'div.conversations-list div.conversation'
); );
@ -205,7 +205,19 @@ export default {
activeConversation activeConversation
); );
const lastConversationIndex = allConversations.length - 1; const lastConversationIndex = allConversations.length - 1;
return {
allConversations,
activeConversation,
activeConversationIndex,
lastConversationIndex,
};
},
handleKeyEvents(e) {
if (hasPressedAltAndJKey(e)) { if (hasPressedAltAndJKey(e)) {
const {
allConversations,
activeConversationIndex,
} = this.getKeyboardListenerParams();
if (activeConversationIndex === -1) { if (activeConversationIndex === -1) {
allConversations[0].click(); allConversations[0].click();
} }
@ -214,6 +226,11 @@ export default {
} }
} }
if (hasPressedAltAndKKey(e)) { if (hasPressedAltAndKKey(e)) {
const {
allConversations,
activeConversationIndex,
lastConversationIndex,
} = this.getKeyboardListenerParams();
if (activeConversationIndex === -1) { if (activeConversationIndex === -1) {
allConversations[lastConversationIndex].click(); allConversations[lastConversationIndex].click();
} else if (activeConversationIndex < lastConversationIndex) { } else if (activeConversationIndex < lastConversationIndex) {

View file

@ -176,8 +176,10 @@ export default {
'.conversations-list .conversation' '.conversations-list .conversation'
); );
if (hasPressedAltAndMKey(e)) { if (hasPressedAltAndMKey(e)) {
if (this.$refs.arrowDownButton) {
this.$refs.arrowDownButton.$el.click(); this.$refs.arrowDownButton.$el.click();
} }
}
if (hasPressedAltAndEKey(e)) { if (hasPressedAltAndEKey(e)) {
const activeConversation = document.querySelector( const activeConversation = document.querySelector(
'div.conversations-list div.conversation.active' 'div.conversations-list div.conversation.active'

View file

@ -95,10 +95,15 @@ import AddAccountModal from './sidebarComponents/AddAccountModal.vue';
import AddLabelModal from '../../routes/dashboard/settings/labels/AddLabel'; import AddLabelModal from '../../routes/dashboard/settings/labels/AddLabel';
import WootKeyShortcutModal from 'components/widgets/modal/WootKeyShortcutModal'; import WootKeyShortcutModal from 'components/widgets/modal/WootKeyShortcutModal';
import { import {
hasPressedAltAndCKey,
hasPressedAltAndRKey,
hasPressedAltAndSKey,
hasPressedAltAndVKey,
hasPressedCommandAndForwardSlash, hasPressedCommandAndForwardSlash,
isEscape, isEscape,
} from 'shared/helpers/KeyboardHelpers'; } from 'shared/helpers/KeyboardHelpers';
import eventListenerMixins from 'shared/mixins/eventListenerMixins'; import eventListenerMixins from 'shared/mixins/eventListenerMixins';
import router from '../../routes';
export default { export default {
components: { components: {
@ -276,6 +281,27 @@ export default {
if (isEscape(e)) { if (isEscape(e)) {
this.closeKeyShortcutModal(); this.closeKeyShortcutModal();
} }
if (hasPressedAltAndCKey(e)) {
if (!this.isCurrentRouteSameAsNavigation('home')) {
router.push({ name: 'home' });
}
} else if (hasPressedAltAndVKey(e)) {
if (!this.isCurrentRouteSameAsNavigation('contacts_dashboard')) {
router.push({ name: 'contacts_dashboard' });
}
} else if (hasPressedAltAndRKey(e)) {
if (!this.isCurrentRouteSameAsNavigation('settings_account_reports')) {
router.push({ name: 'settings_account_reports' });
}
} else if (hasPressedAltAndSKey(e)) {
if (!this.isCurrentRouteSameAsNavigation('agent_list')) {
router.push({ name: 'agent_list' });
}
}
},
isCurrentRouteSameAsNavigation(routeName) {
return router.currentRoute && router.currentRoute.name === routeName;
}, },
toggleSupportChatWindow() { toggleSupportChatWindow() {
window.$chatwoot.toggle(); window.$chatwoot.toggle();

View file

@ -59,17 +59,10 @@
import { mapGetters } from 'vuex'; import { mapGetters } from 'vuex';
import router from '../../routes'; import router from '../../routes';
import {
hasPressedAltAndCKey,
hasPressedAltAndVKey,
hasPressedAltAndRKey,
hasPressedAltAndSKey,
} from 'shared/helpers/KeyboardHelpers';
import adminMixin from '../../mixins/isAdmin'; import adminMixin from '../../mixins/isAdmin';
import eventListenerMixins from 'shared/mixins/eventListenerMixins';
import { getInboxClassByType } from 'dashboard/helper/inbox'; import { getInboxClassByType } from 'dashboard/helper/inbox';
export default { export default {
mixins: [adminMixin, eventListenerMixins], mixins: [adminMixin],
props: { props: {
menuItem: { menuItem: {
type: Object, type: Object,
@ -124,20 +117,6 @@ export default {
} }
} }
}, },
handleKeyEvents(e) {
if (hasPressedAltAndCKey(e)) {
router.push({ name: 'home' });
}
if (hasPressedAltAndVKey(e)) {
router.push({ name: 'contacts_dashboard' });
}
if (hasPressedAltAndRKey(e)) {
router.push({ name: 'settings_account_reports' });
}
if (hasPressedAltAndSKey(e)) {
router.push({ name: 'settings_home' });
}
},
showItem(item) { showItem(item) {
return this.isAdmin && item.newLink !== undefined; return this.isAdmin && item.newLink !== undefined;
}, },

View file

@ -76,7 +76,6 @@
import { mapGetters } from 'vuex'; import { mapGetters } from 'vuex';
import { mixin as clickaway } from 'vue-clickaway'; import { mixin as clickaway } from 'vue-clickaway';
import alertMixin from 'shared/mixins/alertMixin'; import alertMixin from 'shared/mixins/alertMixin';
import eventListenerMixins from 'shared/mixins/eventListenerMixins';
import EmojiInput from 'shared/components/emoji/EmojiInput'; import EmojiInput from 'shared/components/emoji/EmojiInput';
import CannedResponse from './CannedResponse'; import CannedResponse from './CannedResponse';
@ -108,13 +107,7 @@ export default {
ReplyBottomPanel, ReplyBottomPanel,
WootMessageEditor, WootMessageEditor,
}, },
mixins: [ mixins: [clickaway, inboxMixin, uiSettingsMixin, alertMixin],
clickaway,
inboxMixin,
uiSettingsMixin,
alertMixin,
eventListenerMixins,
],
props: { props: {
selectedTweet: { selectedTweet: {
type: [Object, String], type: [Object, String],
@ -304,6 +297,15 @@ export default {
} }
}, },
}, },
mounted() {
// Donot use the keyboard listener mixin here as the events here are supposed to be
// working even if input/textarea is focussed.
document.addEventListener('keydown', this.handleKeyEvents);
},
destroyed() {
document.removeEventListener('keydown', this.handleKeyEvents);
},
methods: { methods: {
toggleUserMention(currentMentionState) { toggleUserMention(currentMentionState) {
this.hasUserMention = currentMentionState; this.hasUserMention = currentMentionState;

View file

@ -99,6 +99,7 @@ export const SDK_CSS = `.woot-widget-holder {
.woot--close::before, .woot--close::after { .woot--close::before, .woot--close::after {
background-color: #fff; background-color: #fff;
content: ' '; content: ' ';
display: inline;
height: 24px; height: 24px;
left: 32px; left: 32px;
position: absolute; position: absolute;

View file

@ -1,8 +1,28 @@
import { isEscape } from '../helpers/KeyboardHelpers';
export default { export default {
mounted() { mounted() {
document.addEventListener('keydown', this.handleKeyEvents); document.addEventListener('keydown', this.onKeyDownHandler);
},
beforeDestroy() {
document.removeEventListener('keydown', this.onKeyDownHandler);
},
methods: {
onKeyDownHandler(e) {
const isEventFromAnInputBox =
e.target?.tagName === 'INPUT' || e.target?.tagName === 'TEXTAREA';
const isEventFromProseMirror = e.target?.className?.includes(
'ProseMirror'
);
if (isEventFromAnInputBox || isEventFromProseMirror) {
if (isEscape(e)) {
e.target.blur();
}
return;
}
this.handleKeyEvents(e);
}, },
destroyed() {
document.removeEventListener('keydown', this.handleKeyEvents);
}, },
}; };