feat: escape prevents automatic editor focus
This commit is contained in:
committed by
mrugesh
parent
a7c42446be
commit
95fdb74d95
@ -1,10 +1,14 @@
|
||||
import React, { Component, Suspense } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { bindActionCreators } from 'redux';
|
||||
import { connect } from 'react-redux';
|
||||
import { createSelector } from 'reselect';
|
||||
|
||||
import { executeChallenge, updateFile } from '../redux';
|
||||
import {
|
||||
canFocusEditorSelector,
|
||||
executeChallenge,
|
||||
setEditorFocusability,
|
||||
updateFile
|
||||
} from '../redux';
|
||||
import { userSelector, isDonationModalOpenSelector } from '../../../redux';
|
||||
import { Loader } from '../../../components/helpers';
|
||||
|
||||
@ -18,27 +22,26 @@ const propTypes = {
|
||||
executeChallenge: PropTypes.func.isRequired,
|
||||
ext: PropTypes.string,
|
||||
fileKey: PropTypes.string,
|
||||
setEditorFocusability: PropTypes.func,
|
||||
theme: PropTypes.string,
|
||||
updateFile: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
const mapStateToProps = createSelector(
|
||||
canFocusEditorSelector,
|
||||
isDonationModalOpenSelector,
|
||||
userSelector,
|
||||
(open, { theme = 'night' }) => ({
|
||||
canFocus: !open,
|
||||
(canFocus, open, { theme = 'night' }) => ({
|
||||
canFocus: open ? false : canFocus,
|
||||
theme
|
||||
})
|
||||
);
|
||||
|
||||
const mapDispatchToProps = dispatch =>
|
||||
bindActionCreators(
|
||||
{
|
||||
const mapDispatchToProps = {
|
||||
setEditorFocusability,
|
||||
executeChallenge,
|
||||
updateFile
|
||||
},
|
||||
dispatch
|
||||
);
|
||||
};
|
||||
|
||||
const modeMap = {
|
||||
css: 'css',
|
||||
@ -110,13 +113,15 @@ class Editor extends Component {
|
||||
|
||||
editorDidMount = (editor, monaco) => {
|
||||
this._editor = editor;
|
||||
if (this.props.canFocus) this._editor.focus();
|
||||
if (this.props.canFocus) {
|
||||
this._editor.focus();
|
||||
} else this.focusOnHotkeys();
|
||||
this._editor.addAction({
|
||||
id: 'execute-challenge',
|
||||
label: 'Run tests',
|
||||
keybindings: [
|
||||
/* eslint-disable no-bitwise */
|
||||
monaco.KeyMod.chord(monaco.KeyMod.WinCtrl | monaco.KeyCode.Enter)
|
||||
monaco.KeyMod.chord(monaco.KeyMod.CtrlCmd | monaco.KeyCode.Enter)
|
||||
],
|
||||
run: this.props.executeChallenge
|
||||
});
|
||||
@ -125,12 +130,21 @@ class Editor extends Component {
|
||||
label: 'Leave editor',
|
||||
keybindings: [monaco.KeyCode.Escape],
|
||||
run: () => {
|
||||
if (this.props.containerRef.current)
|
||||
this.props.containerRef.current.focus();
|
||||
this.focusOnHotkeys();
|
||||
this.props.setEditorFocusability(false);
|
||||
}
|
||||
});
|
||||
this._editor.onDidFocusEditorWidget(() =>
|
||||
this.props.setEditorFocusability(true)
|
||||
);
|
||||
};
|
||||
|
||||
focusOnHotkeys() {
|
||||
if (this.props.containerRef.current) {
|
||||
this.props.containerRef.current.focus();
|
||||
}
|
||||
}
|
||||
|
||||
onChange = editorValue => {
|
||||
const { updateFile, fileKey } = this.props;
|
||||
updateFile({ key: fileKey, editorValue });
|
||||
|
@ -4,9 +4,9 @@ import { HotKeys, GlobalHotKeys } from 'react-hotkeys';
|
||||
import { navigate } from 'gatsby';
|
||||
|
||||
const keyMap = {
|
||||
EXECUTE_CHALLENGE: ['ctrl+enter'],
|
||||
NAVIGATE_PREV: ['ctrl+left'],
|
||||
NAVIGATE_NEXT: ['ctrl+right']
|
||||
EXECUTE_CHALLENGE: ['ctrl+enter', 'command+enter'],
|
||||
NAVIGATE_PREV: ['p'],
|
||||
NAVIGATE_NEXT: ['n']
|
||||
};
|
||||
|
||||
const propTypes = {
|
||||
|
@ -18,6 +18,7 @@ export const ns = 'challenge';
|
||||
export const backendNS = 'backendChallenge';
|
||||
|
||||
const initialState = {
|
||||
canFocusEditor: true,
|
||||
challengeFiles: {},
|
||||
challengeMeta: {
|
||||
id: '',
|
||||
@ -75,7 +76,9 @@ export const types = createTypes(
|
||||
'resetChallenge',
|
||||
'submitChallenge',
|
||||
|
||||
'moveToTab'
|
||||
'moveToTab',
|
||||
|
||||
'setEditorFocusability'
|
||||
],
|
||||
ns
|
||||
);
|
||||
@ -148,6 +151,8 @@ export const submitChallenge = createAction(types.submitChallenge);
|
||||
|
||||
export const moveToTab = createAction(types.moveToTab);
|
||||
|
||||
export const setEditorFocusability = createAction(types.setEditorFocusability);
|
||||
|
||||
export const currentTabSelector = state => state[ns].currentTab;
|
||||
export const challengeFilesSelector = state => state[ns].challengeFiles;
|
||||
export const challengeMetaSelector = state => state[ns].challengeMeta;
|
||||
@ -217,6 +222,8 @@ export const challengeDataSelector = state => {
|
||||
return challengeData;
|
||||
};
|
||||
|
||||
export const canFocusEditorSelector = state => state[ns].canFocusEditor;
|
||||
|
||||
const MAX_LOGS_SIZE = 64 * 1024;
|
||||
|
||||
export const reducer = handleActions(
|
||||
@ -348,6 +355,10 @@ export const reducer = handleActions(
|
||||
[types.executeChallenge]: state => ({
|
||||
...state,
|
||||
currentTab: 3
|
||||
}),
|
||||
[types.setEditorFocusability]: (state, { payload }) => ({
|
||||
...state,
|
||||
canFocusEditor: payload
|
||||
})
|
||||
},
|
||||
initialState
|
||||
|
Reference in New Issue
Block a user