@electerm/electerm-react 5.0.7 → 5.1.6
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 +2 -0
- package/client/common/default-setting.js +10 -1
- package/client/common/left-sidebar-icon-defs.js +36 -0
- package/client/components/ai/ai-config-props.js +8 -0
- package/client/components/bookmark-form/common/fields.jsx +3 -2
- package/client/components/bookmark-form/common/ssh-agent.jsx +3 -2
- package/client/components/bookmark-form/common/x11.jsx +2 -2
- package/client/components/common/logo-elem.jsx +1 -1
- package/client/components/common/logo.styl +8 -2
- package/client/components/common/switch.jsx +63 -0
- package/client/components/common/switch.styl +7 -0
- package/client/components/footer/cmd-history.jsx +10 -8
- package/client/components/footer/cmd-history.styl +8 -0
- package/client/components/layout/layout.jsx +8 -5
- package/client/components/main/main.jsx +7 -2
- package/client/components/profile/profile-form-elem.jsx +2 -2
- package/client/components/quick-commands/quick-commands-box.jsx +2 -19
- package/client/components/quick-commands/quick-commands-form-elem.jsx +2 -2
- package/client/components/quick-commands/quick-commands-select.jsx +10 -20
- package/client/components/rdp/rdp-session.jsx +3 -4
- package/client/components/setting-panel/setting-common.jsx +9 -5
- package/client/components/setting-panel/setting-left-sidebar-icons.jsx +54 -0
- package/client/components/setting-panel/setting-terminal.jsx +3 -4
- package/client/components/setting-sync/data-import.jsx +3 -4
- package/client/components/setting-sync/setting-sync-form.jsx +3 -2
- package/client/components/sftp/file-compare-modal.jsx +1 -1
- package/client/components/sidebar/history.jsx +9 -11
- package/client/components/sidebar/index.jsx +22 -71
- package/client/components/sidebar/left-sidebar-icons.jsx +148 -0
- package/client/components/sidebar/sidebar.styl +6 -0
- package/client/components/sidebar/transfer-list.jsx +1 -1
- package/client/components/spice/spice-session.jsx +4 -5
- package/client/components/tabs/no-session.jsx +1 -1
- package/client/components/tabs/no-session.styl +31 -8
- package/client/components/terminal/shortcut-bar-defs.js +131 -0
- package/client/components/terminal/shortcut-bar-edit.jsx +205 -0
- package/client/components/terminal/shortcut-bar-entry.jsx +34 -0
- package/client/components/terminal/shortcut-bar.jsx +150 -0
- package/client/components/terminal/shortcut-bar.styl +186 -0
- package/client/components/terminal/terminal-color-query.mjs +47 -0
- package/client/components/terminal/terminal.jsx +39 -1
- package/client/components/terminal/terminal.styl +8 -0
- package/client/components/terminal-info/base.jsx +5 -7
- package/client/components/widgets/widget-form.jsx +3 -2
- package/client/css/mobile.styl +18 -6
- package/client/store/init-state.js +3 -0
- package/client/store/mcp-handler.js +29 -1
- package/package.json +1 -1
|
@@ -79,6 +79,8 @@ export const authTypeMap = buildConst([
|
|
|
79
79
|
|
|
80
80
|
export const footerHeight = 36
|
|
81
81
|
export const quickCommandBoxHeight = 180
|
|
82
|
+
export const shortcutBarHeight = 44
|
|
83
|
+
export const shortcutBarLsKey = 'shortcut-bar-buttons'
|
|
82
84
|
export const isWin = typeof window.et.isWin === 'undefined' ? window.pre.isWin : window.et.isWin
|
|
83
85
|
export const isMac = typeof window.et.isMac === 'undefined' ? window.pre.isMac : window.et.isMac
|
|
84
86
|
export const isMacJs = /Macintosh|Mac|Mac OS|MacIntel|MacPPC|Mac68K/gi.test(window.navigator.userAgent)
|
|
@@ -79,5 +79,14 @@ export default {
|
|
|
79
79
|
allowMultiInstance: false,
|
|
80
80
|
disableDeveloperTool: false,
|
|
81
81
|
dragDropBehavior: 'ask',
|
|
82
|
-
switchTabOnHover: false
|
|
82
|
+
switchTabOnHover: false,
|
|
83
|
+
leftSideBarIcons: [
|
|
84
|
+
'newBookmark',
|
|
85
|
+
'quickConnect',
|
|
86
|
+
'bookmarks',
|
|
87
|
+
'terminalThemes',
|
|
88
|
+
'setting',
|
|
89
|
+
'settingSync',
|
|
90
|
+
'widgets'
|
|
91
|
+
]
|
|
83
92
|
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* customizable icons for the far-left sidebar.
|
|
3
|
+
*
|
|
4
|
+
* `text` is a locale key passed to window.translate. The "about",
|
|
5
|
+
* "hide sidebar" and "file transfer" icons are intentionally excluded —
|
|
6
|
+
* they are always visible / conditionally rendered and not part of the
|
|
7
|
+
* customizable set.
|
|
8
|
+
*
|
|
9
|
+
* order of `leftSidebarIconOptions` is the default order shown in the sidebar.
|
|
10
|
+
*/
|
|
11
|
+
export const leftSidebarIconOptions = [
|
|
12
|
+
{ id: 'newBookmark', text: 'newBookmark' },
|
|
13
|
+
{ id: 'quickConnect', text: 'quickConnect' },
|
|
14
|
+
{ id: 'bookmarks', text: 'bookmarks' },
|
|
15
|
+
{ id: 'terminalThemes', text: 'terminalThemes' },
|
|
16
|
+
{ id: 'setting', text: 'setting' },
|
|
17
|
+
{ id: 'settingSync', text: 'settingSync' },
|
|
18
|
+
{ id: 'widgets', text: 'widgets' }
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
// default ordered list of icon ids — mirrors the order above
|
|
22
|
+
export const defaultLeftSideBarIcons = leftSidebarIconOptions.map(o => o.id)
|
|
23
|
+
|
|
24
|
+
// valid ids, for sanitizing persisted/synced config
|
|
25
|
+
export const leftSidebarIconIds = new Set(leftSidebarIconOptions.map(o => o.id))
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* returns a clean, ordered list of icon ids from a possibly-untrusted value:
|
|
29
|
+
* unknown ids dropped, missing default ids left to the user's choice.
|
|
30
|
+
*/
|
|
31
|
+
export function normalizeLeftSideBarIcons (value) {
|
|
32
|
+
if (!Array.isArray(value)) {
|
|
33
|
+
return [...defaultLeftSideBarIcons]
|
|
34
|
+
}
|
|
35
|
+
return value.filter(id => leftSidebarIconIds.has(id))
|
|
36
|
+
}
|
|
@@ -19,6 +19,14 @@ export const defaultAIPresets = [
|
|
|
19
19
|
modelAI: 'deepseek-ai/deepseek-v4-flash',
|
|
20
20
|
authHeaderNameAI: 'Authorization: Bearer'
|
|
21
21
|
},
|
|
22
|
+
{
|
|
23
|
+
id: 'ApiSmart',
|
|
24
|
+
nameAI: 'ApiSmart',
|
|
25
|
+
baseURLAI: 'https://api.apismart.ai/v1',
|
|
26
|
+
apiPathAI: '/chat/completions',
|
|
27
|
+
modelAI: 'DEEPSEEK_V4_FLASH',
|
|
28
|
+
authHeaderNameAI: 'Authorization: Bearer'
|
|
29
|
+
},
|
|
22
30
|
{
|
|
23
31
|
id: 'deepseek',
|
|
24
32
|
nameAI: 'DeepSeek',
|
|
@@ -3,9 +3,10 @@
|
|
|
3
3
|
* Maps field types to React components
|
|
4
4
|
*/
|
|
5
5
|
import React from 'react'
|
|
6
|
-
import { Form, Input, InputNumber,
|
|
6
|
+
import { Form, Input, InputNumber, Select, AutoComplete, Alert, Radio } from 'antd'
|
|
7
7
|
import { ColorPickerItem } from './color-picker-item.jsx'
|
|
8
8
|
import Password from '../../common/password.jsx'
|
|
9
|
+
import SwitchLabel from '../../common/switch.jsx'
|
|
9
10
|
import InputAutoFocus from '../../common/input-auto-focus.jsx'
|
|
10
11
|
import ProxyField from './proxy.jsx'
|
|
11
12
|
import X11Field from './x11.jsx'
|
|
@@ -66,7 +67,7 @@ export function renderFormItem (item, formItemLayout, form, ctxProps, index) {
|
|
|
66
67
|
control = <InputNumber min={1} max={65535} step={1} {...item.props} />
|
|
67
68
|
break
|
|
68
69
|
case 'switch':
|
|
69
|
-
control = <
|
|
70
|
+
control = <SwitchLabel {...item.props} />
|
|
70
71
|
break
|
|
71
72
|
case 'select':
|
|
72
73
|
control = <Select options={item.options} {...item.props} />
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
|
-
import { Form, Input,
|
|
2
|
+
import { Form, Input, Space } from 'antd'
|
|
3
|
+
import SwitchLabel from '../../common/switch'
|
|
3
4
|
import HelpIcon from '../../common/help-icon'
|
|
4
5
|
import { formItemLayout } from '../../../common/form-layout'
|
|
5
6
|
|
|
@@ -18,7 +19,7 @@ export default function SshAgent () {
|
|
|
18
19
|
valuePropName='checked'
|
|
19
20
|
noStyle
|
|
20
21
|
>
|
|
21
|
-
<
|
|
22
|
+
<SwitchLabel />
|
|
22
23
|
</FormItem>
|
|
23
24
|
<FormItem
|
|
24
25
|
name='sshAgent'
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
* bookmark form
|
|
3
3
|
*/
|
|
4
4
|
import {
|
|
5
|
-
Switch,
|
|
6
5
|
Form,
|
|
7
6
|
Button,
|
|
8
7
|
Select
|
|
9
8
|
} from 'antd'
|
|
9
|
+
import SwitchLabel from '../../common/switch'
|
|
10
10
|
import { formItemLayout } from '../../../common/form-layout'
|
|
11
11
|
|
|
12
12
|
const FormItem = Form.Item
|
|
@@ -153,7 +153,7 @@ export default function renderX11 ({ form }) {
|
|
|
153
153
|
name='x11'
|
|
154
154
|
valuePropName='checked'
|
|
155
155
|
>
|
|
156
|
-
<
|
|
156
|
+
<SwitchLabel />
|
|
157
157
|
</FormItem>
|
|
158
158
|
</>
|
|
159
159
|
)
|
|
@@ -9,7 +9,7 @@ import './logo.styl'
|
|
|
9
9
|
|
|
10
10
|
export default function LogoElem () {
|
|
11
11
|
return (
|
|
12
|
-
<h1 className='mg3y font50'>
|
|
12
|
+
<h1 className='logo-elem mg3y font50'>
|
|
13
13
|
<span className='iblock pd3 morph-shape mg1l mg1r'>
|
|
14
14
|
<img src={logoPath2} className='iblock mwm-100 mg1l mg1r logo-filter logo-img' />
|
|
15
15
|
</span>
|
|
@@ -3,8 +3,14 @@
|
|
|
3
3
|
.logo-img-small
|
|
4
4
|
height 28px
|
|
5
5
|
border-radius 28px
|
|
6
|
-
|
|
6
|
+
// the h1 vertical margin so the logo stops dominating the no-session panel.
|
|
7
|
+
.is-mobile
|
|
8
|
+
.logo-elem
|
|
9
|
+
margin-top 8px
|
|
10
|
+
margin-bottom 8px
|
|
11
|
+
.morph-shape
|
|
12
|
+
padding 6px
|
|
7
13
|
.logo-img
|
|
8
|
-
height
|
|
14
|
+
height 32px
|
|
9
15
|
.logo-img-small
|
|
10
16
|
height 20px
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* antd Switch wrapper.
|
|
3
|
+
*
|
|
4
|
+
* `checkedChildren` / `unCheckedChildren` cram the label text inside the
|
|
5
|
+
* toggle, which renders poorly on small / touch screens. This wrapper drops
|
|
6
|
+
* those props and renders an optional text label as a sibling `<span>`
|
|
7
|
+
* instead. Clicking the label toggles the switch by default.
|
|
8
|
+
*
|
|
9
|
+
* Passes every other prop (checked, onChange, size, disabled, ref, ...) through
|
|
10
|
+
* to the underlying antd Switch, so it is a drop-in replacement and is safe
|
|
11
|
+
* inside antd Form.Item (`valuePropName='checked'`).
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { memo } from 'react'
|
|
15
|
+
import { Switch } from 'antd'
|
|
16
|
+
import './switch.styl'
|
|
17
|
+
|
|
18
|
+
function SwitchLabel (props) {
|
|
19
|
+
const {
|
|
20
|
+
label,
|
|
21
|
+
labelPosition = 'after',
|
|
22
|
+
labelClickToggle = true,
|
|
23
|
+
className = '',
|
|
24
|
+
labelClassName = '',
|
|
25
|
+
checked,
|
|
26
|
+
onChange,
|
|
27
|
+
ref,
|
|
28
|
+
...rest
|
|
29
|
+
} = props
|
|
30
|
+
const hasLabel = label !== undefined && label !== null && label !== ''
|
|
31
|
+
const onLabelClick = labelClickToggle && onChange
|
|
32
|
+
? () => onChange(!checked)
|
|
33
|
+
: undefined
|
|
34
|
+
const labelEl = hasLabel
|
|
35
|
+
? (
|
|
36
|
+
<span
|
|
37
|
+
className={
|
|
38
|
+
'switch-label-text' +
|
|
39
|
+
(labelPosition === 'before' ? ' mg1r' : ' mg1l') +
|
|
40
|
+
(labelClickToggle ? ' pointer' : '') +
|
|
41
|
+
(labelClassName ? ' ' + labelClassName : '')
|
|
42
|
+
}
|
|
43
|
+
onClick={onLabelClick}
|
|
44
|
+
>
|
|
45
|
+
{label}
|
|
46
|
+
</span>
|
|
47
|
+
)
|
|
48
|
+
: null
|
|
49
|
+
return (
|
|
50
|
+
<span className={'switch-label-wrap' + (className ? ' ' + className : '')}>
|
|
51
|
+
{labelPosition === 'before' ? labelEl : null}
|
|
52
|
+
<Switch
|
|
53
|
+
checked={checked}
|
|
54
|
+
onChange={onChange}
|
|
55
|
+
ref={ref}
|
|
56
|
+
{...rest}
|
|
57
|
+
/>
|
|
58
|
+
{labelPosition === 'after' ? labelEl : null}
|
|
59
|
+
</span>
|
|
60
|
+
)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export default memo(SwitchLabel)
|
|
@@ -3,8 +3,9 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import { useState, useEffect } from 'react'
|
|
6
|
-
import { Button, Empty, Popover
|
|
6
|
+
import { Button, Empty, Popover } from 'antd'
|
|
7
7
|
import { auto } from 'manate/react'
|
|
8
|
+
import SwitchLabel from '../common/switch'
|
|
8
9
|
import { copy } from '../../common/clipboard'
|
|
9
10
|
import { HistoryOutlined, DeleteOutlined, CopyOutlined, UnorderedListOutlined } from '@ant-design/icons'
|
|
10
11
|
import InputAutoFocus from '../common/input-auto-focus'
|
|
@@ -111,13 +112,14 @@ export default auto(function CmdHistory (props) {
|
|
|
111
112
|
}
|
|
112
113
|
return (
|
|
113
114
|
<div className='cmd-history-header pd2b'>
|
|
114
|
-
<
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
115
|
+
<div className='cmd-history-sort'>
|
|
116
|
+
<SwitchLabel
|
|
117
|
+
checked={sortByFrequency}
|
|
118
|
+
onChange={handleSortByFrequencyChange}
|
|
119
|
+
size='small'
|
|
120
|
+
label={e('sortByFrequency')}
|
|
121
|
+
/>
|
|
122
|
+
</div>
|
|
121
123
|
<UnorderedListOutlined
|
|
122
124
|
className='cmd-history-clear-icon pointer clear-ai-icon icon-hover'
|
|
123
125
|
title={e('clear')}
|
|
@@ -4,7 +4,8 @@ import TabsWrap from '../tabs/index'
|
|
|
4
4
|
import {
|
|
5
5
|
splitConfig,
|
|
6
6
|
quickCommandBoxHeight,
|
|
7
|
-
footerHeight
|
|
7
|
+
footerHeight,
|
|
8
|
+
shortcutBarHeight
|
|
8
9
|
} from '../../common/constants'
|
|
9
10
|
import layoutAlg from './layout-alg'
|
|
10
11
|
import calcSessionSize from './session-size-alg'
|
|
@@ -41,9 +42,10 @@ export default auto(function Layout (props) {
|
|
|
41
42
|
rightPanelPinned,
|
|
42
43
|
rightPanelWidth,
|
|
43
44
|
resizeTrigger,
|
|
44
|
-
inActiveTerminal
|
|
45
|
+
inActiveTerminal,
|
|
46
|
+
shortcutBarVisible
|
|
45
47
|
} = props.store
|
|
46
|
-
const h = height - footerHeight - (inActiveTerminal && pinnedQuickCommandBar ? quickCommandBoxHeight : 0) + resizeTrigger
|
|
48
|
+
const h = height - footerHeight - (inActiveTerminal && pinnedQuickCommandBar ? quickCommandBoxHeight : 0) - (shortcutBarVisible ? shortcutBarHeight : 0) + resizeTrigger
|
|
47
49
|
const l = pinned ? leftSideBarWidth + leftSidePanelWidth : leftSideBarWidth
|
|
48
50
|
const r = rightPanelVisible && rightPanelPinned ? rightPanelWidth : 0
|
|
49
51
|
return {
|
|
@@ -65,14 +67,15 @@ export default auto(function Layout (props) {
|
|
|
65
67
|
rightPanelVisible,
|
|
66
68
|
rightPanelPinned,
|
|
67
69
|
rightPanelWidth,
|
|
68
|
-
pinned
|
|
70
|
+
pinned,
|
|
71
|
+
shortcutBarVisible
|
|
69
72
|
} = props.store
|
|
70
73
|
const l = pinned ? leftSidePanelWidth : 0
|
|
71
74
|
const r = rightPanelPinned && rightPanelVisible ? rightPanelWidth : 0
|
|
72
75
|
// account for the far-left icon bar (sidebarWidth - 1px border on desktop;
|
|
73
76
|
// 0 when the bar is hidden on mobile)
|
|
74
77
|
const w = width - l - r - (leftSideBarWidth > 0 ? leftSideBarWidth - 1 : 0)
|
|
75
|
-
const h = height - footerHeight - (pinnedQuickCommandBar ? quickCommandBoxHeight : 0)
|
|
78
|
+
const h = height - footerHeight - (pinnedQuickCommandBar ? quickCommandBoxHeight : 0) - (shortcutBarVisible ? shortcutBarHeight : 0)
|
|
76
79
|
return layoutAlg(layout, w, h)
|
|
77
80
|
}
|
|
78
81
|
const layoutSize = calcLayoutStyle()
|
|
@@ -42,6 +42,7 @@ import { pick } from 'lodash-es'
|
|
|
42
42
|
import deepCopy from 'json-deep-copy'
|
|
43
43
|
import './wrapper.styl'
|
|
44
44
|
import TerminalInfo from '../terminal-info/terminal-info-entry'
|
|
45
|
+
import ShortcutBarEntry from '../terminal/shortcut-bar-entry'
|
|
45
46
|
import '../../common/fs.js'
|
|
46
47
|
import './term-fullscreen.styl'
|
|
47
48
|
|
|
@@ -99,7 +100,8 @@ export default auto(function Index (props) {
|
|
|
99
100
|
transferToConfirm,
|
|
100
101
|
openResolutionEdit,
|
|
101
102
|
rightPanelTitle,
|
|
102
|
-
rightPanelTab
|
|
103
|
+
rightPanelTab,
|
|
104
|
+
widgetInstances
|
|
103
105
|
} = store
|
|
104
106
|
const upgradeInfo = deepCopy(store.upgradeInfo)
|
|
105
107
|
const cls = classnames({
|
|
@@ -181,7 +183,9 @@ export default auto(function Index (props) {
|
|
|
181
183
|
fileTransfers: copiedTransfer,
|
|
182
184
|
transferHistory: copiedHistory,
|
|
183
185
|
upgradeInfo,
|
|
184
|
-
pinned
|
|
186
|
+
pinned,
|
|
187
|
+
leftSideBarIcons: config.leftSideBarIcons,
|
|
188
|
+
widgetInstancesLength: widgetInstances.length
|
|
185
189
|
}
|
|
186
190
|
|
|
187
191
|
const infoModalProps = {
|
|
@@ -311,6 +315,7 @@ export default auto(function Index (props) {
|
|
|
311
315
|
<BookmarkFromHistoryModal />
|
|
312
316
|
<NotificationContainer />
|
|
313
317
|
<BatchOpRunner />
|
|
318
|
+
<ShortcutBarEntry store={store} />
|
|
314
319
|
{!isAIDisabled() && <AIConfigModal store={store} />}
|
|
315
320
|
<UnixTimestampTooltip />
|
|
316
321
|
</div>
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { useState } from 'react'
|
|
2
2
|
import {
|
|
3
3
|
Form,
|
|
4
|
-
Switch,
|
|
5
4
|
Button
|
|
6
5
|
} from 'antd'
|
|
7
6
|
import message from '../common/message'
|
|
7
|
+
import SwitchLabel from '../common/switch'
|
|
8
8
|
import InputAutoFocus from '../common/input-auto-focus'
|
|
9
9
|
import { formItemLayout } from '../../common/form-layout'
|
|
10
10
|
import HelpIcon from '../common/help-icon'
|
|
@@ -90,7 +90,7 @@ export default function ProfileFormElem (props) {
|
|
|
90
90
|
name='isDefault'
|
|
91
91
|
valuePropName='checked'
|
|
92
92
|
>
|
|
93
|
-
<
|
|
93
|
+
<SwitchLabel />
|
|
94
94
|
</FormItem>
|
|
95
95
|
<ProfileTabs {...tabsProps} />
|
|
96
96
|
<FormItem>
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* quick commands footer selection wrap
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import { useState
|
|
5
|
+
import { useState } from 'react'
|
|
6
6
|
import { quickCommandLabelsLsKey, pinnedQuickCommandBarKey } from '../../common/constants'
|
|
7
7
|
import { sortBy } from 'lodash-es'
|
|
8
8
|
import { Button, Input, Select, Space, Flex } from 'antd'
|
|
@@ -25,21 +25,6 @@ const { Option } = Select
|
|
|
25
25
|
export default function QuickCommandsFooterBox (props) {
|
|
26
26
|
const [keyword, setKeyword] = useState('')
|
|
27
27
|
const [label, setLabel] = useState(ls.getItem(quickCommandLabelsLsKey, ''))
|
|
28
|
-
const timer = useRef(null)
|
|
29
|
-
|
|
30
|
-
function handleMouseLeave () {
|
|
31
|
-
timer.current = setTimeout(() => {
|
|
32
|
-
toggle(false)
|
|
33
|
-
}, 500)
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
function handleMouseEnter () {
|
|
37
|
-
clearTimeout(timer.current)
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
function toggle (openQuickCommandBar) {
|
|
41
|
-
window.store.openQuickCommandBar = openQuickCommandBar
|
|
42
|
-
}
|
|
43
28
|
|
|
44
29
|
function handleTogglePinned () {
|
|
45
30
|
const current = !window.store.pinnedQuickCommandBar
|
|
@@ -209,9 +194,7 @@ export default function QuickCommandsFooterBox (props) {
|
|
|
209
194
|
className: 'qm-wrap-tooltip',
|
|
210
195
|
style: {
|
|
211
196
|
left: w
|
|
212
|
-
}
|
|
213
|
-
onMouseLeave: handleMouseLeave,
|
|
214
|
-
onMouseEnter: handleMouseEnter
|
|
197
|
+
}
|
|
215
198
|
}
|
|
216
199
|
return (
|
|
217
200
|
<div
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Button,
|
|
3
|
-
Switch,
|
|
4
3
|
Form,
|
|
5
4
|
Select,
|
|
6
5
|
Input
|
|
7
6
|
} from 'antd'
|
|
8
7
|
import message from '../common/message'
|
|
8
|
+
import SwitchLabel from '../common/switch'
|
|
9
9
|
import { useState } from 'react'
|
|
10
10
|
import generate from '../../common/uid'
|
|
11
11
|
import InputAutoFocus from '../common/input-auto-focus'
|
|
@@ -162,7 +162,7 @@ export default function QuickCommandForm (props) {
|
|
|
162
162
|
name='inputOnly'
|
|
163
163
|
valuePropName='checked'
|
|
164
164
|
>
|
|
165
|
-
<
|
|
165
|
+
<SwitchLabel />
|
|
166
166
|
</FormItem>
|
|
167
167
|
<FormItem>
|
|
168
168
|
<p>
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* quick commands footer selection
|
|
3
|
+
*
|
|
4
|
+
* Click to toggle the quick-command bar. Click-based so it works identically
|
|
5
|
+
* on touch (mobile) and mouse (desktop) — the old hover-to-open model was
|
|
6
|
+
* unreliable on Android, where a tap synthesizes mouseleave and cancels the
|
|
7
|
+
* open timer.
|
|
3
8
|
*/
|
|
4
9
|
|
|
5
10
|
import { PureComponent } from 'react'
|
|
@@ -7,33 +12,18 @@ import { Button } from 'antd'
|
|
|
7
12
|
import './qm.styl'
|
|
8
13
|
|
|
9
14
|
export default class QuickCommandsFooter extends PureComponent {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
handleOpen = () => {
|
|
16
|
-
this.timer = setTimeout(this.act, 500)
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
act = () => {
|
|
20
|
-
window.store.openQuickCommandBar = true
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
handleMouseLeave = () => {
|
|
24
|
-
clearTimeout(this.timer)
|
|
15
|
+
handleClick = () => {
|
|
16
|
+
const { store } = window
|
|
17
|
+
store.openQuickCommandBar = !store.openQuickCommandBar
|
|
25
18
|
}
|
|
26
19
|
|
|
27
20
|
render () {
|
|
28
21
|
return (
|
|
29
|
-
<div
|
|
30
|
-
className='fleft relative quick-command-trigger-wrap'
|
|
31
|
-
onMouseEnter={this.handleOpen}
|
|
32
|
-
onMouseLeave={this.handleMouseLeave}
|
|
33
|
-
>
|
|
22
|
+
<div className='fleft relative quick-command-trigger-wrap'>
|
|
34
23
|
<Button
|
|
35
24
|
size='small'
|
|
36
25
|
type='text'
|
|
26
|
+
onClick={this.handleClick}
|
|
37
27
|
>
|
|
38
28
|
Q
|
|
39
29
|
</Button>
|
|
@@ -15,7 +15,6 @@ import {
|
|
|
15
15
|
import {
|
|
16
16
|
Spin,
|
|
17
17
|
Select,
|
|
18
|
-
Switch,
|
|
19
18
|
Tooltip
|
|
20
19
|
} from 'antd'
|
|
21
20
|
import * as ls from '../../common/safe-local-storage'
|
|
@@ -23,6 +22,7 @@ import scanCode from './code-scan'
|
|
|
23
22
|
import resolutions from './resolutions'
|
|
24
23
|
import { readClipboardAsync } from '../../common/clipboard'
|
|
25
24
|
import RemoteFloatControl from '../common/remote-float-control'
|
|
25
|
+
import SwitchLabel from '../common/switch'
|
|
26
26
|
import HelpIcon from '../common/help-icon'
|
|
27
27
|
import { FileTransferManager, createFileLogger } from './file-transfer'
|
|
28
28
|
import { notification } from '../common/notification'
|
|
@@ -634,8 +634,7 @@ export default class RdpSession extends PureComponent {
|
|
|
634
634
|
const scaleProps = {
|
|
635
635
|
checked: this.state.scaleViewport,
|
|
636
636
|
onChange: this.handleScaleViewChange,
|
|
637
|
-
|
|
638
|
-
checkedChildren: window.translate('scaleViewport'),
|
|
637
|
+
label: window.translate('scaleViewport'),
|
|
639
638
|
className: 'mg1l'
|
|
640
639
|
}
|
|
641
640
|
const uploadTitle = window.translate('upload') || 'Upload files to remote'
|
|
@@ -671,7 +670,7 @@ export default class RdpSession extends PureComponent {
|
|
|
671
670
|
className='mg2r mg1l pointer'
|
|
672
671
|
/>
|
|
673
672
|
{this.renderInfo()}
|
|
674
|
-
<
|
|
673
|
+
<SwitchLabel
|
|
675
674
|
{...scaleProps}
|
|
676
675
|
/>
|
|
677
676
|
<Tooltip title={uploadTitle}>
|
|
@@ -7,9 +7,9 @@ import {
|
|
|
7
7
|
} from '@ant-design/icons'
|
|
8
8
|
import message from '../common/message'
|
|
9
9
|
import { notification } from '../common/notification'
|
|
10
|
+
import SwitchLabel from '../common/switch'
|
|
10
11
|
import {
|
|
11
12
|
Select,
|
|
12
|
-
Switch,
|
|
13
13
|
Button,
|
|
14
14
|
Table,
|
|
15
15
|
Space,
|
|
@@ -34,6 +34,7 @@ import delay from '../../common/wait.js'
|
|
|
34
34
|
import isColorDark from '../../common/is-color-dark'
|
|
35
35
|
import DeepLinkControl from './deep-link-control'
|
|
36
36
|
import HotkeySetting from './hotkey'
|
|
37
|
+
import SettingLeftSidebarIcons from './setting-left-sidebar-icons'
|
|
37
38
|
import './setting.styl'
|
|
38
39
|
|
|
39
40
|
const { Option } = Select
|
|
@@ -192,10 +193,9 @@ export default class SettingCommon extends Component {
|
|
|
192
193
|
const checked = !!this.props.config[name]
|
|
193
194
|
return (
|
|
194
195
|
<div className='pd2b' key={'rt' + name}>
|
|
195
|
-
<
|
|
196
|
+
<SwitchLabel
|
|
196
197
|
checked={checked}
|
|
197
|
-
|
|
198
|
-
unCheckedChildren={e(name)}
|
|
198
|
+
label={e(name)}
|
|
199
199
|
onChange={v => this.onChangeValue(v, name)}
|
|
200
200
|
/>
|
|
201
201
|
{isNumber(extra) ? null : extra}
|
|
@@ -372,7 +372,7 @@ export default class SettingCommon extends Component {
|
|
|
372
372
|
style={{ body: { style } }}
|
|
373
373
|
/>
|
|
374
374
|
</span>
|
|
375
|
-
<
|
|
375
|
+
<SwitchLabel
|
|
376
376
|
checked={enableGlobalProxy}
|
|
377
377
|
onChange={v => {
|
|
378
378
|
this.onChangeValue(v, 'enableGlobalProxy')
|
|
@@ -471,6 +471,10 @@ export default class SettingCommon extends Component {
|
|
|
471
471
|
return (
|
|
472
472
|
<div className='form-wrap pd1y pd2x'>
|
|
473
473
|
<h2>{e('settings')}</h2>
|
|
474
|
+
<SettingLeftSidebarIcons
|
|
475
|
+
config={props.config}
|
|
476
|
+
store={props.store}
|
|
477
|
+
/>
|
|
474
478
|
<HotkeySetting
|
|
475
479
|
{...hotkeyProps}
|
|
476
480
|
/>
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* editor (embedded in the common settings page) for the customizable
|
|
3
|
+
* far-left sidebar icons. The select takes effect immediately — order of the
|
|
4
|
+
* selected ids is the order shown in the sidebar.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { Select } from 'antd'
|
|
8
|
+
import {
|
|
9
|
+
leftSidebarIconOptions,
|
|
10
|
+
defaultLeftSideBarIcons
|
|
11
|
+
} from '../../common/left-sidebar-icon-defs'
|
|
12
|
+
|
|
13
|
+
const { Option } = Select
|
|
14
|
+
const e = window.translate
|
|
15
|
+
|
|
16
|
+
export default function SettingLeftSidebarIcons (props) {
|
|
17
|
+
const { config, store } = props
|
|
18
|
+
const value = Array.isArray(config.leftSideBarIcons) && config.leftSideBarIcons.length
|
|
19
|
+
? config.leftSideBarIcons
|
|
20
|
+
: [...defaultLeftSideBarIcons]
|
|
21
|
+
|
|
22
|
+
const handleChange = (v) => {
|
|
23
|
+
store.updateConfig({
|
|
24
|
+
leftSideBarIcons: v
|
|
25
|
+
})
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return (
|
|
29
|
+
<div className='pd2b'>
|
|
30
|
+
<div className='pd1b'>{e('leftSideBarIcons')}</div>
|
|
31
|
+
<Select
|
|
32
|
+
mode='multiple'
|
|
33
|
+
value={value}
|
|
34
|
+
onChange={handleChange}
|
|
35
|
+
popupMatchSelectWidth={false}
|
|
36
|
+
style={{ minWidth: 320, width: '100%' }}
|
|
37
|
+
placeholder={e('leftSideBarIcons')}
|
|
38
|
+
>
|
|
39
|
+
{
|
|
40
|
+
leftSidebarIconOptions.map(opt => {
|
|
41
|
+
return (
|
|
42
|
+
<Option
|
|
43
|
+
key={opt.id}
|
|
44
|
+
value={opt.id}
|
|
45
|
+
>
|
|
46
|
+
{e(opt.text)}
|
|
47
|
+
</Option>
|
|
48
|
+
)
|
|
49
|
+
})
|
|
50
|
+
}
|
|
51
|
+
</Select>
|
|
52
|
+
</div>
|
|
53
|
+
)
|
|
54
|
+
}
|
|
@@ -4,9 +4,9 @@ import {
|
|
|
4
4
|
LoadingOutlined
|
|
5
5
|
} from '@ant-design/icons'
|
|
6
6
|
import message from '../common/message'
|
|
7
|
+
import SwitchLabel from '../common/switch'
|
|
7
8
|
import {
|
|
8
9
|
Select,
|
|
9
|
-
Switch,
|
|
10
10
|
Button,
|
|
11
11
|
AutoComplete,
|
|
12
12
|
Tooltip,
|
|
@@ -123,10 +123,9 @@ export default class SettingTerminal extends Component {
|
|
|
123
123
|
const txt = label || e(name)
|
|
124
124
|
return (
|
|
125
125
|
<div className={cls} key={'rt' + name}>
|
|
126
|
-
<
|
|
126
|
+
<SwitchLabel
|
|
127
127
|
checked={checked}
|
|
128
|
-
|
|
129
|
-
unCheckedChildren={txt}
|
|
128
|
+
label={txt}
|
|
130
129
|
onChange={v => this.onChangeValue(v, name)}
|
|
131
130
|
/>
|
|
132
131
|
</div>
|