Mailspring/app/internal_packages/preferences/lib/tabs/keymaps/command-item.tsx

208 lines
5.2 KiB
TypeScript
Raw Normal View History

import React from 'react';
import ReactDOM from 'react-dom';
2017-09-27 02:33:08 +08:00
import PropTypes from 'prop-types';
import _ from 'underscore';
2017-09-27 02:46:00 +08:00
import { Flexbox } from 'mailspring-component-kit';
import { localized } from 'mailspring-exports';
import fs from 'fs';
2017-09-27 02:33:08 +08:00
import { keyAndModifiersForEvent } from './mousetrap-keybinding-helpers';
Replace Babel with TypeScript compiler, switch entire app to TypeScript 🎉 (#1404) * Switch to using Typescript instead of Babel * Switch all es6 / jsx file extensions to ts / tsx * Convert Utils to a TS module from module.exports style module * Move everything from module.exports to typescript exports * Define .d.ts files for mailspring-exports and component kit… Yes it seems this is the best option :( * Load up on those @types * Synthesize TS types from PropTypes for standard components * Add types to Model classes and move constructor constants to instance vars * 9800 => 7700 TS errors * 7700 => 5600 TS errors * 5600 => 5330 TS errors * 5330 => 4866 TS errors * 4866 => 4426 TS errors * 4426 => 2411 TS errors * 2411 > 1598 TS errors * 1598 > 769 TS errors * 769 > 129 TS errors * 129 > 22 TS errors * Fix runtime errors * More runtime error fixes * Remove support for custom .es6 file extension * Remove a few odd remaining references to Nylas * Don’t ship Typescript support in the compiled app for now * Fix issues in compiled app - module resolution in TS is case sensitive? * README updates * Fix a few more TS errors * Make “No Signature” option clickable + selectable * Remove flicker when saving file and reloading keymaps * Fix mail rule item height in preferences * Fix missing spacing in thread sharing popover * Fix scrollbar ticks being nested incorrectly * Add Japanese as a manually reviewed language * Prevent the thread list from “sticking” * Re-use Sheet when switching root tabs, prevent sidebar from resetting * Ensure specs run * Update package configuration to avoid shpping types * Turn eslint back on - we will opt-in to the TS rules one by one
2019-03-05 03:03:12 +08:00
interface CommandKeybindingProps {
bindings: string[];
label: string;
command: string;
}
interface CommandKeybindingState {
editing: boolean;
editingBinding?: string;
modifiers?: string[];
keys?: string[];
}
export default class CommandKeybinding extends React.Component<
CommandKeybindingProps,
CommandKeybindingState
> {
static propTypes = {
2017-09-27 02:33:08 +08:00
bindings: PropTypes.array,
label: PropTypes.string,
command: PropTypes.string,
};
Replace Babel with TypeScript compiler, switch entire app to TypeScript 🎉 (#1404) * Switch to using Typescript instead of Babel * Switch all es6 / jsx file extensions to ts / tsx * Convert Utils to a TS module from module.exports style module * Move everything from module.exports to typescript exports * Define .d.ts files for mailspring-exports and component kit… Yes it seems this is the best option :( * Load up on those @types * Synthesize TS types from PropTypes for standard components * Add types to Model classes and move constructor constants to instance vars * 9800 => 7700 TS errors * 7700 => 5600 TS errors * 5600 => 5330 TS errors * 5330 => 4866 TS errors * 4866 => 4426 TS errors * 4426 => 2411 TS errors * 2411 > 1598 TS errors * 1598 > 769 TS errors * 769 > 129 TS errors * 129 > 22 TS errors * Fix runtime errors * More runtime error fixes * Remove support for custom .es6 file extension * Remove a few odd remaining references to Nylas * Don’t ship Typescript support in the compiled app for now * Fix issues in compiled app - module resolution in TS is case sensitive? * README updates * Fix a few more TS errors * Make “No Signature” option clickable + selectable * Remove flicker when saving file and reloading keymaps * Fix mail rule item height in preferences * Fix missing spacing in thread sharing popover * Fix scrollbar ticks being nested incorrectly * Add Japanese as a manually reviewed language * Prevent the thread list from “sticking” * Re-use Sheet when switching root tabs, prevent sidebar from resetting * Ensure specs run * Update package configuration to avoid shpping types * Turn eslint back on - we will opt-in to the TS rules one by one
2019-03-05 03:03:12 +08:00
_mounted = false;
constructor(props) {
super(props);
this.state = {
editing: false,
2017-09-27 02:33:08 +08:00
};
}
Replace Babel with TypeScript compiler, switch entire app to TypeScript 🎉 (#1404) * Switch to using Typescript instead of Babel * Switch all es6 / jsx file extensions to ts / tsx * Convert Utils to a TS module from module.exports style module * Move everything from module.exports to typescript exports * Define .d.ts files for mailspring-exports and component kit… Yes it seems this is the best option :( * Load up on those @types * Synthesize TS types from PropTypes for standard components * Add types to Model classes and move constructor constants to instance vars * 9800 => 7700 TS errors * 7700 => 5600 TS errors * 5600 => 5330 TS errors * 5330 => 4866 TS errors * 4866 => 4426 TS errors * 4426 => 2411 TS errors * 2411 > 1598 TS errors * 1598 > 769 TS errors * 769 > 129 TS errors * 129 > 22 TS errors * Fix runtime errors * More runtime error fixes * Remove support for custom .es6 file extension * Remove a few odd remaining references to Nylas * Don’t ship Typescript support in the compiled app for now * Fix issues in compiled app - module resolution in TS is case sensitive? * README updates * Fix a few more TS errors * Make “No Signature” option clickable + selectable * Remove flicker when saving file and reloading keymaps * Fix mail rule item height in preferences * Fix missing spacing in thread sharing popover * Fix scrollbar ticks being nested incorrectly * Add Japanese as a manually reviewed language * Prevent the thread list from “sticking” * Re-use Sheet when switching root tabs, prevent sidebar from resetting * Ensure specs run * Update package configuration to avoid shpping types * Turn eslint back on - we will opt-in to the TS rules one by one
2019-03-05 03:03:12 +08:00
componentDidMount() {
this._mounted = true;
}
componentDidUpdate() {
2017-09-27 02:33:08 +08:00
const { modifiers, keys, editing } = this.state;
if (editing) {
2017-09-27 02:33:08 +08:00
const finished = (modifiers.length > 0 && keys.length > 0) || keys.length >= 2;
if (finished) {
Replace Babel with TypeScript compiler, switch entire app to TypeScript 🎉 (#1404) * Switch to using Typescript instead of Babel * Switch all es6 / jsx file extensions to ts / tsx * Convert Utils to a TS module from module.exports style module * Move everything from module.exports to typescript exports * Define .d.ts files for mailspring-exports and component kit… Yes it seems this is the best option :( * Load up on those @types * Synthesize TS types from PropTypes for standard components * Add types to Model classes and move constructor constants to instance vars * 9800 => 7700 TS errors * 7700 => 5600 TS errors * 5600 => 5330 TS errors * 5330 => 4866 TS errors * 4866 => 4426 TS errors * 4426 => 2411 TS errors * 2411 > 1598 TS errors * 1598 > 769 TS errors * 769 > 129 TS errors * 129 > 22 TS errors * Fix runtime errors * More runtime error fixes * Remove support for custom .es6 file extension * Remove a few odd remaining references to Nylas * Don’t ship Typescript support in the compiled app for now * Fix issues in compiled app - module resolution in TS is case sensitive? * README updates * Fix a few more TS errors * Make “No Signature” option clickable + selectable * Remove flicker when saving file and reloading keymaps * Fix mail rule item height in preferences * Fix missing spacing in thread sharing popover * Fix scrollbar ticks being nested incorrectly * Add Japanese as a manually reviewed language * Prevent the thread list from “sticking” * Re-use Sheet when switching root tabs, prevent sidebar from resetting * Ensure specs run * Update package configuration to avoid shpping types * Turn eslint back on - we will opt-in to the TS rules one by one
2019-03-05 03:03:12 +08:00
(ReactDOM.findDOMNode(this) as HTMLElement).blur();
}
}
}
Replace Babel with TypeScript compiler, switch entire app to TypeScript 🎉 (#1404) * Switch to using Typescript instead of Babel * Switch all es6 / jsx file extensions to ts / tsx * Convert Utils to a TS module from module.exports style module * Move everything from module.exports to typescript exports * Define .d.ts files for mailspring-exports and component kit… Yes it seems this is the best option :( * Load up on those @types * Synthesize TS types from PropTypes for standard components * Add types to Model classes and move constructor constants to instance vars * 9800 => 7700 TS errors * 7700 => 5600 TS errors * 5600 => 5330 TS errors * 5330 => 4866 TS errors * 4866 => 4426 TS errors * 4426 => 2411 TS errors * 2411 > 1598 TS errors * 1598 > 769 TS errors * 769 > 129 TS errors * 129 > 22 TS errors * Fix runtime errors * More runtime error fixes * Remove support for custom .es6 file extension * Remove a few odd remaining references to Nylas * Don’t ship Typescript support in the compiled app for now * Fix issues in compiled app - module resolution in TS is case sensitive? * README updates * Fix a few more TS errors * Make “No Signature” option clickable + selectable * Remove flicker when saving file and reloading keymaps * Fix mail rule item height in preferences * Fix missing spacing in thread sharing popover * Fix scrollbar ticks being nested incorrectly * Add Japanese as a manually reviewed language * Prevent the thread list from “sticking” * Re-use Sheet when switching root tabs, prevent sidebar from resetting * Ensure specs run * Update package configuration to avoid shpping types * Turn eslint back on - we will opt-in to the TS rules one by one
2019-03-05 03:03:12 +08:00
componentWillUnmount() {
this._mounted = false;
}
_formatKeystrokes(original) {
// On Windows, display cmd-shift-c
2017-09-27 02:33:08 +08:00
if (process.platform === 'win32') return original;
// Replace "cmd" => ⌘, etc.
const modifiers = [
[/\+(?!$)/gi, ''],
[/command/gi, '⌘'],
[/meta/gi, '⌘'],
[/alt/gi, '⌥'],
[/shift/gi, '⇧'],
[/ctrl/gi, '^'],
2017-09-27 02:33:08 +08:00
[/mod/gi, process.platform === 'darwin' ? '⌘' : '^'],
];
let clean = original;
for (const [regexp, char] of modifiers) {
clean = clean.replace(regexp, char);
}
// ⌘⇧c => ⌘⇧C
if (clean !== original) {
clean = clean.toUpperCase();
}
// backspace => Backspace
if (original.length > 1 && clean === original) {
clean = clean[0].toUpperCase() + clean.slice(1);
}
return clean;
}
_renderKeystrokes = (keystrokes, idx) => {
const elements = [];
const splitKeystrokes = keystrokes.split(' ');
splitKeystrokes.forEach((keystroke, kidx) => {
elements.push(<span key={kidx}>{this._formatKeystrokes(keystroke)}</span>);
if (kidx < splitKeystrokes.length - 1) {
2017-09-27 02:33:08 +08:00
elements.push(
<span className="then" key={`then${kidx}`}>
{` ${localized('then')} `}
2017-09-27 02:33:08 +08:00
</span>
);
}
});
return (
2017-09-27 02:33:08 +08:00
<span key={`keystrokes-${idx}`} className="shortcut-value">
{elements}
</span>
);
2017-09-27 02:33:08 +08:00
};
_onEdit = () => {
2017-09-27 02:33:08 +08:00
this.setState({ editing: true, editingBinding: null, keys: [], modifiers: [] });
2017-09-27 02:36:58 +08:00
AppEnv.keymaps.suspendAllKeymaps();
2017-09-27 02:33:08 +08:00
};
_onFinishedEditing = () => {
if (this.state.editingBinding) {
2017-09-27 02:36:58 +08:00
const keymapPath = AppEnv.keymaps.getUserKeymapPath();
let keymaps = {};
try {
const exists = fs.existsSync(keymapPath);
if (exists) {
Replace Babel with TypeScript compiler, switch entire app to TypeScript 🎉 (#1404) * Switch to using Typescript instead of Babel * Switch all es6 / jsx file extensions to ts / tsx * Convert Utils to a TS module from module.exports style module * Move everything from module.exports to typescript exports * Define .d.ts files for mailspring-exports and component kit… Yes it seems this is the best option :( * Load up on those @types * Synthesize TS types from PropTypes for standard components * Add types to Model classes and move constructor constants to instance vars * 9800 => 7700 TS errors * 7700 => 5600 TS errors * 5600 => 5330 TS errors * 5330 => 4866 TS errors * 4866 => 4426 TS errors * 4426 => 2411 TS errors * 2411 > 1598 TS errors * 1598 > 769 TS errors * 769 > 129 TS errors * 129 > 22 TS errors * Fix runtime errors * More runtime error fixes * Remove support for custom .es6 file extension * Remove a few odd remaining references to Nylas * Don’t ship Typescript support in the compiled app for now * Fix issues in compiled app - module resolution in TS is case sensitive? * README updates * Fix a few more TS errors * Make “No Signature” option clickable + selectable * Remove flicker when saving file and reloading keymaps * Fix mail rule item height in preferences * Fix missing spacing in thread sharing popover * Fix scrollbar ticks being nested incorrectly * Add Japanese as a manually reviewed language * Prevent the thread list from “sticking” * Re-use Sheet when switching root tabs, prevent sidebar from resetting * Ensure specs run * Update package configuration to avoid shpping types * Turn eslint back on - we will opt-in to the TS rules one by one
2019-03-05 03:03:12 +08:00
keymaps = JSON.parse(fs.readFileSync(keymapPath).toString());
}
} catch (err) {
console.error(err);
}
keymaps[this.props.command] = this.state.editingBinding;
try {
fs.writeFileSync(keymapPath, JSON.stringify(keymaps, null, 2));
} catch (err) {
2017-09-27 02:36:58 +08:00
AppEnv.showErrorDialog(
localized(`Mailspring was unable to modify your keymaps at %@.`, keymapPath) +
' ' +
err.toString()
2017-09-27 02:33:08 +08:00
);
}
}
Replace Babel with TypeScript compiler, switch entire app to TypeScript 🎉 (#1404) * Switch to using Typescript instead of Babel * Switch all es6 / jsx file extensions to ts / tsx * Convert Utils to a TS module from module.exports style module * Move everything from module.exports to typescript exports * Define .d.ts files for mailspring-exports and component kit… Yes it seems this is the best option :( * Load up on those @types * Synthesize TS types from PropTypes for standard components * Add types to Model classes and move constructor constants to instance vars * 9800 => 7700 TS errors * 7700 => 5600 TS errors * 5600 => 5330 TS errors * 5330 => 4866 TS errors * 4866 => 4426 TS errors * 4426 => 2411 TS errors * 2411 > 1598 TS errors * 1598 > 769 TS errors * 769 > 129 TS errors * 129 > 22 TS errors * Fix runtime errors * More runtime error fixes * Remove support for custom .es6 file extension * Remove a few odd remaining references to Nylas * Don’t ship Typescript support in the compiled app for now * Fix issues in compiled app - module resolution in TS is case sensitive? * README updates * Fix a few more TS errors * Make “No Signature” option clickable + selectable * Remove flicker when saving file and reloading keymaps * Fix mail rule item height in preferences * Fix missing spacing in thread sharing popover * Fix scrollbar ticks being nested incorrectly * Add Japanese as a manually reviewed language * Prevent the thread list from “sticking” * Re-use Sheet when switching root tabs, prevent sidebar from resetting * Ensure specs run * Update package configuration to avoid shpping types * Turn eslint back on - we will opt-in to the TS rules one by one
2019-03-05 03:03:12 +08:00
2017-09-27 02:36:58 +08:00
AppEnv.keymaps.resumeAllKeymaps();
Replace Babel with TypeScript compiler, switch entire app to TypeScript 🎉 (#1404) * Switch to using Typescript instead of Babel * Switch all es6 / jsx file extensions to ts / tsx * Convert Utils to a TS module from module.exports style module * Move everything from module.exports to typescript exports * Define .d.ts files for mailspring-exports and component kit… Yes it seems this is the best option :( * Load up on those @types * Synthesize TS types from PropTypes for standard components * Add types to Model classes and move constructor constants to instance vars * 9800 => 7700 TS errors * 7700 => 5600 TS errors * 5600 => 5330 TS errors * 5330 => 4866 TS errors * 4866 => 4426 TS errors * 4426 => 2411 TS errors * 2411 > 1598 TS errors * 1598 > 769 TS errors * 769 > 129 TS errors * 129 > 22 TS errors * Fix runtime errors * More runtime error fixes * Remove support for custom .es6 file extension * Remove a few odd remaining references to Nylas * Don’t ship Typescript support in the compiled app for now * Fix issues in compiled app - module resolution in TS is case sensitive? * README updates * Fix a few more TS errors * Make “No Signature” option clickable + selectable * Remove flicker when saving file and reloading keymaps * Fix mail rule item height in preferences * Fix missing spacing in thread sharing popover * Fix scrollbar ticks being nested incorrectly * Add Japanese as a manually reviewed language * Prevent the thread list from “sticking” * Re-use Sheet when switching root tabs, prevent sidebar from resetting * Ensure specs run * Update package configuration to avoid shpping types * Turn eslint back on - we will opt-in to the TS rules one by one
2019-03-05 03:03:12 +08:00
setTimeout(() => {
if (!this._mounted) return;
this.setState({ editing: false, editingBinding: null });
}, 100);
2017-09-27 02:33:08 +08:00
};
2017-09-27 02:33:08 +08:00
_onKey = event => {
if (!this.state.editing) {
return;
}
event.preventDefault();
event.stopPropagation();
const [eventKey, eventMods] = keyAndModifiersForEvent(event);
if (!eventKey || ['mod', 'meta', 'command', 'ctrl', 'alt', 'shift'].includes(eventKey)) {
return;
}
2017-09-27 02:33:08 +08:00
let { keys, modifiers } = this.state;
keys = keys.concat([eventKey]);
modifiers = _.uniq(modifiers.concat(eventMods));
let editingBinding = keys.join(' ');
if (modifiers.length > 0) {
editingBinding = [...modifiers, ...keys].join('+');
editingBinding = editingBinding.replace(/(meta|command|ctrl)/g, 'mod');
}
2017-09-27 02:33:08 +08:00
this.setState({ keys, modifiers, editingBinding });
};
render() {
2017-09-27 02:33:08 +08:00
const { editing, editingBinding } = this.state;
const bindings = editingBinding ? [editingBinding] : this.props.bindings;
Replace Babel with TypeScript compiler, switch entire app to TypeScript 🎉 (#1404) * Switch to using Typescript instead of Babel * Switch all es6 / jsx file extensions to ts / tsx * Convert Utils to a TS module from module.exports style module * Move everything from module.exports to typescript exports * Define .d.ts files for mailspring-exports and component kit… Yes it seems this is the best option :( * Load up on those @types * Synthesize TS types from PropTypes for standard components * Add types to Model classes and move constructor constants to instance vars * 9800 => 7700 TS errors * 7700 => 5600 TS errors * 5600 => 5330 TS errors * 5330 => 4866 TS errors * 4866 => 4426 TS errors * 4426 => 2411 TS errors * 2411 > 1598 TS errors * 1598 > 769 TS errors * 769 > 129 TS errors * 129 > 22 TS errors * Fix runtime errors * More runtime error fixes * Remove support for custom .es6 file extension * Remove a few odd remaining references to Nylas * Don’t ship Typescript support in the compiled app for now * Fix issues in compiled app - module resolution in TS is case sensitive? * README updates * Fix a few more TS errors * Make “No Signature” option clickable + selectable * Remove flicker when saving file and reloading keymaps * Fix mail rule item height in preferences * Fix missing spacing in thread sharing popover * Fix scrollbar ticks being nested incorrectly * Add Japanese as a manually reviewed language * Prevent the thread list from “sticking” * Re-use Sheet when switching root tabs, prevent sidebar from resetting * Ensure specs run * Update package configuration to avoid shpping types * Turn eslint back on - we will opt-in to the TS rules one by one
2019-03-05 03:03:12 +08:00
let value: React.ReactChild | React.ReactChild[] = 'None';
if (bindings.length > 0) {
value = _.uniq(bindings).map(this._renderKeystrokes);
}
2017-09-27 02:33:08 +08:00
let classnames = 'shortcut';
if (editing) {
2017-09-27 02:33:08 +08:00
classnames += ' editing';
}
return (
<Flexbox
className={classnames}
tabIndex={-1}
onKeyDown={this._onKey}
onKeyPress={this._onKey}
onFocus={this._onEdit}
onBlur={this._onFinishedEditing}
>
2017-09-27 02:33:08 +08:00
<div className="col-left shortcut-name">{this.props.label}</div>
<div className="col-right">
<div className="values">{value}</div>
</div>
</Flexbox>
);
}
}