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

View file

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

View file

@ -95,10 +95,15 @@ import AddAccountModal from './sidebarComponents/AddAccountModal.vue';
import AddLabelModal from '../../routes/dashboard/settings/labels/AddLabel';
import WootKeyShortcutModal from 'components/widgets/modal/WootKeyShortcutModal';
import {
hasPressedAltAndCKey,
hasPressedAltAndRKey,
hasPressedAltAndSKey,
hasPressedAltAndVKey,
hasPressedCommandAndForwardSlash,
isEscape,
} from 'shared/helpers/KeyboardHelpers';
import eventListenerMixins from 'shared/mixins/eventListenerMixins';
import router from '../../routes';
export default {
components: {
@ -276,6 +281,27 @@ export default {
if (isEscape(e)) {
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() {
window.$chatwoot.toggle();

View file

@ -59,17 +59,10 @@
import { mapGetters } from 'vuex';
import router from '../../routes';
import {
hasPressedAltAndCKey,
hasPressedAltAndVKey,
hasPressedAltAndRKey,
hasPressedAltAndSKey,
} from 'shared/helpers/KeyboardHelpers';
import adminMixin from '../../mixins/isAdmin';
import eventListenerMixins from 'shared/mixins/eventListenerMixins';
import { getInboxClassByType } from 'dashboard/helper/inbox';
export default {
mixins: [adminMixin, eventListenerMixins],
mixins: [adminMixin],
props: {
menuItem: {
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) {
return this.isAdmin && item.newLink !== undefined;
},

View file

@ -76,7 +76,6 @@
import { mapGetters } from 'vuex';
import { mixin as clickaway } from 'vue-clickaway';
import alertMixin from 'shared/mixins/alertMixin';
import eventListenerMixins from 'shared/mixins/eventListenerMixins';
import EmojiInput from 'shared/components/emoji/EmojiInput';
import CannedResponse from './CannedResponse';
@ -108,13 +107,7 @@ export default {
ReplyBottomPanel,
WootMessageEditor,
},
mixins: [
clickaway,
inboxMixin,
uiSettingsMixin,
alertMixin,
eventListenerMixins,
],
mixins: [clickaway, inboxMixin, uiSettingsMixin, alertMixin],
props: {
selectedTweet: {
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: {
toggleUserMention(currentMentionState) {
this.hasUserMention = currentMentionState;

View file

@ -99,6 +99,7 @@ export const SDK_CSS = `.woot-widget-holder {
.woot--close::before, .woot--close::after {
background-color: #fff;
content: ' ';
display: inline;
height: 24px;
left: 32px;
position: absolute;
@ -149,7 +150,7 @@ export const SDK_CSS = `.woot-widget-holder {
max-height: 100vh;
padding: 0 8px;
}
.woot-widget-holder.has-unread-view iframe {
min-height: unset !important;
}
@ -157,7 +158,7 @@ export const SDK_CSS = `.woot-widget-holder {
.woot-widget-holder.has-unread-view.woot-elements--left {
left: 0;
}
.woot-widget-bubble.woot--close {
bottom: 60px;
opacity: 0;

View file

@ -1,8 +1,28 @@
import { isEscape } from '../helpers/KeyboardHelpers';
export default {
mounted() {
document.addEventListener('keydown', this.handleKeyEvents);
document.addEventListener('keydown', this.onKeyDownHandler);
},
destroyed() {
document.removeEventListener('keydown', this.handleKeyEvents);
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);
},
},
};