@electerm/electerm-react 1.34.63 → 1.35.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client/common/constants.js +3 -1
- package/client/common/key-pressed.js +1 -1
- package/client/common/rand-hex-color.js +28 -0
- package/client/common/shortcuts-defaults.js +51 -0
- package/client/components/batch-op/batch-op.jsx +6 -2
- package/client/components/bookmark-form/color-picker-item.jsx +14 -0
- package/client/components/bookmark-form/color-picker.jsx +90 -0
- package/client/components/bookmark-form/color-picker.styl +20 -0
- package/client/components/bookmark-form/form-ssh-common.jsx +4 -0
- package/client/components/bookmark-form/hex-input.jsx +39 -0
- package/client/components/bookmark-form/local-form-ui.jsx +1 -0
- package/client/components/bookmark-form/serial-form-ui.jsx +12 -8
- package/client/components/bookmark-form/ssh-form-ui.jsx +3 -0
- package/client/components/bookmark-form/telnet-form-ui.jsx +1 -0
- package/client/components/bookmark-form/use-ui.jsx +11 -1
- package/client/components/context-menu/context-menu.styl +1 -1
- package/client/components/context-menu/menu-btn.jsx +6 -3
- package/client/components/main/custom-css.jsx +28 -0
- package/client/components/main/main.jsx +5 -2
- package/client/components/session/session.jsx +11 -35
- package/client/components/session/sessions.jsx +15 -15
- package/client/components/setting-panel/setting.jsx +20 -32
- package/client/components/setting-panel/tab-settings.jsx +13 -10
- package/client/components/sftp/transfer-tag.jsx +2 -2
- package/client/components/sftp/transport-action.jsx +1 -0
- package/client/components/shortcuts/get-key-char.js +45 -0
- package/client/components/shortcuts/shortcut-control.jsx +63 -0
- package/client/components/shortcuts/shortcut-editor.jsx +194 -0
- package/client/components/shortcuts/shortcut-handler.js +76 -0
- package/client/components/shortcuts/shortcut.styl +0 -0
- package/client/components/shortcuts/shortcuts-defaults.js +87 -0
- package/client/components/shortcuts/shortcuts.jsx +166 -0
- package/client/components/sidebar/index.jsx +1 -1
- package/client/components/sidebar/transfer-history-modal.jsx +14 -2
- package/client/components/tabs/index.jsx +0 -25
- package/client/components/tabs/tab.jsx +6 -5
- package/client/components/terminal/index.jsx +93 -110
- package/client/components/terminal/term-search.jsx +9 -21
- package/client/components/terminal-theme/index.jsx +4 -3
- package/client/store/index.js +17 -2
- package/client/store/init-state.js +1 -8
- package/client/store/item.js +3 -0
- package/client/store/session.js +0 -22
- package/client/store/watch.js +3 -1
- package/client/views/index.pug +2 -0
- package/package.json +1 -1
|
@@ -14,8 +14,6 @@ import {
|
|
|
14
14
|
statusMap
|
|
15
15
|
} from '../../common/constants'
|
|
16
16
|
import newTerm, { updateCount } from '../../common/new-terminal'
|
|
17
|
-
import keyControlPress from '../../common/key-control-pressed'
|
|
18
|
-
import keyPressed from '../../common/key-pressed'
|
|
19
17
|
import postMsg from '../../common/post-msg'
|
|
20
18
|
import TermSearch from '../terminal/term-search'
|
|
21
19
|
import Footer from '../footer/footer-entry'
|
|
@@ -23,12 +21,13 @@ import QuickCommandsFooterBox from '../quick-commands/quick-commands-box'
|
|
|
23
21
|
import LogoElem from '../common/logo-elem'
|
|
24
22
|
import { Button } from 'antd'
|
|
25
23
|
import toSimpleObj from '../../common/to-simple-obj'
|
|
24
|
+
import { shortcutExtend } from '../shortcuts/shortcut-handler.js'
|
|
26
25
|
|
|
27
26
|
const { prefix } = window
|
|
28
27
|
const e = prefix('tabs')
|
|
29
28
|
const c = prefix('control')
|
|
30
29
|
|
|
31
|
-
|
|
30
|
+
class Sessions extends Component {
|
|
32
31
|
state = {
|
|
33
32
|
tabs: [],
|
|
34
33
|
currentTabId: ''
|
|
@@ -40,16 +39,14 @@ export default class Sessions extends Component {
|
|
|
40
39
|
}
|
|
41
40
|
|
|
42
41
|
initShortcuts () {
|
|
43
|
-
window.addEventListener('keydown',
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
}
|
|
52
|
-
})
|
|
42
|
+
window.addEventListener('keydown', this.handleKeyboardEvent.bind(this))
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
closeCurrentTabShortcut = (e) => {
|
|
46
|
+
e.stopPropagation()
|
|
47
|
+
this.delTab(
|
|
48
|
+
this.state.currentTabId
|
|
49
|
+
)
|
|
53
50
|
}
|
|
54
51
|
|
|
55
52
|
watch = () => {
|
|
@@ -418,11 +415,12 @@ export default class Sessions extends Component {
|
|
|
418
415
|
}
|
|
419
416
|
|
|
420
417
|
render () {
|
|
421
|
-
const { store } = this.props
|
|
418
|
+
const { store, config } = this.props
|
|
422
419
|
const currentTab = this.getCurrentTab()
|
|
423
420
|
const termProps = {
|
|
424
421
|
currentTab,
|
|
425
|
-
store
|
|
422
|
+
store,
|
|
423
|
+
config
|
|
426
424
|
}
|
|
427
425
|
return [
|
|
428
426
|
this.renderTabs(),
|
|
@@ -443,3 +441,5 @@ export default class Sessions extends Component {
|
|
|
443
441
|
]
|
|
444
442
|
}
|
|
445
443
|
}
|
|
444
|
+
|
|
445
|
+
export default shortcutExtend(Sessions)
|
|
@@ -34,7 +34,6 @@ import createEditLangLink from '../../common/create-lang-edit-link'
|
|
|
34
34
|
import mapper from '../../common/auto-complete-data-mapper'
|
|
35
35
|
import StartSession from './start-session-select'
|
|
36
36
|
import HelpIcon from '../common/help-icon'
|
|
37
|
-
import fs from '../../common/fs'
|
|
38
37
|
import delay from '../../common/wait.js'
|
|
39
38
|
import './setting.styl'
|
|
40
39
|
|
|
@@ -186,6 +185,10 @@ export default class Setting extends Component {
|
|
|
186
185
|
this.props.store.setTheme(id)
|
|
187
186
|
}
|
|
188
187
|
|
|
188
|
+
handleCustomCss = (e) => {
|
|
189
|
+
this.onChangeValue(e.target.value, 'customCss')
|
|
190
|
+
}
|
|
191
|
+
|
|
189
192
|
onChangeValue = (value, name) => {
|
|
190
193
|
if (name === 'useSystemTitleBar') {
|
|
191
194
|
message.info(e('useSystemTitleBarTip'), 5)
|
|
@@ -213,21 +216,18 @@ export default class Setting extends Component {
|
|
|
213
216
|
)
|
|
214
217
|
}
|
|
215
218
|
|
|
216
|
-
saveConfig = async (
|
|
217
|
-
const config =
|
|
218
|
-
const ext = deepCopy(_ext)
|
|
219
|
-
const update = Object.assign({}, config, deepCopy(_ext))
|
|
219
|
+
saveConfig = async (ext) => {
|
|
220
|
+
const { config } = this.props
|
|
220
221
|
if (ext.hotkey && ext.hotkey !== config.hotkey) {
|
|
221
222
|
const res = await window.pre.runGlobalAsync('changeHotkey', ext.hotkey)
|
|
222
223
|
if (!res) {
|
|
223
224
|
message.warning(e('hotkeyNotOk'))
|
|
224
|
-
|
|
225
|
-
ext.hotkey = config.hotkey
|
|
225
|
+
delete ext.hotkey
|
|
226
226
|
} else {
|
|
227
227
|
message.success(e('saved'))
|
|
228
228
|
}
|
|
229
229
|
}
|
|
230
|
-
this.props.store.setConfig(
|
|
230
|
+
this.props.store.setConfig(ext)
|
|
231
231
|
}
|
|
232
232
|
|
|
233
233
|
renderOption = (m, i) => {
|
|
@@ -663,29 +663,6 @@ export default class Setting extends Component {
|
|
|
663
663
|
)
|
|
664
664
|
}
|
|
665
665
|
|
|
666
|
-
handlePortable = async () => {
|
|
667
|
-
const {
|
|
668
|
-
appPath,
|
|
669
|
-
exePath
|
|
670
|
-
} = this.props.store
|
|
671
|
-
const from = osResolve(appPath, 'electerm', 'users')
|
|
672
|
-
const tar = osResolve(exePath, 'electerm', 'users')
|
|
673
|
-
const cmd = `xcopy /E /I /Q /Y "${from}" ${tar}`
|
|
674
|
-
const x = await fs.runWinCmd(cmd)
|
|
675
|
-
.catch(err => {
|
|
676
|
-
this.props.store.onError(err)
|
|
677
|
-
return false
|
|
678
|
-
})
|
|
679
|
-
if (x !== false) {
|
|
680
|
-
message.success(
|
|
681
|
-
`${e('dataTransferedTo')}: ${tar}`
|
|
682
|
-
)
|
|
683
|
-
setTimeout(
|
|
684
|
-
this.props.store.restart, 5000
|
|
685
|
-
)
|
|
686
|
-
}
|
|
687
|
-
}
|
|
688
|
-
|
|
689
666
|
renderLoginPassAfter () {
|
|
690
667
|
const {
|
|
691
668
|
loginPass,
|
|
@@ -750,7 +727,8 @@ export default class Setting extends Component {
|
|
|
750
727
|
hotkey,
|
|
751
728
|
language,
|
|
752
729
|
rendererType,
|
|
753
|
-
theme
|
|
730
|
+
theme,
|
|
731
|
+
customCss
|
|
754
732
|
} = this.props.config
|
|
755
733
|
const {
|
|
756
734
|
appPath,
|
|
@@ -848,6 +826,16 @@ export default class Setting extends Component {
|
|
|
848
826
|
}
|
|
849
827
|
</Select>
|
|
850
828
|
</div>
|
|
829
|
+
|
|
830
|
+
<div className='pd2b'>
|
|
831
|
+
<span className='inline-title mg1r'>{e('customCss')}</span>
|
|
832
|
+
<Input.TextArea
|
|
833
|
+
onChange={this.handleCustomCss}
|
|
834
|
+
value={customCss}
|
|
835
|
+
rows={3}
|
|
836
|
+
/>
|
|
837
|
+
</div>
|
|
838
|
+
|
|
851
839
|
<div className='pd2b'>
|
|
852
840
|
<span className='inline-title mg1r'>{e('language')}</span>
|
|
853
841
|
<Select
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import Setting from './setting'
|
|
2
2
|
import SettingCol from './col'
|
|
3
3
|
import SyncSetting from '../setting-sync/setting-sync'
|
|
4
|
+
import Shortcuts from '../shortcuts/shortcuts'
|
|
4
5
|
import List from './list'
|
|
5
6
|
import {
|
|
6
7
|
settingMap,
|
|
7
|
-
settingSyncId
|
|
8
|
+
settingSyncId,
|
|
9
|
+
settingShortcutsId
|
|
8
10
|
} from '../../common/constants'
|
|
9
11
|
|
|
10
12
|
export default function TabSettings (props) {
|
|
@@ -19,6 +21,15 @@ export default function TabSettings (props) {
|
|
|
19
21
|
listProps,
|
|
20
22
|
store
|
|
21
23
|
} = props
|
|
24
|
+
let elem = null
|
|
25
|
+
const sid = settingItem.id
|
|
26
|
+
if (sid === settingSyncId) {
|
|
27
|
+
elem = <SyncSetting store={store} />
|
|
28
|
+
} else if (sid === settingShortcutsId) {
|
|
29
|
+
elem = <Shortcuts store={store} />
|
|
30
|
+
} else {
|
|
31
|
+
elem = <Setting {...listProps} config={store.config} />
|
|
32
|
+
}
|
|
22
33
|
return (
|
|
23
34
|
<div
|
|
24
35
|
className='setting-tabs-setting'
|
|
@@ -27,15 +38,7 @@ export default function TabSettings (props) {
|
|
|
27
38
|
<List
|
|
28
39
|
{...listProps}
|
|
29
40
|
/>
|
|
30
|
-
{
|
|
31
|
-
settingItem.id === settingSyncId
|
|
32
|
-
? (
|
|
33
|
-
<SyncSetting
|
|
34
|
-
store={store}
|
|
35
|
-
/>
|
|
36
|
-
)
|
|
37
|
-
: <Setting {...listProps} config={store.config} />
|
|
38
|
-
}
|
|
41
|
+
{elem}
|
|
39
42
|
</SettingCol>
|
|
40
43
|
</div>
|
|
41
44
|
)
|
|
@@ -21,7 +21,7 @@ export default function TransferTag (props) {
|
|
|
21
21
|
const typeFromTitle = e(typeFrom)
|
|
22
22
|
const typeToTitle = e(typeTo)
|
|
23
23
|
const title = error
|
|
24
|
-
? `error: ${error}`
|
|
24
|
+
? `[error: ${error}]`
|
|
25
25
|
: ''
|
|
26
26
|
return (
|
|
27
27
|
<span className={'flex-child transfer-tag transfer-status-' + tagStatus} title={title}>
|
|
@@ -34,7 +34,7 @@ export default function TransferTag (props) {
|
|
|
34
34
|
<span className='sftp-transfer-type'>
|
|
35
35
|
{typeToTitle}
|
|
36
36
|
</span>
|
|
37
|
-
<span className='mg1l'>
|
|
37
|
+
<span className='mg1l'>{title}</span>
|
|
38
38
|
</span>
|
|
39
39
|
)
|
|
40
40
|
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export function getKeyCharacter (code = '') {
|
|
2
|
+
const mapping = {
|
|
3
|
+
Backquote: '`',
|
|
4
|
+
Minus: '-',
|
|
5
|
+
Equal: '=',
|
|
6
|
+
BracketLeft: '[',
|
|
7
|
+
BracketRight: ']',
|
|
8
|
+
Backslash: '\\',
|
|
9
|
+
NumpadDivide: '/',
|
|
10
|
+
NumpadMultiply: '*',
|
|
11
|
+
NumpadSubtract: '-',
|
|
12
|
+
Numpad7: 'N7',
|
|
13
|
+
Numpad8: 'N8',
|
|
14
|
+
Numpad9: 'N9',
|
|
15
|
+
NumpadAdd: '+',
|
|
16
|
+
Numpad4: 'N4',
|
|
17
|
+
Numpad5: 'N5',
|
|
18
|
+
Numpad6: 'N6',
|
|
19
|
+
Numpad1: 'N1',
|
|
20
|
+
Numpad2: 'N2',
|
|
21
|
+
Numpad3: 'N3',
|
|
22
|
+
NumpadEnter: 'Enter',
|
|
23
|
+
Numpad0: 'N0',
|
|
24
|
+
NumpadDecimal: '.',
|
|
25
|
+
IntlBackslash: '\\',
|
|
26
|
+
ArrowLeft: '←',
|
|
27
|
+
ArrowUp: '↑',
|
|
28
|
+
ArrowRight: '→',
|
|
29
|
+
ArrowDown: '↓',
|
|
30
|
+
Semicolon: ';',
|
|
31
|
+
Quote: '\'',
|
|
32
|
+
Comma: ',',
|
|
33
|
+
Period: '.',
|
|
34
|
+
Slash: '/',
|
|
35
|
+
mouseWheelUp: '▲',
|
|
36
|
+
mouseWheelDown: '▼'
|
|
37
|
+
}
|
|
38
|
+
if (code.startsWith('Key') && code.length === 4) {
|
|
39
|
+
return code[3].toLowerCase()
|
|
40
|
+
} else if (code.startsWith('Digit') && code.length === 5) {
|
|
41
|
+
return code[5]
|
|
42
|
+
} else {
|
|
43
|
+
return mapping[code] || code
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* session tabs component
|
|
3
|
+
* @param {array} props.tabs {id, title}
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import React from 'react'
|
|
7
|
+
import { shortcutExtend } from './shortcut-handler.js'
|
|
8
|
+
|
|
9
|
+
class ShortcutControl extends React.PureComponent {
|
|
10
|
+
componentDidMount () {
|
|
11
|
+
window.addEventListener('keydown', this.handleKeyboardEvent.bind(this))
|
|
12
|
+
window.addEventListener('mousewheel', this.handleKeyboardEvent.bind(this))
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
prevTabShortcut = (e) => {
|
|
16
|
+
e.stopPropagation()
|
|
17
|
+
window.store.clickPrevTab()
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
nextTabShortcut = (e) => {
|
|
21
|
+
e.stopPropagation()
|
|
22
|
+
window.store.clickNextTab()
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
newBookmarkShortcut = (e) => {
|
|
26
|
+
e.stopPropagation()
|
|
27
|
+
window.store.onNewSsh()
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
togglefullscreenShortcut = (e) => {
|
|
31
|
+
e.stopPropagation()
|
|
32
|
+
document.querySelector('.term-fullscreen-control').click()
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
zoominShortcut = (e) => {
|
|
36
|
+
e.stopPropagation()
|
|
37
|
+
window.store.zoom(0.25, true)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
zoomoutShortcut = (e) => {
|
|
41
|
+
e.stopPropagation()
|
|
42
|
+
window.store.zoom(-0.25, true)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
zoominTerminalShortcut = (event) => {
|
|
46
|
+
if (window.store.inActiveTerminal) {
|
|
47
|
+
window.store.zoomTerminal(event.wheelDeltaY)
|
|
48
|
+
} else {
|
|
49
|
+
const plus = event.wheelDeltaY > 0 ? 0.2 : -0.2
|
|
50
|
+
window.store.zoom(plus, true)
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
zoomoutTerminalShortcut = (event) => {
|
|
55
|
+
this.zoominTerminalShortcut(event)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
render () {
|
|
59
|
+
return null
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export default shortcutExtend(ShortcutControl)
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import { PureComponent } from 'react'
|
|
2
|
+
import {
|
|
3
|
+
Button,
|
|
4
|
+
Input,
|
|
5
|
+
message
|
|
6
|
+
} from 'antd'
|
|
7
|
+
import {
|
|
8
|
+
EditFilled,
|
|
9
|
+
CheckOutlined,
|
|
10
|
+
CloseOutlined
|
|
11
|
+
} from '@ant-design/icons'
|
|
12
|
+
import { debounce } from 'lodash-es'
|
|
13
|
+
import { getKeyCharacter } from './get-key-char.js'
|
|
14
|
+
|
|
15
|
+
export default class ShortcutEdit extends PureComponent {
|
|
16
|
+
state = {
|
|
17
|
+
editMode: false,
|
|
18
|
+
shortcut: '',
|
|
19
|
+
data: null
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
addEventListener = () => {
|
|
23
|
+
const elem = document.querySelector('.ant-drawer')
|
|
24
|
+
elem?.addEventListener('click', this.handleClickOuter)
|
|
25
|
+
document.addEventListener('keydown', this.handleKeyDown)
|
|
26
|
+
document.addEventListener('mousewheel', this.handleKeyDown)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
removeEventListener = () => {
|
|
30
|
+
const elem = document.querySelector('.ant-drawer')
|
|
31
|
+
elem?.removeEventListener('click', this.handleClickOuter)
|
|
32
|
+
document.removeEventListener('keydown', this.handleKeyDown)
|
|
33
|
+
document.removeEventListener('mousewheel', this.handleKeyDown)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
isInsideElement = (event) => {
|
|
37
|
+
const { target } = event
|
|
38
|
+
const cls = this.getCls()
|
|
39
|
+
if (!target || !target.classList) {
|
|
40
|
+
return false
|
|
41
|
+
} else if (target.classList.contains(cls)) {
|
|
42
|
+
return true
|
|
43
|
+
} else {
|
|
44
|
+
const parent = target.parentElement
|
|
45
|
+
if (parent !== null) {
|
|
46
|
+
return this.isInsideElement({ target: parent })
|
|
47
|
+
} else {
|
|
48
|
+
return false
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
handleClickOuter = (e) => {
|
|
54
|
+
if (!this.isInsideElement(e)) {
|
|
55
|
+
this.handleCancel()
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
handleEditClick = () => {
|
|
60
|
+
this.setState({
|
|
61
|
+
editMode: true
|
|
62
|
+
}, this.addEventListener)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
handleCancel = () => {
|
|
66
|
+
this.setState({
|
|
67
|
+
editMode: false
|
|
68
|
+
}, this.removeEventListener)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
handleConfirm = () => {
|
|
72
|
+
const {
|
|
73
|
+
name
|
|
74
|
+
} = this.props.data
|
|
75
|
+
this.props.updateConfig(
|
|
76
|
+
name, this.state.shortcut
|
|
77
|
+
)
|
|
78
|
+
this.handleCancel()
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
getCls = () => {
|
|
82
|
+
const { index } = this.props.data
|
|
83
|
+
return 'shortcut-control-' + index
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
warnCtrolKey = debounce(() => {
|
|
87
|
+
message.info(
|
|
88
|
+
'Must have one of Ctrl or Shift or Alt or Meta key',
|
|
89
|
+
undefined
|
|
90
|
+
)
|
|
91
|
+
}, 3000)
|
|
92
|
+
|
|
93
|
+
warnExist = debounce(() => {
|
|
94
|
+
message.info(
|
|
95
|
+
'Shortcut already exists',
|
|
96
|
+
undefined
|
|
97
|
+
)
|
|
98
|
+
}, 3000)
|
|
99
|
+
|
|
100
|
+
handleKeyDown = (e) => {
|
|
101
|
+
const {
|
|
102
|
+
code,
|
|
103
|
+
ctrlKey,
|
|
104
|
+
shiftKey,
|
|
105
|
+
metaKey,
|
|
106
|
+
altKey,
|
|
107
|
+
wheelDeltaY
|
|
108
|
+
} = e
|
|
109
|
+
const codeName = e instanceof window.WheelEvent
|
|
110
|
+
? (wheelDeltaY > 0 ? 'mouseWheelUp' : 'mouseWheelDown')
|
|
111
|
+
: code
|
|
112
|
+
const codeK = getKeyCharacter(codeName)
|
|
113
|
+
const noControlKey = !ctrlKey && !shiftKey && !metaKey && !altKey
|
|
114
|
+
if (noControlKey && codeK === 'Escape') {
|
|
115
|
+
return this.handleCancel()
|
|
116
|
+
} else if (noControlKey) {
|
|
117
|
+
return this.warnCtrolKey()
|
|
118
|
+
}
|
|
119
|
+
const r = (ctrlKey ? 'ctrl+' : '') +
|
|
120
|
+
(metaKey ? 'meta+' : '') +
|
|
121
|
+
(shiftKey ? 'shift+' : '') +
|
|
122
|
+
(altKey ? 'alt+' : '') +
|
|
123
|
+
codeK.toLowerCase()
|
|
124
|
+
if (this.props.keysTaken[r]) {
|
|
125
|
+
return this.warnExist()
|
|
126
|
+
}
|
|
127
|
+
this.setState({
|
|
128
|
+
shortcut: r
|
|
129
|
+
})
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
handleClickOutside = () => {
|
|
133
|
+
this.removeEventListener()
|
|
134
|
+
this.setState({
|
|
135
|
+
editMode: false
|
|
136
|
+
})
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
renderStatic () {
|
|
140
|
+
const {
|
|
141
|
+
shortcut
|
|
142
|
+
} = this.props.data
|
|
143
|
+
return (
|
|
144
|
+
<Button
|
|
145
|
+
className='edit-shortcut-button'
|
|
146
|
+
onClick={this.handleEditClick}
|
|
147
|
+
>
|
|
148
|
+
<span>{shortcut}</span>
|
|
149
|
+
<EditFilled
|
|
150
|
+
className='shortcut-edit-icon pointer mg1l'
|
|
151
|
+
/>
|
|
152
|
+
</Button>
|
|
153
|
+
)
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
renderAfter () {
|
|
157
|
+
const {
|
|
158
|
+
shortcut
|
|
159
|
+
} = this.state
|
|
160
|
+
if (!shortcut) {
|
|
161
|
+
return null
|
|
162
|
+
}
|
|
163
|
+
return (
|
|
164
|
+
<div>
|
|
165
|
+
<CheckOutlined
|
|
166
|
+
onClick={this.handleConfirm}
|
|
167
|
+
className='pointer'
|
|
168
|
+
/>
|
|
169
|
+
<CloseOutlined
|
|
170
|
+
onClick={this.handleCancel}
|
|
171
|
+
className='pointer mg1l'
|
|
172
|
+
/>
|
|
173
|
+
</div>
|
|
174
|
+
)
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
render () {
|
|
178
|
+
const {
|
|
179
|
+
shortcut,
|
|
180
|
+
editMode
|
|
181
|
+
} = this.state
|
|
182
|
+
if (!editMode) {
|
|
183
|
+
return this.renderStatic()
|
|
184
|
+
}
|
|
185
|
+
return (
|
|
186
|
+
<div className={this.getCls()}>
|
|
187
|
+
<Input
|
|
188
|
+
addonAfter={this.renderAfter()}
|
|
189
|
+
value={shortcut}
|
|
190
|
+
/>
|
|
191
|
+
</div>
|
|
192
|
+
)
|
|
193
|
+
}
|
|
194
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { getKeyCharacter } from './get-key-char.js'
|
|
2
|
+
import shortcutsDefaultsGen from './shortcuts-defaults.js'
|
|
3
|
+
import {
|
|
4
|
+
isMacJs
|
|
5
|
+
} from '../../common/constants'
|
|
6
|
+
|
|
7
|
+
function buildConfig (config) {
|
|
8
|
+
const defs = shortcutsDefaultsGen()
|
|
9
|
+
const { shortcuts = {} } = config
|
|
10
|
+
return defs.reduce((p, c) => {
|
|
11
|
+
const propName = isMacJs ? 'shortcutMac' : 'shortcut'
|
|
12
|
+
const name = c.name + '_' + propName
|
|
13
|
+
const [type, func] = c.name.split('_')
|
|
14
|
+
return {
|
|
15
|
+
...p,
|
|
16
|
+
[name]: {
|
|
17
|
+
shortcut: c.readonly ? c[propName] : (shortcuts[name] || c[propName]),
|
|
18
|
+
type,
|
|
19
|
+
func
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}, {})
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function shortcutExtend (Cls) {
|
|
26
|
+
Cls.prototype.handleKeyboardEvent = function (event) {
|
|
27
|
+
// console.log('event', event)
|
|
28
|
+
const {
|
|
29
|
+
code,
|
|
30
|
+
ctrlKey,
|
|
31
|
+
shiftKey,
|
|
32
|
+
metaKey,
|
|
33
|
+
altKey,
|
|
34
|
+
wheelDeltaY
|
|
35
|
+
} = event
|
|
36
|
+
const codeName = event instanceof window.WheelEvent
|
|
37
|
+
? (wheelDeltaY > 0 ? 'mouseWheelUp' : 'mouseWheelDown')
|
|
38
|
+
: code
|
|
39
|
+
const codeK = getKeyCharacter(codeName)
|
|
40
|
+
const noControlKey = !ctrlKey && !shiftKey && !metaKey && !altKey
|
|
41
|
+
if (noControlKey) {
|
|
42
|
+
return
|
|
43
|
+
}
|
|
44
|
+
const r = (ctrlKey ? 'ctrl+' : '') +
|
|
45
|
+
(metaKey ? 'meta+' : '') +
|
|
46
|
+
(shiftKey ? 'shift+' : '') +
|
|
47
|
+
(altKey ? 'alt+' : '') +
|
|
48
|
+
codeK.toLowerCase()
|
|
49
|
+
const shortcutsConfig = buildConfig(this.props.config)
|
|
50
|
+
const keys = Object.keys(shortcutsConfig)
|
|
51
|
+
const len = keys.length
|
|
52
|
+
for (let i = 0; i < len; i++) {
|
|
53
|
+
const k = keys[i]
|
|
54
|
+
const conf = shortcutsConfig[k]
|
|
55
|
+
const funcName = conf.func + 'Shortcut'
|
|
56
|
+
if (conf.shortcut.split(',').includes(r)) {
|
|
57
|
+
if (this[funcName]) {
|
|
58
|
+
this[funcName](event)
|
|
59
|
+
} else {
|
|
60
|
+
return false
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return Cls
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export function shortcutDescExtend (Cls) {
|
|
69
|
+
Cls.prototype.getShortcut = function (name) {
|
|
70
|
+
const shortcutsConfig = buildConfig(this.props.config)
|
|
71
|
+
const propName = isMacJs ? 'shortcutMac' : 'shortcut'
|
|
72
|
+
const n = `${name}_${propName}`
|
|
73
|
+
return shortcutsConfig[n].shortcut
|
|
74
|
+
}
|
|
75
|
+
return Cls
|
|
76
|
+
}
|
|
File without changes
|