From e7d3310feab7cafc5a193492202dd402b2b04610 Mon Sep 17 00:00:00 2001 From: Frank Date: Wed, 6 Jan 2021 01:25:07 +0000 Subject: [PATCH 1/8] Fix Issue #1039 : extending KeyboardShortcut to Support Special Keys --- src/components/Modal.js | 9 ++++++++- src/libs/KeyboardShortcut/index.js | 29 ++++++++++++++++------------- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/src/components/Modal.js b/src/components/Modal.js index d19e454a16a6..a9e33b57d8cf 100644 --- a/src/components/Modal.js +++ b/src/components/Modal.js @@ -1,4 +1,4 @@ -import React from 'react'; +import React, {useEffect} from 'react'; import PropTypes from 'prop-types'; import {View, useWindowDimensions} from 'react-native'; import ReactNativeModal from 'react-native-modal'; @@ -8,6 +8,7 @@ import styles, {getSafeAreaPadding} from '../styles/styles'; import themeColors from '../styles/themes/default'; import getModalStyles from '../styles/getModalStyles'; import CONST from '../CONST'; +import KeyboardShortcut from "../libs/KeyboardShortcut"; const propTypes = { // Callback method fired when the user requests to close the modal @@ -39,6 +40,12 @@ const Modal = (props) => { needsSafeAreaPadding } = getModalStyles(props.type, useWindowDimensions()); + //register escape key listener via effect + useEffect(()=>{ + KeyboardShortcut.subscribe('Escape', ()=> props.onClose(), 'special'); + return ()=> KeyboardShortcut.unsubscribe('Escape'); + },[props]); + return ( { + if (modifier === 'shift' && !event.shiftKey) { return false; } @@ -25,12 +26,11 @@ function bindHandlerToKeyupEvent(event) { if (modifier === 'alt' && !event.altKey) { return false; } - if (modifier === 'meta' && !event.metaKey) { - return false; - } - return true; + return !(modifier === 'meta' && !event.metaKey); + }); + if (!pressedModifiers) { return; } @@ -74,19 +74,22 @@ const KeyboardShortcut = { * @param {Boolean} captureOnInputs Should we capture the event on inputs too? */ subscribe(key, callback, modifiers = 'shift', captureOnInputs = false) { - const keyCode = key.charCodeAt(0); - if (events[keyCode] === undefined) { - events[keyCode] = []; + + //enable support for special keys like Escape + //const keyCode = key.charCodeAt(0); + + if (events[key] === undefined) { + events[key] = []; } - events[keyCode].push({callback, modifiers: _.isArray(modifiers) ? modifiers : [modifiers], captureOnInputs}); + events[key].push({callback, modifiers: _.isArray(modifiers) ? modifiers : [modifiers], captureOnInputs}); }, /** * Unsubscribes to a keyboard event. - * @param {Number} keyCode The key code to stop watching + * @param {String} key The key to stop watching */ - unsubscribe(keyCode) { - delete events[keyCode]; + unsubscribe(key) { + delete events[key]; } }; From 6f0190945dd0ce6bd7a40bc49bcc60e54a7385e3 Mon Sep 17 00:00:00 2001 From: Frank Date: Wed, 6 Jan 2021 01:25:07 +0000 Subject: [PATCH 2/8] Fix Issue #1039 : extending KeyboardShortcut to Support Special Keys --- src/components/Modal.js | 9 ++++++++- src/libs/KeyboardShortcut/index.js | 28 +++++++++++++++------------- 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/src/components/Modal.js b/src/components/Modal.js index d19e454a16a6..a9e33b57d8cf 100644 --- a/src/components/Modal.js +++ b/src/components/Modal.js @@ -1,4 +1,4 @@ -import React from 'react'; +import React, {useEffect} from 'react'; import PropTypes from 'prop-types'; import {View, useWindowDimensions} from 'react-native'; import ReactNativeModal from 'react-native-modal'; @@ -8,6 +8,7 @@ import styles, {getSafeAreaPadding} from '../styles/styles'; import themeColors from '../styles/themes/default'; import getModalStyles from '../styles/getModalStyles'; import CONST from '../CONST'; +import KeyboardShortcut from "../libs/KeyboardShortcut"; const propTypes = { // Callback method fired when the user requests to close the modal @@ -39,6 +40,12 @@ const Modal = (props) => { needsSafeAreaPadding } = getModalStyles(props.type, useWindowDimensions()); + //register escape key listener via effect + useEffect(()=>{ + KeyboardShortcut.subscribe('Escape', ()=> props.onClose(), 'special'); + return ()=> KeyboardShortcut.unsubscribe('Escape'); + },[props]); + return ( { + if (modifier === 'shift' && !event.shiftKey) { return false; } @@ -25,12 +26,10 @@ function bindHandlerToKeyupEvent(event) { if (modifier === 'alt' && !event.altKey) { return false; } - if (modifier === 'meta' && !event.metaKey) { - return false; - } - return true; + return !(modifier === 'meta' && !event.metaKey); }); + if (!pressedModifiers) { return; } @@ -74,19 +73,22 @@ const KeyboardShortcut = { * @param {Boolean} captureOnInputs Should we capture the event on inputs too? */ subscribe(key, callback, modifiers = 'shift', captureOnInputs = false) { - const keyCode = key.charCodeAt(0); - if (events[keyCode] === undefined) { - events[keyCode] = []; + + //enable support for special keys like Escape + //const keyCode = key.charCodeAt(0); + + if (events[key] === undefined) { + events[key] = []; } - events[keyCode].push({callback, modifiers: _.isArray(modifiers) ? modifiers : [modifiers], captureOnInputs}); + events[key].push({callback, modifiers: _.isArray(modifiers) ? modifiers : [modifiers], captureOnInputs}); }, /** * Unsubscribes to a keyboard event. - * @param {Number} keyCode The key code to stop watching + * @param {String} key The key to stop watching */ - unsubscribe(keyCode) { - delete events[keyCode]; + unsubscribe(key) { + delete events[key]; } }; From b325b1d51f7eeea317aeaa7551511725b8efd23e Mon Sep 17 00:00:00 2001 From: Frank Date: Wed, 6 Jan 2021 22:47:49 +0000 Subject: [PATCH 3/8] patch: linting --- src/libs/KeyboardShortcut/index.js | 118 +++++++++++++++-------------- 1 file changed, 60 insertions(+), 58 deletions(-) diff --git a/src/libs/KeyboardShortcut/index.js b/src/libs/KeyboardShortcut/index.js index 70a06938bea2..622d800eaf14 100644 --- a/src/libs/KeyboardShortcut/index.js +++ b/src/libs/KeyboardShortcut/index.js @@ -7,46 +7,45 @@ const events = {}; * @param {Event} event */ function bindHandlerToKeyupEvent(event) { - if (events[event.key] === undefined) { - return; - } - - // The active callback is the last element in the array - const eventCallbacks = events[event.key]; - const callback = eventCallbacks[eventCallbacks.length - 1]; + if (events[event.key] === undefined) { + return; + } - const pressedModifiers = _.all(callback.modifiers, (modifier) => { - - if (modifier === 'shift' && !event.shiftKey) { - return false; - } - if (modifier === 'control' && !event.ctrlKey) { - return false; - } - if (modifier === 'alt' && !event.altKey) { - return false; - } - return !(modifier === 'meta' && !event.metaKey); - }); + // The active callback is the last element in the array + const eventCallbacks = events[event.key]; + const callback = eventCallbacks[eventCallbacks.length - 1]; - - if (!pressedModifiers) { - return; + const pressedModifiers = _.all(callback.modifiers, (modifier) => { + if (modifier === 'shift' && !event.shiftKey) { + return false; } - - // If configured to do so, prevent input text control to trigger this event - if (!callback.captureOnInputs && ( - event.target.nodeName === 'INPUT' - || event.target.nodeName === 'TEXTAREA' - || event.target.contentEditable === 'true' - )) { - return; + if (modifier === 'control' && !event.ctrlKey) { + return false; } - - if (_.isFunction(callback.callback)) { - callback.callback(event); + if (modifier === 'alt' && !event.altKey) { + return false; } - event.preventDefault(); + return !(modifier === 'meta' && !event.metaKey); + }); + + if (!pressedModifiers) { + return; + } + + // If configured to do so, prevent input text control to trigger this event + if ( + !callback.captureOnInputs && + (event.target.nodeName === 'INPUT' || + event.target.nodeName === 'TEXTAREA' || + event.target.contentEditable === 'true') + ) { + return; + } + + if (_.isFunction(callback.callback)) { + callback.callback(event); + } + event.preventDefault(); } // Make sure we don't add multiple listeners @@ -65,31 +64,34 @@ document.addEventListener('keydown', bindHandlerToKeyupEvent); * The "subClass" is used by pages to bind /unbind with no worries */ const KeyboardShortcut = { - /** - * Subscribes to a keyboard event. - * @param {String} key The key code to watch - * @param {Function} callback The callback to call - * @param {String|Array} modifiers Can either be shift or control - * @param {Boolean} captureOnInputs Should we capture the event on inputs too? - */ - subscribe(key, callback, modifiers = 'shift', captureOnInputs = false) { - - //enable support for special keys like Escape - //const keyCode = key.charCodeAt(0); + /** + * Subscribes to a keyboard event. + * @param {String} key The key code to watch + * @param {Function} callback The callback to call + * @param {String|Array} modifiers Can either be shift or control + * @param {Boolean} captureOnInputs Should we capture the event on inputs too? + */ + subscribe(key, callback, modifiers = 'shift', captureOnInputs = false) { + //enable support for special keys like Escape + //const keyCode = key.charCodeAt(0); - if (events[key] === undefined) { - events[key] = []; - } - events[key].push({callback, modifiers: _.isArray(modifiers) ? modifiers : [modifiers], captureOnInputs}); - }, - - /** - * Unsubscribes to a keyboard event. - * @param {String} key The key to stop watching - */ - unsubscribe(key) { - delete events[key]; + if (events[key] === undefined) { + events[key] = []; } + events[key].push({ + callback, + modifiers: _.isArray(modifiers) ? modifiers : [modifiers], + captureOnInputs, + }); + }, + + /** + * Unsubscribes to a keyboard event. + * @param {String} key The key to stop watching + */ + unsubscribe(key) { + delete events[key]; + }, }; export default KeyboardShortcut; From 345f81688c6c9381fa3c8372b2ab2d9f7fe99541 Mon Sep 17 00:00:00 2001 From: Frank Date: Wed, 6 Jan 2021 22:47:49 +0000 Subject: [PATCH 4/8] patch: linting --- src/libs/KeyboardShortcut/index.js | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/libs/KeyboardShortcut/index.js b/src/libs/KeyboardShortcut/index.js index 70a06938bea2..6d2d0ad1f52f 100644 --- a/src/libs/KeyboardShortcut/index.js +++ b/src/libs/KeyboardShortcut/index.js @@ -16,7 +16,6 @@ function bindHandlerToKeyupEvent(event) { const callback = eventCallbacks[eventCallbacks.length - 1]; const pressedModifiers = _.all(callback.modifiers, (modifier) => { - if (modifier === 'shift' && !event.shiftKey) { return false; } @@ -29,17 +28,17 @@ function bindHandlerToKeyupEvent(event) { return !(modifier === 'meta' && !event.metaKey); }); - if (!pressedModifiers) { return; } // If configured to do so, prevent input text control to trigger this event - if (!callback.captureOnInputs && ( - event.target.nodeName === 'INPUT' - || event.target.nodeName === 'TEXTAREA' - || event.target.contentEditable === 'true' - )) { + if ( + !callback.captureOnInputs && + (event.target.nodeName === 'INPUT' || + event.target.nodeName === 'TEXTAREA' || + event.target.contentEditable === 'true') + ) { return; } @@ -73,14 +72,17 @@ const KeyboardShortcut = { * @param {Boolean} captureOnInputs Should we capture the event on inputs too? */ subscribe(key, callback, modifiers = 'shift', captureOnInputs = false) { - //enable support for special keys like Escape //const keyCode = key.charCodeAt(0); if (events[key] === undefined) { events[key] = []; } - events[key].push({callback, modifiers: _.isArray(modifiers) ? modifiers : [modifiers], captureOnInputs}); + events[key].push({ + callback, + modifiers: _.isArray(modifiers) ? modifiers : [modifiers], + captureOnInputs, + }); }, /** @@ -89,7 +91,7 @@ const KeyboardShortcut = { */ unsubscribe(key) { delete events[key]; - } + }, }; export default KeyboardShortcut; From 5b964bbad39773db9e4bd9d490f0a7e9689f58cd Mon Sep 17 00:00:00 2001 From: Frank Date: Wed, 6 Jan 2021 23:02:29 +0000 Subject: [PATCH 5/8] Fix Issue #1039 : linting updates --- src/libs/KeyboardShortcut/index.js | 88 +++++++----------------------- 1 file changed, 20 insertions(+), 68 deletions(-) diff --git a/src/libs/KeyboardShortcut/index.js b/src/libs/KeyboardShortcut/index.js index 8be0e4c1c9d3..70a06938bea2 100644 --- a/src/libs/KeyboardShortcut/index.js +++ b/src/libs/KeyboardShortcut/index.js @@ -7,11 +7,16 @@ const events = {}; * @param {Event} event */ function bindHandlerToKeyupEvent(event) { - if (events[event.key] === undefined) { - return; - } + if (events[event.key] === undefined) { + return; + } + + // The active callback is the last element in the array + const eventCallbacks = events[event.key]; + const callback = eventCallbacks[eventCallbacks.length - 1]; const pressedModifiers = _.all(callback.modifiers, (modifier) => { + if (modifier === 'shift' && !event.shiftKey) { return false; } @@ -24,43 +29,24 @@ function bindHandlerToKeyupEvent(event) { return !(modifier === 'meta' && !event.metaKey); }); + if (!pressedModifiers) { return; } // If configured to do so, prevent input text control to trigger this event - if ( - !callback.captureOnInputs && - (event.target.nodeName === 'INPUT' || - event.target.nodeName === 'TEXTAREA' || - event.target.contentEditable === 'true') - ) { + if (!callback.captureOnInputs && ( + event.target.nodeName === 'INPUT' + || event.target.nodeName === 'TEXTAREA' + || event.target.contentEditable === 'true' + )) { return; } - if (modifier === 'alt' && !event.altKey) { - return false; - } - return !(modifier === 'meta' && !event.metaKey); - }); - - if (!pressedModifiers) { - return; - } - // If configured to do so, prevent input text control to trigger this event - if ( - !callback.captureOnInputs && - (event.target.nodeName === 'INPUT' || - event.target.nodeName === 'TEXTAREA' || - event.target.contentEditable === 'true') - ) { - return; - } - - if (_.isFunction(callback.callback)) { - callback.callback(event); - } - event.preventDefault(); + if (_.isFunction(callback.callback)) { + callback.callback(event); + } + event.preventDefault(); } // Make sure we don't add multiple listeners @@ -79,7 +65,6 @@ document.addEventListener('keydown', bindHandlerToKeyupEvent); * The "subClass" is used by pages to bind /unbind with no worries */ const KeyboardShortcut = { -<<<<<<< HEAD /** * Subscribes to a keyboard event. * @param {String} key The key code to watch @@ -88,17 +73,14 @@ const KeyboardShortcut = { * @param {Boolean} captureOnInputs Should we capture the event on inputs too? */ subscribe(key, callback, modifiers = 'shift', captureOnInputs = false) { + //enable support for special keys like Escape //const keyCode = key.charCodeAt(0); if (events[key] === undefined) { events[key] = []; } - events[key].push({ - callback, - modifiers: _.isArray(modifiers) ? modifiers : [modifiers], - captureOnInputs, - }); + events[key].push({callback, modifiers: _.isArray(modifiers) ? modifiers : [modifiers], captureOnInputs}); }, /** @@ -107,37 +89,7 @@ const KeyboardShortcut = { */ unsubscribe(key) { delete events[key]; - }, -======= - /** - * Subscribes to a keyboard event. - * @param {String} key The key code to watch - * @param {Function} callback The callback to call - * @param {String|Array} modifiers Can either be shift or control - * @param {Boolean} captureOnInputs Should we capture the event on inputs too? - */ - subscribe(key, callback, modifiers = 'shift', captureOnInputs = false) { - //enable support for special keys like Escape - //const keyCode = key.charCodeAt(0); - - if (events[key] === undefined) { - events[key] = []; } - events[key].push({ - callback, - modifiers: _.isArray(modifiers) ? modifiers : [modifiers], - captureOnInputs, - }); - }, - - /** - * Unsubscribes to a keyboard event. - * @param {String} key The key to stop watching - */ - unsubscribe(key) { - delete events[key]; - }, ->>>>>>> b325b1d51f7eeea317aeaa7551511725b8efd23e }; export default KeyboardShortcut; From 16e72e855dc7ccefb53c18c96a5dae27efe63307 Mon Sep 17 00:00:00 2001 From: Frank Date: Tue, 12 Jan 2021 13:13:55 +0000 Subject: [PATCH 6/8] patch: updated comments --- src/components/Modal.js | 2 +- src/libs/KeyboardShortcut/index.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/Modal.js b/src/components/Modal.js index e1915d80a251..493d90b1674a 100644 --- a/src/components/Modal.js +++ b/src/components/Modal.js @@ -40,7 +40,7 @@ const Modal = (props) => { needsSafeAreaPadding, } = getModalStyles(props.type, useWindowDimensions()); - //register escape key listener via effect + // Register escape key listener via effect useEffect(()=>{ KeyboardShortcut.subscribe('Escape', ()=> props.onClose(), 'special'); return ()=> KeyboardShortcut.unsubscribe('Escape'); diff --git a/src/libs/KeyboardShortcut/index.js b/src/libs/KeyboardShortcut/index.js index 70a06938bea2..08c856efda42 100644 --- a/src/libs/KeyboardShortcut/index.js +++ b/src/libs/KeyboardShortcut/index.js @@ -74,8 +74,8 @@ const KeyboardShortcut = { */ subscribe(key, callback, modifiers = 'shift', captureOnInputs = false) { - //enable support for special keys like Escape - //const keyCode = key.charCodeAt(0); + // Enable support for special keys like Escape + if (events[key] === undefined) { events[key] = []; From 224be10a765196896b31c4b7f9d77aa8eedfd107 Mon Sep 17 00:00:00 2001 From: Frank Date: Tue, 12 Jan 2021 13:13:55 +0000 Subject: [PATCH 7/8] patch: updated comments --- src/components/Modal.js | 2 +- src/libs/KeyboardShortcut/index.js | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/components/Modal.js b/src/components/Modal.js index e1915d80a251..493d90b1674a 100644 --- a/src/components/Modal.js +++ b/src/components/Modal.js @@ -40,7 +40,7 @@ const Modal = (props) => { needsSafeAreaPadding, } = getModalStyles(props.type, useWindowDimensions()); - //register escape key listener via effect + // Register escape key listener via effect useEffect(()=>{ KeyboardShortcut.subscribe('Escape', ()=> props.onClose(), 'special'); return ()=> KeyboardShortcut.unsubscribe('Escape'); diff --git a/src/libs/KeyboardShortcut/index.js b/src/libs/KeyboardShortcut/index.js index 70a06938bea2..262af75acb8c 100644 --- a/src/libs/KeyboardShortcut/index.js +++ b/src/libs/KeyboardShortcut/index.js @@ -16,7 +16,6 @@ function bindHandlerToKeyupEvent(event) { const callback = eventCallbacks[eventCallbacks.length - 1]; const pressedModifiers = _.all(callback.modifiers, (modifier) => { - if (modifier === 'shift' && !event.shiftKey) { return false; } @@ -74,8 +73,8 @@ const KeyboardShortcut = { */ subscribe(key, callback, modifiers = 'shift', captureOnInputs = false) { - //enable support for special keys like Escape - //const keyCode = key.charCodeAt(0); + // Enable support for special keys like Escape + if (events[key] === undefined) { events[key] = []; From 76e073c0e8d603f7bf070cf9ee0b4eafdeadbe71 Mon Sep 17 00:00:00 2001 From: Frank Date: Thu, 14 Jan 2021 11:25:51 +0000 Subject: [PATCH 8/8] patch: remove unused space --- src/libs/KeyboardShortcut/index.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/libs/KeyboardShortcut/index.js b/src/libs/KeyboardShortcut/index.js index 88ad38939fac..17292ea110b3 100644 --- a/src/libs/KeyboardShortcut/index.js +++ b/src/libs/KeyboardShortcut/index.js @@ -28,7 +28,6 @@ function bindHandlerToKeyupEvent(event) { return !(modifier === 'meta' && !event.metaKey); }); - if (!pressedModifiers) { return; } @@ -73,7 +72,6 @@ const KeyboardShortcut = { */ subscribe(key, callback, modifiers = 'shift', captureOnInputs = false) { // Enable support for special keys like Escape - if (events[key] === undefined) { events[key] = []; }