add keyboard shortcut to toggle docs

this is useful for users with small screens
This commit is contained in:
David Lechner
2021-01-27 11:48:51 -06:00
parent 4f00c962e1
commit 64e6b3739e
4 changed files with 66 additions and 2 deletions
+12
View File
@@ -7,6 +7,7 @@ import { SettingId } from '../settings/user';
/** Actions related to settings. */
export enum SettingsActionType {
SetBoolean = 'settings.action.setBoolean',
ToggleBoolean = 'settings.action.toggleBoolean',
DidFailToSetBoolean = 'settings.action.didFailToSetBoolean',
DidBooleanChange = 'settings.action.didBooleanChange',
}
@@ -27,6 +28,16 @@ export function setBoolean(id: SettingId, newState: boolean): SettingsSetBoolean
return { type: SettingsActionType.SetBoolean, id, newState };
}
/** Action to toggle a setting. */
export type SettingsToggleBooleanAction = Action<SettingsActionType.ToggleBoolean> & {
id: SettingId;
};
/** Creates an action to toggle a setting. */
export function toggleBoolean(id: SettingId): SettingsToggleBooleanAction {
return { type: SettingsActionType.ToggleBoolean, id };
}
/** Action that indicates setting/storing a setting failed. */
export type SettingsDidFailToSetBooleanAction = Action<SettingsActionType.DidFailToSetBoolean> & {
id: SettingId;
@@ -56,5 +67,6 @@ export function didBooleanChange(
/** Common type for all settings actions. */
export type SettingsAction =
| SettingsSetBooleanAction
| SettingsToggleBooleanAction
| SettingsDidFailToSetBooleanAction
| SettingsDidBooleanChangeAction;
+19 -1
View File
@@ -17,7 +17,9 @@ import { connect } from 'react-redux';
import { Action, Dispatch } from '../actions';
import { setEditSession, storageChanged } from '../actions/editor';
import { compile } from '../actions/mpy';
import { toggleBoolean } from '../actions/settings';
import { RootState } from '../reducers';
import { SettingId } from '../settings/user';
import { isMacOS } from '../utils/os';
import { EditorStringId } from './editor-i18n';
import en from './editor-i18n.en.json';
@@ -34,12 +36,14 @@ import './editor.scss';
type StateProps = {
darkMode: boolean;
showDocs: boolean;
};
type DispatchProps = {
onSessionChanged: (session?: Ace.EditSession) => void;
onProgramStorageChanged: (newValue: string) => void;
onCheck: (script: string) => void;
onToggleDocs: () => void;
};
type EditorProps = StateProps & DispatchProps & WithI18nProps;
@@ -78,7 +82,7 @@ class Editor extends React.Component<EditorProps> {
}
render(): JSX.Element {
const { darkMode, i18n, onSessionChanged, onCheck } = this.props;
const { i18n, darkMode, onSessionChanged, onCheck, onToggleDocs } = this.props;
return (
<div className="h-100">
<ResizeSensor onResize={(): void => this.editor?.resize()}>
@@ -105,6 +109,13 @@ class Editor extends React.Component<EditorProps> {
mac: 'Shift-F2',
};
// we want to use Ctrl-D for docs toggle, so change
// delete line to VSCode default
e.commands.byName['removeline'].bindKey = {
win: 'Ctrl-Shift-K',
mac: 'Cmd-Shift-K',
};
config.loadModule(
'ace/ext/menu_tools/get_editor_keyboard_shortcuts',
(m) => {
@@ -129,6 +140,11 @@ class Editor extends React.Component<EditorProps> {
bindKey: { win: 'F2', mac: 'F2' },
exec: (editor) => onCheck(editor.getValue()),
},
{
name: 'toggleDocs',
bindKey: { win: 'Ctrl-D', mac: 'Cmd-D' },
exec: () => onToggleDocs(),
},
{
name: 'save',
bindKey: { win: 'Ctrl-S', mac: 'Cmd-S' },
@@ -202,6 +218,7 @@ class Editor extends React.Component<EditorProps> {
const mapStateToProps = (state: RootState): StateProps => ({
darkMode: state.settings.darkMode,
showDocs: state.settings.showDocs,
});
const mapDispatchToProps = (dispatch: Dispatch): DispatchProps => ({
@@ -210,6 +227,7 @@ const mapDispatchToProps = (dispatch: Dispatch): DispatchProps => ({
// REVISIT: the options here might need to be changed - hopefully there is
// one setting that works for all hub types for cases where we aren't connected.
onCheck: (script) => dispatch(compile(script)),
onToggleDocs: () => dispatch(toggleBoolean(SettingId.ShowDocs)),
});
export default connect(
+27 -1
View File
@@ -5,7 +5,12 @@
import { AsyncSaga } from '../../test';
import { didStart } from '../actions/app';
import { didBooleanChange, didFailToSetBoolean, setBoolean } from '../actions/settings';
import {
didBooleanChange,
didFailToSetBoolean,
setBoolean,
toggleBoolean,
} from '../actions/settings';
import { SettingId } from '../settings/user';
import settings from './settings';
@@ -345,3 +350,24 @@ describe('storage monitor', () => {
await saga.end();
});
});
describe('toggle', () => {
test('showDocs', async () => {
const saga = new AsyncSaga(settings, { settings: { showDocs: false } });
const mockSetItem = jest
.spyOn(Object.getPrototypeOf(window.localStorage), 'setItem')
.mockImplementation((key, value) => {
expect(key).toBe('setting.showDocs');
expect(value).toBe('true');
});
saga.put(toggleBoolean(SettingId.ShowDocs));
expect(mockSetItem).toHaveBeenCalled();
const action = await saga.take();
expect(action).toEqual(didBooleanChange(SettingId.ShowDocs, true));
await saga.end();
});
});
+8
View File
@@ -11,8 +11,10 @@ import { AppActionType } from '../actions/app';
import {
SettingsActionType,
SettingsSetBooleanAction,
SettingsToggleBooleanAction,
didBooleanChange,
didFailToSetBoolean,
setBoolean,
} from '../actions/settings';
import { RootState } from '../reducers';
import { SettingId, getDefaultBooleanValue } from '../settings/user';
@@ -97,8 +99,14 @@ function* storeSetting(action: SettingsSetBooleanAction): Generator {
}
}
function* toggleSetting(action: SettingsToggleBooleanAction): Generator {
const oldValue = yield* select((s: RootState) => s.settings[action.id]);
yield* storeSetting(setBoolean(action.id, !oldValue));
}
export default function* (): Generator {
yield* fork(monitorLocalStorage);
yield* takeEvery(AppActionType.DidStart, loadSettings);
yield* takeEvery(SettingsActionType.SetBoolean, storeSetting);
yield* takeEvery(SettingsActionType.ToggleBoolean, toggleSetting);
}