@electerm/electerm-react 2.3.36 → 2.3.58
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 +0 -37
- package/client/common/terminal-theme.js +8 -13
- package/client/common/theme-defaults.js +120 -0
- package/client/components/common/ref.js +35 -0
- package/client/components/file-transfer/transfer.styl +9 -4
- package/client/components/sidebar/index.jsx +25 -25
- package/client/components/sidebar/sidebar-panel.jsx +20 -3
- package/client/components/tabs/add-btn.jsx +62 -108
- package/client/components/tabs/add-btn.styl +2 -1
- package/client/components/tabs/tab.jsx +3 -12
- package/client/components/tabs/tabs.styl +3 -3
- package/client/components/text-editor/simple-editor.jsx +8 -1
- package/client/components/theme/theme-form.jsx +9 -3
- package/client/components/theme/theme-list-item.jsx +3 -3
- package/client/components/theme/theme-list.jsx +3 -2
- package/client/store/common.js +4 -0
- package/client/store/init-state.js +1 -4
- package/client/store/load-data.js +0 -1
- package/client/store/sidebar.js +0 -4
- package/client/store/store.js +2 -2
- package/client/store/tab.js +2 -2
- package/client/store/terminal-theme.js +21 -43
- package/client/store/ui-theme.js +5 -2
- package/package.json +1 -1
- package/client/common/db-defaults.js +0 -123
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* constants
|
|
3
3
|
*/
|
|
4
|
-
import { getUiThemeConfig } from './ui-theme'
|
|
5
4
|
import logoPath1Ref from '@electerm/electerm-resource/res/imgs/electerm-round-128x128.png'
|
|
6
5
|
import logoPath2Ref from '@electerm/electerm-resource/res/imgs/electerm.png'
|
|
7
6
|
import logoPath3Ref from '@electerm/electerm-resource/res/imgs/electerm-watermark.png'
|
|
8
|
-
import dbDefaults from './db-defaults'
|
|
9
|
-
import { get as _get } from 'lodash-es'
|
|
10
7
|
export const packInfo = typeof window.et.packInfo === 'undefined' ? window.pre.packInfo : window.et.packInfo
|
|
11
8
|
const buildConst = (props) => {
|
|
12
9
|
return props.reduce((prev, key) => {
|
|
@@ -150,35 +147,6 @@ export const leftSidebarWidthKey = 'left-sidebar-width'
|
|
|
150
147
|
export const rightSidebarWidthKey = 'right-sidebar-width'
|
|
151
148
|
export const sftpDefaultSortSettingKey = 'sftp-default-sort'
|
|
152
149
|
export const qmSortByFrequencyKey = 'qm-sort-by-frequency'
|
|
153
|
-
// https://github.com/tinkertrain/panda-syntax-vscode/blob/master/themes/workbench.yaml
|
|
154
|
-
export const defaultTheme = {
|
|
155
|
-
id: 'default',
|
|
156
|
-
name: 'default',
|
|
157
|
-
themeConfig: {
|
|
158
|
-
foreground: '#bbbbbb',
|
|
159
|
-
background: '#141314',
|
|
160
|
-
cursor: '#b5bd68',
|
|
161
|
-
cursorAccent: '#1d1f21',
|
|
162
|
-
selectionBackground: 'rgba(255, 255, 255, 0.3)',
|
|
163
|
-
black: '#575757',
|
|
164
|
-
red: '#FF2C6D',
|
|
165
|
-
green: '#19f9d8',
|
|
166
|
-
yellow: '#FFB86C',
|
|
167
|
-
blue: '#45A9F9',
|
|
168
|
-
magenta: '#FF75B5',
|
|
169
|
-
cyan: '#B084EB',
|
|
170
|
-
white: '#CDCDCD',
|
|
171
|
-
brightBlack: '#757575',
|
|
172
|
-
brightRed: '#FF2C6D',
|
|
173
|
-
brightGreen: '#19f9d8',
|
|
174
|
-
brightYellow: '#FFCC95',
|
|
175
|
-
brightBlue: '#6FC1FF',
|
|
176
|
-
brightMagenta: '#FF9AC1',
|
|
177
|
-
brightCyan: '#BCAAFE',
|
|
178
|
-
brightWhite: '#E6E6E6'
|
|
179
|
-
},
|
|
180
|
-
uiThemeConfig: getUiThemeConfig()
|
|
181
|
-
}
|
|
182
150
|
|
|
183
151
|
export const commonBaudRates = [
|
|
184
152
|
110,
|
|
@@ -230,11 +198,6 @@ export const settingShortcutsId = 'setting-shortcuts'
|
|
|
230
198
|
export const settingAiId = 'setting-ai'
|
|
231
199
|
export const settingCommonId = 'setting-common'
|
|
232
200
|
export const defaultEnvLang = 'en_US.UTF-8'
|
|
233
|
-
const defaultThemeLightConf = _get(
|
|
234
|
-
dbDefaults, '[0].data[1]'
|
|
235
|
-
)
|
|
236
|
-
defaultThemeLightConf.id = defaultThemeLightConf._id
|
|
237
|
-
export const defaultThemeLight = defaultThemeLightConf
|
|
238
201
|
export const fileActions = {
|
|
239
202
|
cancel: 'cancel',
|
|
240
203
|
skip: 'skip',
|
|
@@ -2,9 +2,12 @@
|
|
|
2
2
|
* theme control
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { settingMap } from '../common/constants'
|
|
6
6
|
import download from '../common/download'
|
|
7
|
-
import
|
|
7
|
+
import {
|
|
8
|
+
defaultTheme
|
|
9
|
+
} from './theme-defaults'
|
|
10
|
+
|
|
8
11
|
const e = window.translate
|
|
9
12
|
const terminalPrefix = 'terminal:'
|
|
10
13
|
export const requiredThemeProps = [
|
|
@@ -46,21 +49,13 @@ export const validThemeProps = [
|
|
|
46
49
|
...requiredThemeProps,
|
|
47
50
|
'name'
|
|
48
51
|
]
|
|
49
|
-
/**
|
|
50
|
-
* build default themes
|
|
51
|
-
*/
|
|
52
|
-
export const buildDefaultThemes = () => {
|
|
53
|
-
return {
|
|
54
|
-
[defaultTheme.id]: defaultTheme
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
52
|
|
|
58
53
|
/**
|
|
59
54
|
* build new theme
|
|
60
55
|
*/
|
|
61
|
-
export const buildNewTheme = (theme = defaultTheme) => {
|
|
56
|
+
export const buildNewTheme = (theme = defaultTheme()) => {
|
|
62
57
|
return Object.assign(
|
|
63
|
-
|
|
58
|
+
theme,
|
|
64
59
|
{
|
|
65
60
|
id: '',
|
|
66
61
|
name: e('newTheme')
|
|
@@ -132,7 +127,7 @@ export const convertTheme = (themeTxt) => {
|
|
|
132
127
|
* @return {array} extra keys
|
|
133
128
|
*/
|
|
134
129
|
export const verifyTheme = (themeConfig) => {
|
|
135
|
-
const keysRight = Object.keys(defaultTheme.themeConfig)
|
|
130
|
+
const keysRight = Object.keys(defaultTheme().themeConfig)
|
|
136
131
|
const keys = Object.keys(themeConfig)
|
|
137
132
|
const extraKeys = keys.filter(k => !keysRight.includes(k))
|
|
138
133
|
return extraKeys
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* database default should init
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
function parsor (themeTxt) {
|
|
6
|
+
return themeTxt.split('\n').reduce((prev, line) => {
|
|
7
|
+
let [key = '', value = ''] = line.split('=')
|
|
8
|
+
key = key.trim()
|
|
9
|
+
value = value.trim()
|
|
10
|
+
if (!key || !value) {
|
|
11
|
+
return prev
|
|
12
|
+
}
|
|
13
|
+
prev[key] = value
|
|
14
|
+
return prev
|
|
15
|
+
}, {})
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const defaultThemeDark = () => {
|
|
19
|
+
return parsor(`
|
|
20
|
+
main-dark=#000
|
|
21
|
+
main-light=#2E3338
|
|
22
|
+
text=#ddd
|
|
23
|
+
text-light=#fff
|
|
24
|
+
text-dark=#888
|
|
25
|
+
text-disabled=#777
|
|
26
|
+
primary=#08c
|
|
27
|
+
info=#FFD166
|
|
28
|
+
success=#06D6A0
|
|
29
|
+
error=#EF476F
|
|
30
|
+
warn=#E55934
|
|
31
|
+
main=#121214
|
|
32
|
+
`)
|
|
33
|
+
}
|
|
34
|
+
const defaultThemeLightFunc = () => {
|
|
35
|
+
return parsor(`
|
|
36
|
+
main=#ededed
|
|
37
|
+
main-dark=#cccccc
|
|
38
|
+
main-light=#fefefe
|
|
39
|
+
text=#555
|
|
40
|
+
text-light=#777
|
|
41
|
+
text-dark=#444
|
|
42
|
+
text-disabled=#888
|
|
43
|
+
primary=#08c
|
|
44
|
+
info=#FFD166
|
|
45
|
+
success=#06D6A0
|
|
46
|
+
error=#EF476F
|
|
47
|
+
warn=#E55934
|
|
48
|
+
`)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const defaultThemeLightTerminal = () => {
|
|
52
|
+
return parsor(`
|
|
53
|
+
background=#121214
|
|
54
|
+
foreground=#af9a91
|
|
55
|
+
cursor=#af9a91
|
|
56
|
+
selectionBackground=#575256
|
|
57
|
+
cursorAccent=#121214
|
|
58
|
+
black=#572100
|
|
59
|
+
red=#ba3934
|
|
60
|
+
green=#91773f
|
|
61
|
+
yellow=#b55600
|
|
62
|
+
blue=#5f63b4
|
|
63
|
+
magenta=#a17c7b
|
|
64
|
+
cyan=#8faea9
|
|
65
|
+
white=#af9a91
|
|
66
|
+
brightBlack=#4e4b61
|
|
67
|
+
brightRed=#d9443f
|
|
68
|
+
brightGreen=#d6b04e
|
|
69
|
+
brightYellow=#f66813
|
|
70
|
+
brightBlue=#8086ef
|
|
71
|
+
brightMagenta=#e2c2bb
|
|
72
|
+
brightCyan=#a4dce7
|
|
73
|
+
brightWhite=#d2c7a9
|
|
74
|
+
`
|
|
75
|
+
)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const defaultThemeDarkTerminal = () => {
|
|
79
|
+
return {
|
|
80
|
+
foreground: '#bbbbbb',
|
|
81
|
+
background: '#20111b',
|
|
82
|
+
cursor: '#b5bd68',
|
|
83
|
+
cursorAccent: '#1d1f21',
|
|
84
|
+
selectionBackground: 'rgba(255, 255, 255, 0.3)',
|
|
85
|
+
black: '#575757',
|
|
86
|
+
red: '#FF2C6D',
|
|
87
|
+
green: '#19f9d8',
|
|
88
|
+
yellow: '#FFB86C',
|
|
89
|
+
blue: '#45A9F9',
|
|
90
|
+
magenta: '#FF75B5',
|
|
91
|
+
cyan: '#B084EB',
|
|
92
|
+
white: '#CDCDCD',
|
|
93
|
+
brightBlack: '#757575',
|
|
94
|
+
brightRed: '#FF2C6D',
|
|
95
|
+
brightGreen: '#19f9d8',
|
|
96
|
+
brightYellow: '#FFCC95',
|
|
97
|
+
brightBlue: '#6FC1FF',
|
|
98
|
+
brightMagenta: '#FF9AC1',
|
|
99
|
+
brightCyan: '#BCAAFE',
|
|
100
|
+
brightWhite: '#E6E6E6'
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export function defaultTheme () {
|
|
105
|
+
return {
|
|
106
|
+
id: 'default',
|
|
107
|
+
name: 'default',
|
|
108
|
+
themeConfig: defaultThemeDarkTerminal(),
|
|
109
|
+
uiThemeConfig: defaultThemeDark()
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export function defaultThemeLight () {
|
|
114
|
+
return {
|
|
115
|
+
id: 'defaultLight',
|
|
116
|
+
name: 'default light',
|
|
117
|
+
themeConfig: defaultThemeLightTerminal(),
|
|
118
|
+
uiThemeConfig: defaultThemeLightFunc()
|
|
119
|
+
}
|
|
120
|
+
}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
window.refs = new Map()
|
|
3
3
|
window.refsStatic = new Map()
|
|
4
4
|
window.refsTransfers = new Map()
|
|
5
|
+
window.refsTabs = new Map()
|
|
5
6
|
|
|
6
7
|
class Ref {
|
|
7
8
|
constructor (key) {
|
|
@@ -21,6 +22,40 @@ class Ref {
|
|
|
21
22
|
}
|
|
22
23
|
}
|
|
23
24
|
|
|
25
|
+
class TabsRef extends Ref {
|
|
26
|
+
constructor (key) {
|
|
27
|
+
super(key)
|
|
28
|
+
// Map to track add count for each key: key -> number
|
|
29
|
+
this.addCounts = new Map()
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
add (key, inst) {
|
|
33
|
+
// Increment add count
|
|
34
|
+
const currentCount = this.addCounts.get(key) || 0
|
|
35
|
+
this.addCounts.set(key, currentCount + 1)
|
|
36
|
+
|
|
37
|
+
// Add/update the ref
|
|
38
|
+
window[this.key].set(key, inst)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
remove (key) {
|
|
42
|
+
const currentCount = this.addCounts.get(key) || 0
|
|
43
|
+
|
|
44
|
+
if (currentCount <= 0) {
|
|
45
|
+
return
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const newCount = currentCount - 1
|
|
49
|
+
if (newCount === 0) {
|
|
50
|
+
window[this.key].delete(key)
|
|
51
|
+
this.addCounts.delete(key)
|
|
52
|
+
} else {
|
|
53
|
+
this.addCounts.set(key, newCount)
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
24
58
|
export const refs = new Ref('refs')
|
|
25
59
|
export const refsTransfers = new Ref('refsTransfers')
|
|
26
60
|
export const refsStatic = new Ref('refsStatic')
|
|
61
|
+
export const refsTabs = new TabsRef('refsTabs')
|
|
@@ -33,10 +33,15 @@
|
|
|
33
33
|
display flex
|
|
34
34
|
padding 8px 5px
|
|
35
35
|
&:hover
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
36
|
+
font-weight bold
|
|
37
|
+
.transfer-control-icon
|
|
38
|
+
padding-right 5px
|
|
39
|
+
padding-left 5px
|
|
40
|
+
margin-top -2px
|
|
41
|
+
&:hover
|
|
42
|
+
color var(--primary-contrast)
|
|
43
|
+
background var(--primary)
|
|
44
|
+
border-radius 20px
|
|
40
45
|
|
|
41
46
|
.flex-child + .flex-child
|
|
42
47
|
margin-left 5px
|
|
@@ -8,7 +8,6 @@ import {
|
|
|
8
8
|
UpCircleOutlined,
|
|
9
9
|
BarsOutlined
|
|
10
10
|
} from '@ant-design/icons'
|
|
11
|
-
import { useRef, memo } from 'react'
|
|
12
11
|
import { Tooltip } from 'antd'
|
|
13
12
|
import SideBarPanel from './sidebar-panel'
|
|
14
13
|
import TransferList from './transfer-list'
|
|
@@ -25,9 +24,7 @@ import './sidebar.styl'
|
|
|
25
24
|
|
|
26
25
|
const e = window.translate
|
|
27
26
|
|
|
28
|
-
export default
|
|
29
|
-
const handler = useRef(null)
|
|
30
|
-
|
|
27
|
+
export default function Sidebar (props) {
|
|
31
28
|
const {
|
|
32
29
|
height,
|
|
33
30
|
upgradeInfo,
|
|
@@ -47,27 +44,35 @@ export default memo(function Sidebar (props) {
|
|
|
47
44
|
|
|
48
45
|
const { store } = window
|
|
49
46
|
|
|
50
|
-
const
|
|
51
|
-
if
|
|
52
|
-
|
|
47
|
+
const handleClickOutside = (event) => {
|
|
48
|
+
// Don't close if pinned or has active input
|
|
49
|
+
if (store.pinned || hasActiveInput()) {
|
|
50
|
+
return
|
|
53
51
|
}
|
|
54
52
|
|
|
55
|
-
if
|
|
56
|
-
|
|
53
|
+
// Check if click is outside the sidebar panel
|
|
54
|
+
const sidebarPanel = document.querySelector('.sidebar-panel')
|
|
55
|
+
if (sidebarPanel && !sidebarPanel.contains(event.target)) {
|
|
56
|
+
store.setOpenedSideBar('')
|
|
57
|
+
document.removeEventListener('click', handleClickOutside)
|
|
57
58
|
}
|
|
58
|
-
|
|
59
|
-
handler.current = setTimeout(
|
|
60
|
-
() => store.setOpenedSideBar(''),
|
|
61
|
-
400
|
|
62
|
-
)
|
|
63
59
|
}
|
|
64
60
|
|
|
65
|
-
const
|
|
61
|
+
const handleClickBookmark = () => {
|
|
66
62
|
if (pinned) {
|
|
67
|
-
return
|
|
63
|
+
return
|
|
64
|
+
}
|
|
65
|
+
if (openedSideBar === 'bookmarks') {
|
|
66
|
+
// Remove listener when closing
|
|
67
|
+
document.removeEventListener('click', handleClickOutside)
|
|
68
|
+
store.setOpenedSideBar('')
|
|
69
|
+
} else {
|
|
70
|
+
// Add listener when opening, with slight delay to avoid conflict with this click
|
|
71
|
+
setTimeout(() => {
|
|
72
|
+
document.addEventListener('click', handleClickOutside)
|
|
73
|
+
}, 0)
|
|
74
|
+
store.setOpenedSideBar('bookmarks')
|
|
68
75
|
}
|
|
69
|
-
clearTimeout(handler.current)
|
|
70
|
-
store.setOpenedSideBar('bookmarks')
|
|
71
76
|
}
|
|
72
77
|
|
|
73
78
|
const handleShowUpgrade = () => {
|
|
@@ -80,7 +85,6 @@ export default memo(function Sidebar (props) {
|
|
|
80
85
|
openAbout,
|
|
81
86
|
openSettingSync,
|
|
82
87
|
openTerminalThemes,
|
|
83
|
-
onClickBookmark,
|
|
84
88
|
toggleBatchOp,
|
|
85
89
|
setLeftSidePanelWidth
|
|
86
90
|
} = store
|
|
@@ -137,9 +141,7 @@ export default memo(function Sidebar (props) {
|
|
|
137
141
|
active={bookmarksActive}
|
|
138
142
|
>
|
|
139
143
|
<BookOutlined
|
|
140
|
-
|
|
141
|
-
onMouseLeave={handleMouseLeave}
|
|
142
|
-
onClick={onClickBookmark}
|
|
144
|
+
onClick={handleClickBookmark}
|
|
143
145
|
className='font20 iblock control-icon'
|
|
144
146
|
/>
|
|
145
147
|
</SideIcon>
|
|
@@ -212,10 +214,8 @@ export default memo(function Sidebar (props) {
|
|
|
212
214
|
<SideBarPanel
|
|
213
215
|
pinned={pinned}
|
|
214
216
|
sidebarPanelTab={sidebarPanelTab}
|
|
215
|
-
onMouseEnter={handleMouseEnterBookmark}
|
|
216
|
-
onMouseLeave={handleMouseLeave}
|
|
217
217
|
/>
|
|
218
218
|
</SidePanel>
|
|
219
219
|
</div>
|
|
220
220
|
)
|
|
221
|
-
}
|
|
221
|
+
}
|
|
@@ -5,9 +5,15 @@
|
|
|
5
5
|
import { memo } from 'react'
|
|
6
6
|
import BookmarkWrap from './bookmark'
|
|
7
7
|
import History from './history'
|
|
8
|
-
import { pick } from 'lodash-es'
|
|
9
8
|
import { Tabs, Tooltip } from 'antd'
|
|
10
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
ArrowsAltOutlined,
|
|
11
|
+
EditOutlined,
|
|
12
|
+
PlusCircleOutlined,
|
|
13
|
+
ShrinkOutlined,
|
|
14
|
+
PushpinOutlined,
|
|
15
|
+
UnorderedListOutlined
|
|
16
|
+
} from '@ant-design/icons'
|
|
11
17
|
|
|
12
18
|
const e = window.translate
|
|
13
19
|
|
|
@@ -20,9 +26,21 @@ export default memo(function SidebarPanel (props) {
|
|
|
20
26
|
const prps1 = {
|
|
21
27
|
className: prps.className + (pinned ? ' pinned' : '')
|
|
22
28
|
}
|
|
29
|
+
const props2 = {
|
|
30
|
+
onClick: store.clearHistory,
|
|
31
|
+
className: 'mg2x pointer clear-ai-icon icon-hover'
|
|
32
|
+
}
|
|
33
|
+
const tabBarExtraContent = sidebarPanelTab === 'history'
|
|
34
|
+
? (
|
|
35
|
+
<UnorderedListOutlined
|
|
36
|
+
{...props2}
|
|
37
|
+
/>
|
|
38
|
+
)
|
|
39
|
+
: null
|
|
23
40
|
const tabsProps = {
|
|
24
41
|
activeKey: sidebarPanelTab,
|
|
25
42
|
onChange: store.handleSidebarPanelTab,
|
|
43
|
+
tabBarExtraContent,
|
|
26
44
|
items: [
|
|
27
45
|
{
|
|
28
46
|
key: 'bookmarks',
|
|
@@ -69,7 +87,6 @@ export default memo(function SidebarPanel (props) {
|
|
|
69
87
|
return (
|
|
70
88
|
<div
|
|
71
89
|
className='sidebar-panel bookmarks-panel animate-fast'
|
|
72
|
-
{...pick(props, ['onMouseEnter', 'onMouseLeave'])}
|
|
73
90
|
>
|
|
74
91
|
<div className='sidebar-pin-top'>
|
|
75
92
|
<div className='pd1y pd2t pd2x sidebar-panel-control alignright'>
|
|
@@ -27,7 +27,6 @@ export default class AddBtn extends Component {
|
|
|
27
27
|
}
|
|
28
28
|
this.addBtnRef = React.createRef()
|
|
29
29
|
this.menuRef = React.createRef()
|
|
30
|
-
this.hideTimeout = null
|
|
31
30
|
this.portalContainer = null
|
|
32
31
|
}
|
|
33
32
|
|
|
@@ -40,19 +39,9 @@ export default class AddBtn extends Component {
|
|
|
40
39
|
return this.portalContainer
|
|
41
40
|
}
|
|
42
41
|
|
|
43
|
-
componentDidMount () {
|
|
44
|
-
document.addEventListener('click', this.handleDocumentClick)
|
|
45
|
-
// Listen for dropdown events to prevent menu closing
|
|
46
|
-
document.addEventListener('ant-dropdown-show', this.handleDropdownShow)
|
|
47
|
-
document.addEventListener('ant-dropdown-hide', this.handleDropdownHide)
|
|
48
|
-
}
|
|
49
|
-
|
|
50
42
|
componentWillUnmount () {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
document.removeEventListener('ant-dropdown-hide', this.handleDropdownHide)
|
|
54
|
-
if (this.hideTimeout) {
|
|
55
|
-
clearTimeout(this.hideTimeout)
|
|
43
|
+
if (this.state.open) {
|
|
44
|
+
document.removeEventListener('click', this.handleDocumentClick)
|
|
56
45
|
}
|
|
57
46
|
// Clean up portal container
|
|
58
47
|
if (this.portalContainer) {
|
|
@@ -61,19 +50,15 @@ export default class AddBtn extends Component {
|
|
|
61
50
|
}
|
|
62
51
|
}
|
|
63
52
|
|
|
64
|
-
|
|
65
|
-
//
|
|
66
|
-
if (this.
|
|
67
|
-
|
|
68
|
-
|
|
53
|
+
componentDidUpdate (prevProps, prevState) {
|
|
54
|
+
// Attach or detach document click listener only when menu open state changes
|
|
55
|
+
if (this.state.open && !prevState.open) {
|
|
56
|
+
document.addEventListener('click', this.handleDocumentClick)
|
|
57
|
+
} else if (!this.state.open && prevState.open) {
|
|
58
|
+
document.removeEventListener('click', this.handleDocumentClick)
|
|
69
59
|
}
|
|
70
60
|
}
|
|
71
61
|
|
|
72
|
-
handleDropdownHide = () => {
|
|
73
|
-
// Small delay after dropdown hides before allowing menu to close
|
|
74
|
-
// This prevents flicker when dropdown closes
|
|
75
|
-
}
|
|
76
|
-
|
|
77
62
|
handleDocumentClick = (e) => {
|
|
78
63
|
// Don't close menu when clicking inside menu or add button
|
|
79
64
|
if (this.menuRef.current && this.menuRef.current.contains(e.target)) {
|
|
@@ -91,86 +76,6 @@ export default class AddBtn extends Component {
|
|
|
91
76
|
this.setState({ open: false })
|
|
92
77
|
}
|
|
93
78
|
|
|
94
|
-
handleMouseEnter = () => {
|
|
95
|
-
if (this.hideTimeout) {
|
|
96
|
-
clearTimeout(this.hideTimeout)
|
|
97
|
-
this.hideTimeout = null
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
// Calculate menu position
|
|
101
|
-
if (this.addBtnRef.current) {
|
|
102
|
-
const rect = this.addBtnRef.current.getBoundingClientRect()
|
|
103
|
-
const windowWidth = window.innerWidth
|
|
104
|
-
const windowHeight = window.innerHeight
|
|
105
|
-
|
|
106
|
-
// Estimate menu width and height
|
|
107
|
-
const estimatedMenuWidth = Math.min(300, windowWidth - 40) // Responsive width
|
|
108
|
-
const estimatedMenuHeight = 400 // Rough estimate
|
|
109
|
-
|
|
110
|
-
// Calculate fixed position coordinates
|
|
111
|
-
let menuTop = rect.bottom + 4 // 4px margin
|
|
112
|
-
let menuLeft = rect.left
|
|
113
|
-
let menuPosition = 'right'
|
|
114
|
-
|
|
115
|
-
// Check if menu would overflow bottom of screen
|
|
116
|
-
if (menuTop + estimatedMenuHeight > windowHeight - 20) {
|
|
117
|
-
menuTop = rect.top - estimatedMenuHeight - 4 // Show above button
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
// If aligning right would cause overflow, align left instead
|
|
121
|
-
if (rect.left + estimatedMenuWidth > windowWidth - 20) {
|
|
122
|
-
menuPosition = 'left'
|
|
123
|
-
menuLeft = rect.right - estimatedMenuWidth
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
// If aligning left would cause overflow (negative position), force right
|
|
127
|
-
if (menuLeft < 20) {
|
|
128
|
-
menuPosition = 'right'
|
|
129
|
-
menuLeft = Math.max(20, rect.left) // Ensure at least 20px from edge
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
// Final check to ensure menu doesn't go off screen
|
|
133
|
-
if (menuLeft + estimatedMenuWidth > windowWidth - 20) {
|
|
134
|
-
menuLeft = windowWidth - estimatedMenuWidth - 20
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
this.setState({
|
|
138
|
-
open: true,
|
|
139
|
-
menuPosition,
|
|
140
|
-
menuTop,
|
|
141
|
-
menuLeft
|
|
142
|
-
})
|
|
143
|
-
|
|
144
|
-
if (!this.state.open) {
|
|
145
|
-
window.openTabBatch = this.props.batch
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
handleMouseLeave = () => {
|
|
151
|
-
this.hideTimeout = setTimeout(() => {
|
|
152
|
-
this.setState({ open: false })
|
|
153
|
-
}, 200)
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
handleMenuMouseEnter = () => {
|
|
157
|
-
if (this.hideTimeout) {
|
|
158
|
-
clearTimeout(this.hideTimeout)
|
|
159
|
-
this.hideTimeout = null
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
handleMenuMouseLeave = () => {
|
|
164
|
-
// Don't close if there's an active input or dropdown
|
|
165
|
-
if (hasActiveInput()) {
|
|
166
|
-
return
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
this.hideTimeout = setTimeout(() => {
|
|
170
|
-
this.setState({ open: false })
|
|
171
|
-
}, 200)
|
|
172
|
-
}
|
|
173
|
-
|
|
174
79
|
handleMenuScroll = (e) => {
|
|
175
80
|
// Prevent scroll events from bubbling up
|
|
176
81
|
e.stopPropagation()
|
|
@@ -212,8 +117,6 @@ export default class AddBtn extends Component {
|
|
|
212
117
|
top: menuTop,
|
|
213
118
|
left: menuLeft
|
|
214
119
|
}}
|
|
215
|
-
onMouseEnter={this.handleMenuMouseEnter}
|
|
216
|
-
onMouseLeave={this.handleMenuMouseLeave}
|
|
217
120
|
onScroll={this.handleMenuScroll}
|
|
218
121
|
>
|
|
219
122
|
<div
|
|
@@ -230,6 +133,59 @@ export default class AddBtn extends Component {
|
|
|
230
133
|
)
|
|
231
134
|
}
|
|
232
135
|
|
|
136
|
+
handleAddBtnClick = () => {
|
|
137
|
+
if (this.state.open) {
|
|
138
|
+
this.setState({ open: false })
|
|
139
|
+
} else {
|
|
140
|
+
// Calculate menu position and open the menu
|
|
141
|
+
if (this.addBtnRef.current) {
|
|
142
|
+
const rect = this.addBtnRef.current.getBoundingClientRect()
|
|
143
|
+
const windowWidth = window.innerWidth
|
|
144
|
+
const windowHeight = window.innerHeight
|
|
145
|
+
|
|
146
|
+
// Estimate menu width and height
|
|
147
|
+
const estimatedMenuWidth = Math.min(300, windowWidth - 40) // Responsive width
|
|
148
|
+
const estimatedMenuHeight = 400 // Rough estimate
|
|
149
|
+
|
|
150
|
+
// Calculate fixed position coordinates
|
|
151
|
+
let menuTop = rect.bottom + 4 // 4px margin
|
|
152
|
+
let menuLeft = rect.left
|
|
153
|
+
let menuPosition = 'right'
|
|
154
|
+
|
|
155
|
+
// Check if menu would overflow bottom of screen
|
|
156
|
+
if (menuTop + estimatedMenuHeight > windowHeight - 20) {
|
|
157
|
+
menuTop = rect.top - estimatedMenuHeight - 4 // Show above button
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// If aligning right would cause overflow, align left instead
|
|
161
|
+
if (rect.left + estimatedMenuWidth > windowWidth - 20) {
|
|
162
|
+
menuPosition = 'left'
|
|
163
|
+
menuLeft = rect.right - estimatedMenuWidth
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// If aligning left would cause overflow (negative position), force right
|
|
167
|
+
if (menuLeft < 20) {
|
|
168
|
+
menuPosition = 'right'
|
|
169
|
+
menuLeft = Math.max(20, rect.left) // Ensure at least 20px from edge
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// Final check to ensure menu doesn't go off screen
|
|
173
|
+
if (menuLeft + estimatedMenuWidth > windowWidth - 20) {
|
|
174
|
+
menuLeft = windowWidth - estimatedMenuWidth - 20
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
this.setState({
|
|
178
|
+
open: true,
|
|
179
|
+
menuPosition,
|
|
180
|
+
menuTop,
|
|
181
|
+
menuLeft
|
|
182
|
+
})
|
|
183
|
+
|
|
184
|
+
window.openTabBatch = this.props.batch
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
233
189
|
render () {
|
|
234
190
|
const { empty, className } = this.props
|
|
235
191
|
const { open } = this.state
|
|
@@ -246,9 +202,7 @@ export default class AddBtn extends Component {
|
|
|
246
202
|
<PlusOutlined
|
|
247
203
|
title={e('openNewTerm')}
|
|
248
204
|
className={cls}
|
|
249
|
-
onClick={this.
|
|
250
|
-
onMouseEnter={this.handleMouseEnter}
|
|
251
|
-
onMouseLeave={this.handleMouseLeave}
|
|
205
|
+
onClick={this.handleAddBtnClick}
|
|
252
206
|
ref={this.addBtnRef}
|
|
253
207
|
/>
|
|
254
208
|
{open && createPortal(this.renderMenus(), this.getPortalContainer())}
|
|
@@ -3,8 +3,9 @@
|
|
|
3
3
|
position fixed
|
|
4
4
|
z-index 1000
|
|
5
5
|
background var(--main)
|
|
6
|
-
border 1px solid var(--main-
|
|
6
|
+
border 1px solid var(--main-lighter)
|
|
7
7
|
border-radius 6px
|
|
8
|
+
box-shadow 0 4px 12px rgba(0, 0, 0, 0.3), 0 0 0 1px var(--main-darker)
|
|
8
9
|
min-width 160px
|
|
9
10
|
max-width 300px
|
|
10
11
|
overflow-y auto
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import { createRef } from 'react'
|
|
6
6
|
import { Component } from 'manate/react/class-components'
|
|
7
|
-
import {
|
|
7
|
+
import { refsTabs } from '../common/ref'
|
|
8
8
|
import {
|
|
9
9
|
CloseOutlined,
|
|
10
10
|
Loading3QuartersOutlined,
|
|
@@ -36,22 +36,13 @@ class Tab extends Component {
|
|
|
36
36
|
terminalOnData: false
|
|
37
37
|
}
|
|
38
38
|
this.id = 'tab-' + this.props.tab.id
|
|
39
|
-
|
|
39
|
+
refsTabs.add(this.id, this)
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
tabRef = createRef()
|
|
43
43
|
|
|
44
|
-
componentDidUpdate (prevProps) {
|
|
45
|
-
if (this.props.openContextMenu && !prevProps.openContextMenu) {
|
|
46
|
-
this.handleContextMenu()
|
|
47
|
-
}
|
|
48
|
-
if (this.props.contextFunc && !prevProps.contextFunc) {
|
|
49
|
-
this[this.props.contextFunc](...this.props.contextArgs)
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
44
|
componentWillUnmount () {
|
|
54
|
-
|
|
45
|
+
refsTabs.remove(this.id)
|
|
55
46
|
clearTimeout(this.timer)
|
|
56
47
|
this.timer = null
|
|
57
48
|
}
|
|
@@ -106,16 +106,17 @@
|
|
|
106
106
|
.is-terminal-active .tab-terminal-feed
|
|
107
107
|
display block
|
|
108
108
|
animation blink 2s infinite
|
|
109
|
+
background-color transparent !important
|
|
109
110
|
/* Remove opacity animation, use background-color */
|
|
110
111
|
.tab-terminal-feed
|
|
111
112
|
display none
|
|
112
113
|
left 20px
|
|
113
114
|
border-radius 0
|
|
114
115
|
color var(--success)
|
|
115
|
-
background none
|
|
116
116
|
font-size 8px
|
|
117
117
|
left 2px
|
|
118
118
|
top 24px
|
|
119
|
+
background none
|
|
119
120
|
.tab-close
|
|
120
121
|
position absolute
|
|
121
122
|
right 5px
|
|
@@ -131,8 +132,7 @@
|
|
|
131
132
|
line-height 16px
|
|
132
133
|
font-size 10px
|
|
133
134
|
&:hover
|
|
134
|
-
background var(--
|
|
135
|
-
color var(--primary-contast)
|
|
135
|
+
background var(--error)
|
|
136
136
|
|
|
137
137
|
.tabs-add-btn
|
|
138
138
|
display inline-block
|
|
@@ -84,6 +84,13 @@ export default function SimpleEditor (props) {
|
|
|
84
84
|
e.preventDefault()
|
|
85
85
|
}
|
|
86
86
|
findMatches()
|
|
87
|
+
goToNextMatch()
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function handleChange (e) {
|
|
91
|
+
setSearchKeyword(e.target.value)
|
|
92
|
+
findMatches()
|
|
93
|
+
goToNextMatch()
|
|
87
94
|
}
|
|
88
95
|
|
|
89
96
|
// Navigate to next match
|
|
@@ -144,7 +151,7 @@ export default function SimpleEditor (props) {
|
|
|
144
151
|
<Flex className='mg1b' justify='space-between'>
|
|
145
152
|
<Input.Search
|
|
146
153
|
value={searchKeyword}
|
|
147
|
-
onChange={
|
|
154
|
+
onChange={handleChange}
|
|
148
155
|
placeholder='Search in text...'
|
|
149
156
|
allowClear
|
|
150
157
|
enterButton={<SearchOutlined />}
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import { useRef, useState } from 'react'
|
|
2
2
|
import { Button, Input, message, Upload, Form, Space } from 'antd'
|
|
3
|
-
import {
|
|
4
|
-
|
|
3
|
+
import {
|
|
4
|
+
convertTheme,
|
|
5
|
+
convertThemeToText,
|
|
6
|
+
exportTheme,
|
|
7
|
+
validThemeProps,
|
|
8
|
+
requiredThemeProps
|
|
9
|
+
} from '../../common/terminal-theme'
|
|
10
|
+
import { defaultTheme, defaultThemeLight } from '../../common/theme-defaults'
|
|
5
11
|
import generate from '../../common/uid'
|
|
6
12
|
import Link from '../common/external-link'
|
|
7
13
|
import InputAutoFocus from '../common/input-auto-focus'
|
|
@@ -229,7 +235,7 @@ export default function ThemeForm (props) {
|
|
|
229
235
|
themeName,
|
|
230
236
|
themeText: convertThemeToText(props.formData)
|
|
231
237
|
}
|
|
232
|
-
const isDefaultTheme = id === defaultTheme.id || id === defaultThemeLight.id
|
|
238
|
+
const isDefaultTheme = id === defaultTheme().id || id === defaultThemeLight().id
|
|
233
239
|
const disabled = readonly || isDefaultTheme
|
|
234
240
|
const switchTxt = editor === 'theme-editor-txt' ? e('editWithColorPicker') : e('editWithTextEditor')
|
|
235
241
|
const pickerProps = {
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
} from '@ant-design/icons'
|
|
13
13
|
import { Tag, Tooltip, Button, Space } from 'antd'
|
|
14
14
|
import classnames from 'classnames'
|
|
15
|
-
import { defaultTheme } from '../../common/
|
|
15
|
+
import { defaultTheme } from '../../common/theme-defaults'
|
|
16
16
|
import highlight from '../common/highlight'
|
|
17
17
|
import isColorDark from '../../common/is-color-dark'
|
|
18
18
|
|
|
@@ -138,7 +138,7 @@ export default function ThemeListItem (props) {
|
|
|
138
138
|
active: activeItemId === id
|
|
139
139
|
}
|
|
140
140
|
)
|
|
141
|
-
let title = id === defaultTheme.id
|
|
141
|
+
let title = id === defaultTheme().id
|
|
142
142
|
? e(id)
|
|
143
143
|
: name
|
|
144
144
|
title = highlight(
|
|
@@ -160,7 +160,7 @@ export default function ThemeListItem (props) {
|
|
|
160
160
|
{renderTag()}{title}
|
|
161
161
|
</div>
|
|
162
162
|
{
|
|
163
|
-
id === defaultTheme.id || type === 'iterm'
|
|
163
|
+
id === defaultTheme().id || type === 'iterm'
|
|
164
164
|
? null
|
|
165
165
|
: props.renderDelBtn(item)
|
|
166
166
|
}
|
|
@@ -7,7 +7,8 @@ import { LoadingOutlined, CheckCircleOutlined } from '@ant-design/icons'
|
|
|
7
7
|
import { pick } from 'lodash-es'
|
|
8
8
|
import { Pagination } from 'antd'
|
|
9
9
|
import ThemeListItem from './theme-list-item'
|
|
10
|
-
import {
|
|
10
|
+
import { settingMap } from '../../common/constants'
|
|
11
|
+
import { defaultTheme } from '../../common/theme-defaults'
|
|
11
12
|
import getInitItem from '../../common/init-setting-item'
|
|
12
13
|
import './terminal-theme-list.styl'
|
|
13
14
|
|
|
@@ -48,7 +49,7 @@ export default class ThemeList extends List {
|
|
|
48
49
|
return null
|
|
49
50
|
}
|
|
50
51
|
const { name, id } = item
|
|
51
|
-
const title = id === defaultTheme.id
|
|
52
|
+
const title = id === defaultTheme().id
|
|
52
53
|
? e(id)
|
|
53
54
|
: name
|
|
54
55
|
return (
|
package/client/store/common.js
CHANGED
|
@@ -326,6 +326,10 @@ export default Store => {
|
|
|
326
326
|
return aiConfigsArr.slice(0, -1).some(k => !window.store.config[k])
|
|
327
327
|
}
|
|
328
328
|
|
|
329
|
+
Store.prototype.clearHistory = function () {
|
|
330
|
+
window.store.history = []
|
|
331
|
+
}
|
|
332
|
+
|
|
329
333
|
Store.prototype.addCmdHistory = action(function (cmd) {
|
|
330
334
|
const { terminalCommandHistory } = window.store
|
|
331
335
|
terminalCommandHistory.add(cmd)
|
|
@@ -24,7 +24,6 @@ import {
|
|
|
24
24
|
splitMap,
|
|
25
25
|
cmdHistoryKey
|
|
26
26
|
} from '../common/constants'
|
|
27
|
-
import { buildDefaultThemes } from '../common/terminal-theme'
|
|
28
27
|
import * as ls from '../common/safe-local-storage'
|
|
29
28
|
import { exclude } from 'manate'
|
|
30
29
|
import initSettingItem from '../common/init-setting-item'
|
|
@@ -61,9 +60,7 @@ export default () => {
|
|
|
61
60
|
profiles: [],
|
|
62
61
|
bookmarkGroups: getDefaultBookmarkGroups([]),
|
|
63
62
|
_config: {},
|
|
64
|
-
terminalThemes: [
|
|
65
|
-
buildDefaultThemes()
|
|
66
|
-
],
|
|
63
|
+
terminalThemes: [],
|
|
67
64
|
itermThemes: exclude([]),
|
|
68
65
|
currentBookmarkGroupId: defaultBookmarkGroupId,
|
|
69
66
|
expandedKeys: ls.getItemJSON(expandedKeysLsKey, [
|
package/client/store/sidebar.js
CHANGED
package/client/store/store.js
CHANGED
|
@@ -40,7 +40,7 @@ import createTitle from '../common/create-title'
|
|
|
40
40
|
import {
|
|
41
41
|
theme
|
|
42
42
|
} from 'antd'
|
|
43
|
-
import {
|
|
43
|
+
import { refsTabs } from '../components/common/ref'
|
|
44
44
|
|
|
45
45
|
class Store {
|
|
46
46
|
constructor () {
|
|
@@ -79,7 +79,7 @@ class Store {
|
|
|
79
79
|
const {
|
|
80
80
|
activeTabId
|
|
81
81
|
} = this
|
|
82
|
-
const tab =
|
|
82
|
+
const tab = refsTabs.get('tab-' + activeTabId)
|
|
83
83
|
if (!tab) {
|
|
84
84
|
return null
|
|
85
85
|
}
|
package/client/store/tab.js
CHANGED
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
paneMap,
|
|
10
10
|
maxHistory
|
|
11
11
|
} from '../common/constants'
|
|
12
|
-
import { refs } from '../components/common/ref'
|
|
12
|
+
import { refs, refsTabs } from '../components/common/ref'
|
|
13
13
|
import { message } from 'antd'
|
|
14
14
|
import * as ls from '../common/safe-local-storage'
|
|
15
15
|
import deepCopy from 'json-deep-copy'
|
|
@@ -571,7 +571,7 @@ export default Store => {
|
|
|
571
571
|
})
|
|
572
572
|
|
|
573
573
|
Store.prototype.notifyTabOnData = function (tabId) {
|
|
574
|
-
const tab =
|
|
574
|
+
const tab = refsTabs.get('tab-' + tabId)
|
|
575
575
|
if (tab) {
|
|
576
576
|
tab.notifyOnData()
|
|
577
577
|
}
|
|
@@ -2,21 +2,26 @@
|
|
|
2
2
|
* theme related functions
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import { message } from 'antd'
|
|
6
|
-
import { isEqual } from 'lodash-es'
|
|
7
5
|
import {
|
|
8
|
-
|
|
9
|
-
settingMap,
|
|
10
|
-
defaultThemeLight
|
|
6
|
+
settingMap
|
|
11
7
|
} from '../common/constants'
|
|
12
|
-
import copy from 'json-deep-copy'
|
|
13
8
|
import { convertTheme } from '../common/terminal-theme'
|
|
14
|
-
|
|
15
|
-
|
|
9
|
+
import {
|
|
10
|
+
defaultTheme,
|
|
11
|
+
defaultThemeLight
|
|
12
|
+
} from '../common/theme-defaults'
|
|
16
13
|
|
|
17
14
|
export default Store => {
|
|
18
15
|
Store.prototype.getTerminalThemes = function () {
|
|
19
|
-
|
|
16
|
+
const t1 = defaultTheme()
|
|
17
|
+
const t2 = defaultThemeLight()
|
|
18
|
+
return [
|
|
19
|
+
t1,
|
|
20
|
+
t2,
|
|
21
|
+
...window.store.getItems(settingMap.terminalThemes).filter(d => {
|
|
22
|
+
return d && d.id !== t1.id && d.id !== t2.id
|
|
23
|
+
})
|
|
24
|
+
]
|
|
20
25
|
}
|
|
21
26
|
|
|
22
27
|
Store.prototype.setTheme = function (id) {
|
|
@@ -47,14 +52,16 @@ export default Store => {
|
|
|
47
52
|
|
|
48
53
|
Store.prototype.fixThemes = function (themes) {
|
|
49
54
|
return themes.map(t => {
|
|
50
|
-
const
|
|
51
|
-
const
|
|
55
|
+
const d1 = defaultTheme()
|
|
56
|
+
const d2 = defaultThemeLight()
|
|
57
|
+
const isDefaultTheme = t.id === d1.id
|
|
58
|
+
const isDefaultThemeLight = t.id === d2.id
|
|
52
59
|
if (isDefaultTheme) {
|
|
53
|
-
Object.assign(t,
|
|
60
|
+
Object.assign(t, d1)
|
|
54
61
|
} else if (isDefaultThemeLight) {
|
|
55
|
-
Object.assign(t,
|
|
62
|
+
Object.assign(t, d2)
|
|
56
63
|
} else if (!t.uiThemeConfig) {
|
|
57
|
-
t.uiThemeConfig =
|
|
64
|
+
t.uiThemeConfig = d1.uiThemeConfig
|
|
58
65
|
}
|
|
59
66
|
return t
|
|
60
67
|
})
|
|
@@ -78,33 +85,4 @@ export default Store => {
|
|
|
78
85
|
})
|
|
79
86
|
)
|
|
80
87
|
}
|
|
81
|
-
|
|
82
|
-
Store.prototype.checkDefaultTheme = async function (terminalThemes) {
|
|
83
|
-
const { store } = window
|
|
84
|
-
const themeId = defaultTheme.id
|
|
85
|
-
const currentDefaultTheme = store.terminalThemes.find(d => d.id === themeId)
|
|
86
|
-
if (
|
|
87
|
-
currentDefaultTheme &&
|
|
88
|
-
(
|
|
89
|
-
!isEqual(currentDefaultTheme.themeConfig, defaultTheme.themeConfig) || !isEqual(currentDefaultTheme.uiThemeConfig, defaultTheme.uiThemeConfig) ||
|
|
90
|
-
currentDefaultTheme.name !== defaultTheme.name
|
|
91
|
-
)
|
|
92
|
-
) {
|
|
93
|
-
store.editTheme(
|
|
94
|
-
themeId,
|
|
95
|
-
{
|
|
96
|
-
name: defaultTheme.name,
|
|
97
|
-
themeConfig: defaultTheme.themeConfig,
|
|
98
|
-
uiThemeConfig: defaultTheme.uiThemeConfig
|
|
99
|
-
}
|
|
100
|
-
)
|
|
101
|
-
message.info(
|
|
102
|
-
`${e('default')} ${e('themeConfig')} ${e('updated')}`
|
|
103
|
-
)
|
|
104
|
-
}
|
|
105
|
-
const hasLightTheme = store.getTerminalThemes().find(d => d.id === defaultThemeLight.id)
|
|
106
|
-
if (!hasLightTheme) {
|
|
107
|
-
store.addTheme(defaultThemeLight)
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
88
|
}
|
package/client/store/ui-theme.js
CHANGED
|
@@ -3,9 +3,12 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import {
|
|
6
|
-
defaultTheme,
|
|
7
6
|
settingMap
|
|
8
7
|
} from '../common/constants'
|
|
8
|
+
import {
|
|
9
|
+
defaultTheme
|
|
10
|
+
} from '../common/theme-defaults'
|
|
11
|
+
|
|
9
12
|
import copy from 'json-deep-copy'
|
|
10
13
|
|
|
11
14
|
export default Store => {
|
|
@@ -15,6 +18,6 @@ export default Store => {
|
|
|
15
18
|
.find(d => d.id === store.config.theme)
|
|
16
19
|
return theme && theme.uiThemeConfig
|
|
17
20
|
? copy(theme.uiThemeConfig)
|
|
18
|
-
: defaultTheme.uiThemeConfig
|
|
21
|
+
: defaultTheme().uiThemeConfig
|
|
19
22
|
}
|
|
20
23
|
}
|
package/package.json
CHANGED
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* database default should init
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
function parsor (themeTxt) {
|
|
6
|
-
return themeTxt.split('\n').reduce((prev, line) => {
|
|
7
|
-
let [key = '', value = ''] = line.split('=')
|
|
8
|
-
key = key.trim()
|
|
9
|
-
value = value.trim()
|
|
10
|
-
if (!key || !value) {
|
|
11
|
-
return prev
|
|
12
|
-
}
|
|
13
|
-
prev[key] = value
|
|
14
|
-
return prev
|
|
15
|
-
}, {})
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
const defaultTheme = parsor(`
|
|
19
|
-
main = #141314
|
|
20
|
-
main-dark = #000
|
|
21
|
-
main-light = #2E3338
|
|
22
|
-
text = #ddd
|
|
23
|
-
text-light = #fff
|
|
24
|
-
text-dark = #888
|
|
25
|
-
text-disabled = #777
|
|
26
|
-
primary = #08c
|
|
27
|
-
info = #FFD166
|
|
28
|
-
success = #06D6A0
|
|
29
|
-
error = #EF476F
|
|
30
|
-
warn = #E55934
|
|
31
|
-
`)
|
|
32
|
-
const defaultThemeLight = parsor(`
|
|
33
|
-
main=#ededed
|
|
34
|
-
main-dark=#cccccc
|
|
35
|
-
main-light=#fefefe
|
|
36
|
-
text=#555
|
|
37
|
-
text-light=#777
|
|
38
|
-
text-dark=#444
|
|
39
|
-
text-disabled=#888
|
|
40
|
-
primary=#08c
|
|
41
|
-
info=#FFD166
|
|
42
|
-
success=#06D6A0
|
|
43
|
-
error=#EF476F
|
|
44
|
-
warn=#E55934
|
|
45
|
-
`)
|
|
46
|
-
const defaultThemeLightTerminal = parsor(`
|
|
47
|
-
foreground=#333333
|
|
48
|
-
background=#ededed
|
|
49
|
-
cursor=#b5bd68
|
|
50
|
-
cursorAccent=#1d1f21
|
|
51
|
-
selectionBackground=rgba(0, 0, 0, 0.3)
|
|
52
|
-
black=#575757
|
|
53
|
-
red=#FF2C6D
|
|
54
|
-
green=#19f9d8
|
|
55
|
-
yellow=#FFB86C
|
|
56
|
-
blue=#45A9F9
|
|
57
|
-
magenta=#FF75B5
|
|
58
|
-
cyan=#B084EB
|
|
59
|
-
white=#CDCDCD
|
|
60
|
-
brightBlack=#757575
|
|
61
|
-
brightRed=#FF2C6D
|
|
62
|
-
brightGreen=#19f9d8
|
|
63
|
-
brightYellow=#FFCC95
|
|
64
|
-
brightBlue=#6FC1FF
|
|
65
|
-
brightMagenta=#FF9AC1
|
|
66
|
-
brightCyan=#BCAAFE
|
|
67
|
-
brightWhite=#E6E6E6
|
|
68
|
-
`)
|
|
69
|
-
|
|
70
|
-
const defaultThemeTerminal = {
|
|
71
|
-
foreground: '#bbbbbb',
|
|
72
|
-
background: '#141314',
|
|
73
|
-
cursor: '#b5bd68',
|
|
74
|
-
cursorAccent: '#1d1f21',
|
|
75
|
-
selectionBackground: 'rgba(255, 255, 255, 0.3)',
|
|
76
|
-
black: '#575757',
|
|
77
|
-
red: '#FF2C6D',
|
|
78
|
-
green: '#19f9d8',
|
|
79
|
-
yellow: '#FFB86C',
|
|
80
|
-
blue: '#45A9F9',
|
|
81
|
-
magenta: '#FF75B5',
|
|
82
|
-
cyan: '#B084EB',
|
|
83
|
-
white: '#CDCDCD',
|
|
84
|
-
brightBlack: '#757575',
|
|
85
|
-
brightRed: '#FF2C6D',
|
|
86
|
-
brightGreen: '#19f9d8',
|
|
87
|
-
brightYellow: '#FFCC95',
|
|
88
|
-
brightBlue: '#6FC1FF',
|
|
89
|
-
brightMagenta: '#FF9AC1',
|
|
90
|
-
brightCyan: '#BCAAFE',
|
|
91
|
-
brightWhite: '#E6E6E6'
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
export default [
|
|
95
|
-
{
|
|
96
|
-
db: 'terminalThemes',
|
|
97
|
-
data: [
|
|
98
|
-
{
|
|
99
|
-
_id: 'default',
|
|
100
|
-
name: 'default',
|
|
101
|
-
themeConfig: defaultThemeTerminal,
|
|
102
|
-
uiThemeConfig: defaultTheme
|
|
103
|
-
},
|
|
104
|
-
{
|
|
105
|
-
_id: 'defaultLight',
|
|
106
|
-
name: 'default light',
|
|
107
|
-
themeConfig: defaultThemeLightTerminal,
|
|
108
|
-
uiThemeConfig: defaultThemeLight
|
|
109
|
-
}
|
|
110
|
-
]
|
|
111
|
-
},
|
|
112
|
-
{
|
|
113
|
-
db: 'bookmarkGroups',
|
|
114
|
-
data: [
|
|
115
|
-
{
|
|
116
|
-
_id: 'default',
|
|
117
|
-
title: 'default',
|
|
118
|
-
bookmarkIds: [],
|
|
119
|
-
bookmarkGroupIds: []
|
|
120
|
-
}
|
|
121
|
-
]
|
|
122
|
-
}
|
|
123
|
-
]
|