@electerm/electerm-react 1.35.6 → 1.36.2

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.
@@ -216,6 +216,7 @@ export const syncTokenCreateUrls = {
216
216
  custom: 'https://github.com/electerm/electerm/wiki/Custom-sync-server'
217
217
  }
218
218
  export const settingSyncId = 'setting-sync'
219
+ export const settingTerminalId = 'setting-terminal'
219
220
  export const settingShortcutsId = 'setting-shortcuts'
220
221
  export const settingCommonId = 'setting-common'
221
222
  export const defaultEnvLang = 'en_US.UTF-8'
@@ -15,6 +15,8 @@ import './login.styl'
15
15
  const { prefix } = window
16
16
  const f = prefix('form')
17
17
 
18
+ window.store = store
19
+
18
20
  export default class Login extends Component {
19
21
  state = {
20
22
  pass: '',
@@ -3,6 +3,7 @@ import { Popover } from 'antd'
3
3
  import { HexColorPicker } from 'react-colorful'
4
4
  import { defaultColors, getRandomHexColor } from '../../common/rand-hex-color.js'
5
5
  import { HexInput } from './hex-input.jsx'
6
+ import './color-picker.styl'
6
7
 
7
8
  // Your Custom Color Picker component
8
9
  export const ColorPicker = React.forwardRef((props, ref) => {
@@ -22,6 +22,8 @@ import useQm from './use-quick-commands'
22
22
  import copy from 'json-deep-copy'
23
23
  import { defaults } from 'lodash-es'
24
24
  import renderRunScripts from './render-delayed-scripts.jsx'
25
+ import { ColorPickerItem } from './color-picker-item.jsx'
26
+ import { getRandomDefaultColor } from '../../common/rand-hex-color.js'
25
27
 
26
28
  const FormItem = Form.Item
27
29
  const { prefix } = window
@@ -60,6 +62,7 @@ export default function LocalFormUi (props) {
60
62
  term: props.store.config.terminalType,
61
63
  displayRaw: false,
62
64
  type: terminalLocalType,
65
+ color: getRandomDefaultColor(),
63
66
  runScripts: [{}],
64
67
  enableSsh: true
65
68
  }
@@ -75,10 +78,11 @@ export default function LocalFormUi (props) {
75
78
  <FormItem
76
79
  {...formItemLayout}
77
80
  label={e('title')}
78
- name='title'
79
81
  hasFeedback
80
82
  >
81
- <Input />
83
+ <FormItem noStyle name='title'>
84
+ <Input addonBefore={<ColorPickerItem />} />
85
+ </FormItem>
82
86
  </FormItem>
83
87
  <FormItem
84
88
  {...formItemLayout}
@@ -19,6 +19,7 @@ import useSubmit from './use-submit'
19
19
  import useUI from './use-ui'
20
20
  import useQm from './use-quick-commands'
21
21
  import renderCommon from './form-ssh-common'
22
+ import { getRandomDefaultColor } from '../../common/rand-hex-color.js'
22
23
  import copy from 'json-deep-copy'
23
24
  import { defaultsDeep, uniqBy } from 'lodash-es'
24
25
  import './bookmark-form.styl'
@@ -59,6 +60,7 @@ export default function TelnetFormUI (props) {
59
60
  id: '',
60
61
  username: 'root',
61
62
  password: 'guest',
63
+ color: getRandomDefaultColor(),
62
64
  runScripts: [{}],
63
65
  term: defaultSettings.terminalType,
64
66
  displayRaw: false,
@@ -23,6 +23,6 @@ export default function CustomCss (props) {
23
23
  }, [])
24
24
  useConditionalEffect(() => {
25
25
  applyTheme()
26
- }, delta && delta.prev && !eq(delta.prev, delta.curr))
26
+ }, delta && !eq(delta.prev, delta.curr))
27
27
  return null
28
28
  }
@@ -0,0 +1,124 @@
1
+ import {
2
+ Form,
3
+ Input,
4
+ Select,
5
+ Space,
6
+ Button
7
+ } from 'antd'
8
+ import { formItemLayout } from '../../common/form-layout'
9
+ import {
10
+ MinusCircleOutlined,
11
+ PlusOutlined
12
+ } from '@ant-design/icons'
13
+
14
+ const FormItem = Form.Item
15
+ const FormList = Form.List
16
+ const OptionSel = Select.Option
17
+ const { prefix } = window
18
+ const f = prefix('form')
19
+
20
+ export default function KeywordForm (props) {
21
+ const {
22
+ formData
23
+ } = props
24
+ console.log('formData', formData)
25
+ const [formChild] = Form.useForm()
26
+ function handleTrigger () {
27
+ formChild.submit()
28
+ }
29
+
30
+ function handleFinish (data) {
31
+ props.submit(data)
32
+ }
33
+
34
+ function renderItem (field, i, add, remove) {
35
+ return (
36
+ <Space
37
+ align='center'
38
+ key={field.key}
39
+ >
40
+ <FormItem
41
+ hasFeedback
42
+ >
43
+ <FormItem noStyle required name={[field.name, 'keyword']}>
44
+ <Input
45
+ addonBefore={renderBefore(field.name)}
46
+ />
47
+ </FormItem>
48
+ </FormItem>
49
+ <Button
50
+ icon={<MinusCircleOutlined />}
51
+ onClick={() => remove(field.name)}
52
+ className='mg24b'
53
+ />
54
+ </Space>
55
+ )
56
+ }
57
+
58
+ function renderBefore (name) {
59
+ const colors = ['red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white']
60
+ return (
61
+ <FormItem name={[name, 'color']} noStyle>
62
+ <Select>
63
+ {
64
+ colors.map(color => {
65
+ const ps = {
66
+ className: 'color-picker-choose iblock',
67
+ style: {
68
+ backgroundColor: color
69
+ }
70
+ }
71
+ return (
72
+ <OptionSel key={color} value={color}>
73
+ <span
74
+ {...ps}
75
+ />
76
+ </OptionSel>
77
+ )
78
+ })
79
+ }
80
+ </Select>
81
+ </FormItem>
82
+ )
83
+ }
84
+
85
+ return (
86
+ <div>
87
+ <Form
88
+ form={formChild}
89
+ onValuesChange={handleTrigger}
90
+ initialValues={formData}
91
+ onFinish={handleFinish}
92
+ >
93
+ <FormItem {...formItemLayout}>
94
+ <FormList
95
+ name='keywords'
96
+ >
97
+ {
98
+ (fields, { add, remove }, { errors }) => {
99
+ return (
100
+ <div>
101
+ {
102
+ fields.map((field, i) => {
103
+ return renderItem(field, i, add, remove)
104
+ })
105
+ }
106
+ <FormItem>
107
+ <Button
108
+ type='dashed'
109
+ onClick={() => add()}
110
+ icon={<PlusOutlined />}
111
+ >
112
+ {f('keyword')}
113
+ </Button>
114
+ </FormItem>
115
+ </div>
116
+ )
117
+ }
118
+ }
119
+ </FormList>
120
+ </FormItem>
121
+ </Form>
122
+ </div>
123
+ )
124
+ }
@@ -1,6 +1,5 @@
1
1
  import React, { Component } from 'react'
2
2
  import {
3
- CodeOutlined,
4
3
  ArrowRightOutlined,
5
4
  LoadingOutlined
6
5
  } from '@ant-design/icons'
@@ -9,29 +8,21 @@ import {
9
8
  Select,
10
9
  Switch,
11
10
  Input,
12
- Upload,
13
11
  InputNumber,
14
12
  Alert,
15
13
  Button,
16
- AutoComplete,
17
- Tooltip,
18
14
  Table,
19
15
  Space
20
16
  } from 'antd'
21
17
  import deepCopy from 'json-deep-copy'
22
18
  import {
23
- noTerminalBgValue,
24
19
  settingMap,
25
- rendererTypes,
26
20
  proxyHelpLink
27
21
  } from '../../common/constants'
28
22
  import defaultSettings from '../../common/default-setting'
29
- import ShowItem from '../common/show-item'
30
- import { osResolve } from '../../common/resolve'
31
23
  import Link from '../common/external-link'
32
24
  import { isNumber, isNaN } from 'lodash-es'
33
25
  import createEditLangLink from '../../common/create-lang-edit-link'
34
- import mapper from '../../common/auto-complete-data-mapper'
35
26
  import StartSession from './start-session-select'
36
27
  import HelpIcon from '../common/help-icon'
37
28
  import delay from '../../common/wait.js'
@@ -41,7 +32,6 @@ const { Option } = Select
41
32
  const { prefix } = window
42
33
  const e = prefix('setting')
43
34
  const f = prefix('form')
44
- const s = prefix('ssh')
45
35
  const p = prefix('sftp')
46
36
  const t = prefix('terminalThemes')
47
37
 
@@ -58,7 +48,7 @@ const keys = [
58
48
  })
59
49
  ]
60
50
 
61
- export default class Setting extends Component {
51
+ export default class SettingCommon extends Component {
62
52
  state = {
63
53
  ready: false,
64
54
  languageChanged: false,
@@ -202,20 +192,6 @@ export default class Setting extends Component {
202
192
  this.onChangeValue(value, 'onStartSessions')
203
193
  }
204
194
 
205
- handleChangeFont = (values) => {
206
- this.onChangeValue(
207
- values.join(', '),
208
- 'fontFamily'
209
- )
210
- }
211
-
212
- handleChangeCursorStyle = (cursorStyle) => {
213
- this.onChangeValue(
214
- cursorStyle,
215
- 'cursorStyle'
216
- )
217
- }
218
-
219
195
  saveConfig = async (ext) => {
220
196
  const { config } = this.props
221
197
  if (ext.hotkey && ext.hotkey !== config.hotkey) {
@@ -386,111 +362,6 @@ export default class Setting extends Component {
386
362
  )
387
363
  }
388
364
 
389
- renderBgOption = item => {
390
- return {
391
- value: item.value,
392
- label: item.desc
393
- }
394
- }
395
-
396
- renderTerminalBgSelect = (name) => {
397
- const value = this.props.config[name]
398
- const defaultValue = defaultSettings[name]
399
- const onChange = (v) => this.onChangeValue(v, name)
400
- const after = (
401
- <Upload
402
- beforeUpload={(file) => {
403
- this.onChangeValue(file.path, name)
404
- return false
405
- }}
406
- showUploadList={false}
407
- >
408
- <span>{e('chooseFile')}</span>
409
- </Upload>
410
- )
411
- const dataSource = [
412
- {
413
- value: '',
414
- desc: t('default')
415
- },
416
- {
417
- value: noTerminalBgValue,
418
- desc: e('noTerminalBg')
419
- }
420
- ]
421
- const numberOpts = { step: 0.05, min: 0, max: 1, cls: 'bg-img-setting' }
422
-
423
- const renderFilter = () => {
424
- if (this.props.config[name] === noTerminalBgValue) return
425
-
426
- return (
427
- <div>
428
- {
429
- this.renderNumber(
430
- 'terminalBackgroundFilterOpacity',
431
- numberOpts,
432
- e('Opacity')
433
- )
434
- }
435
- {
436
- this.renderNumber(
437
- 'terminalBackgroundFilterBlur',
438
- { ...numberOpts, min: 0, max: 50, step: 0.5 },
439
- e('Blur')
440
- )
441
- }
442
- {
443
- this.renderNumber(
444
- 'terminalBackgroundFilterBrightness',
445
- { ...numberOpts, min: 0, max: 10, step: 0.1 },
446
- e('Brightness')
447
- )
448
- }
449
- {
450
- this.renderNumber(
451
- 'terminalBackgroundFilterGrayscale',
452
- numberOpts,
453
- e('Grayscale')
454
- )
455
- }
456
- {
457
- this.renderNumber(
458
- 'terminalBackgroundFilterContrast',
459
- { ...numberOpts, min: 0, max: 10, step: 0.1 },
460
- e('Contrast')
461
- )
462
- }
463
- </div>
464
- )
465
- }
466
-
467
- return (
468
- <div className='pd2b'>
469
- <div className='pd1b'>
470
- <Tooltip
471
- title='eg: https://xx.com/xx.png or /path/to/xx.png'
472
- >
473
- <AutoComplete
474
- value={value}
475
- onChange={onChange}
476
- placeholder={defaultValue}
477
- className='width-100'
478
- options={dataSource.map(this.renderBgOption)}
479
- >
480
- <Input
481
- addonAfter={after}
482
- />
483
- </AutoComplete>
484
- </Tooltip>
485
- </div>
486
-
487
- {
488
- renderFilter()
489
- }
490
- </div>
491
- )
492
- }
493
-
494
365
  renderReset = () => {
495
366
  return (
496
367
  <div className='pd1b pd1t'>
@@ -503,20 +374,6 @@ export default class Setting extends Component {
503
374
  )
504
375
  }
505
376
 
506
- renderDefaultTerminalType = () => {
507
- const opts = this.props.config.terminalTypes.map(mapper)
508
- return (
509
- <AutoComplete
510
- options={opts}
511
- style={{
512
- width: '200px'
513
- }}
514
- value={this.props.config.terminalType}
515
- onChange={(v) => this.onChangeValue(v, 'terminalType')}
516
- />
517
- )
518
- }
519
-
520
377
  renderProxy () {
521
378
  const {
522
379
  enableGlobalProxy
@@ -587,82 +444,6 @@ export default class Setting extends Component {
587
444
  )
588
445
  }
589
446
 
590
- renderCursorStyleSelect = () => {
591
- const {
592
- cursorStyle = 'block'
593
- } = this.props.config
594
- const sets = [
595
- {
596
- id: 'block',
597
- title: '▊'
598
- },
599
- {
600
- id: 'underline',
601
- title: '_'
602
- },
603
- {
604
- id: 'bar',
605
- title: '|'
606
- }
607
- ]
608
- const props = {
609
- onChange: this.handleChangeCursorStyle,
610
- value: cursorStyle,
611
- style: {
612
- width: '100px'
613
- }
614
- }
615
- return (
616
- <div className='pd1b'>
617
- <span className='inline-title mg1r'>{e('cursorStyle')}</span>
618
- <Select
619
- {...props}
620
- showSearch
621
- >
622
- {
623
- sets.map(f => {
624
- return (
625
- <Option value={f.id} key={f.id}>
626
- <b>{f.title}</b>
627
- </Option>
628
- )
629
- })
630
- }
631
- </Select>
632
- </div>
633
- )
634
- }
635
-
636
- renderFontFamily = () => {
637
- const { fonts } = this.props.store
638
- const { fontFamily } = this.props.config
639
- const props = {
640
- mode: 'multiple',
641
- onChange: this.handleChangeFont,
642
- value: fontFamily.split(/, */g)
643
- }
644
- return (
645
- <Select
646
- {...props}
647
- showSearch
648
- >
649
- {
650
- fonts.map(f => {
651
- return (
652
- <Option value={f} key={f}>
653
- <span style={{
654
- fontFamily: f
655
- }}
656
- >{f}
657
- </span>
658
- </Option>
659
- )
660
- })
661
- }
662
- </Select>
663
- )
664
- }
665
-
666
447
  renderLoginPassAfter () {
667
448
  const {
668
449
  loginPass,
@@ -726,15 +507,12 @@ export default class Setting extends Component {
726
507
  const {
727
508
  hotkey,
728
509
  language,
729
- rendererType,
730
510
  theme,
731
511
  customCss
732
512
  } = this.props.config
733
513
  const {
734
- appPath,
735
514
  langs
736
515
  } = this.props.store
737
- const terminalLogPath = appPath ? osResolve(appPath, 'electerm', 'session_logs') : window.et.sessionLogPath
738
516
  const terminalThemes = this.props.store.getSidebarList(settingMap.terminalThemes)
739
517
  const [modifier, key] = hotkey.split('+')
740
518
  const pops = {
@@ -778,12 +556,6 @@ export default class Setting extends Component {
778
556
  />
779
557
  </div>
780
558
  {this.renderProxy()}
781
- {
782
- this.renderNumber('scrollback', {
783
- step: 200,
784
- min: 1000
785
- }, e('scrollBackDesc'), 400)
786
- }
787
559
  {
788
560
  this.renderNumber('sshReadyTimeout', {
789
561
  step: 200,
@@ -810,7 +582,7 @@ export default class Setting extends Component {
810
582
  }
811
583
 
812
584
  <div className='pd2b'>
813
- <span className='inline-title mg1r'>{e('terminalTheme')}</span>
585
+ <span className='inline-title mg1r'>{t('uiThemes')}</span>
814
586
  <Select
815
587
  onChange={this.handleChangeTerminalTheme}
816
588
  popupMatchSelectWidth={false}
@@ -855,52 +627,6 @@ export default class Setting extends Component {
855
627
  <Link className='mg1l' to={createEditLangLink(language)}>{p('edit')}</Link>
856
628
  </div>
857
629
  {this.renderRestart('languageChanged')}
858
- <div className='pd1y font16 bold'>
859
- <CodeOutlined className='mg1r' />
860
- {s('terminal')} {e('settings')}
861
- </div>
862
- <div className='pd2b'>
863
- <span className='inline-title mg1r'>{e('rendererType')}</span>
864
- <Select
865
- onChange={v => this.onChangeValue(v, 'rendererType')}
866
- value={rendererType}
867
- popupMatchSelectWidth={false}
868
- >
869
- {
870
- Object.keys(rendererTypes).map(id => {
871
- return (
872
- <Option key={id} value={id}>{id}</Option>
873
- )
874
- })
875
- }
876
- </Select>
877
- </div>
878
- {
879
- this.renderNumber('fontSize', {
880
- step: 1,
881
- min: 9
882
- }, `${t('default')} ${e('fontSize')}`, 400)
883
- }
884
- <div className='pd2b'>
885
- <span className='inline-title mg1r'>{t('default')} {e('fontFamily')}</span>
886
- {
887
- this.renderFontFamily()
888
- }
889
- </div>
890
- <div className='pd2b'>
891
- <span className='inline-title mg1r'>{e('defaultTerminalType')}</span>
892
- {
893
- this.renderDefaultTerminalType()
894
- }
895
- </div>
896
- <div className='pd1b'>{e('terminalBackgroundImage')}</div>
897
- {
898
- this.renderTerminalBgSelect('terminalBackgroundImagePath')
899
- }
900
- <div className='pd1b'>{e('terminalWordSeparator')}</div>
901
- {
902
- this.renderText('terminalWordSeparator', e('terminalWordSeparator'))
903
- }
904
630
  <div className='pd1b'>{t('default')} {e('execWindows')}</div>
905
631
  {
906
632
  this.renderTextExec('execWindows')
@@ -913,31 +639,19 @@ export default class Setting extends Component {
913
639
  {
914
640
  this.renderTextExec('execLinux')
915
641
  }
916
- {
917
- this.renderCursorStyleSelect()
918
- }
919
642
  {
920
643
  [
921
644
  'autoRefreshWhenSwitchToSftp',
922
645
  'screenReaderMode',
923
646
  'initDefaultTabOnStart',
924
- 'cursorBlink',
925
- 'rightClickSelectsWord',
926
- 'pasteWhenContextMenu',
927
- 'copyWhenSelect',
928
647
  'disableSshHistory',
929
648
  'disableTransferHistory',
930
- 'ctrlOrMetaOpenTerminalLink',
931
649
  'checkUpdateOnStart',
932
650
  'useSystemTitleBar',
933
651
  'confirmBeforeExit',
934
652
  'debug'
935
653
  ].map(this.renderToggle)
936
654
  }
937
- {this.renderToggle('saveTerminalLogToFile', (
938
- <ShowItem to={terminalLogPath} className='mg1l'>{p('open')}</ShowItem>
939
- ))}
940
-
941
655
  {this.renderLoginPass()}
942
656
  {this.renderReset()}
943
657
  </div>