@electerm/electerm-react 1.72.48 → 1.80.3

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.
Files changed (49) hide show
  1. package/client/common/constants.js +1 -1
  2. package/client/common/sftp.js +3 -1
  3. package/client/components/ai/ai-config.jsx +7 -1
  4. package/client/components/batch-op/batch-op.jsx +4 -5
  5. package/client/components/bg/css-overwrite.jsx +179 -0
  6. package/client/components/bg/shapes.js +501 -0
  7. package/client/components/bookmark-form/form-tabs.jsx +1 -0
  8. package/client/components/bookmark-form/local-form-ui.jsx +7 -1
  9. package/client/components/bookmark-form/render-bg.jsx +43 -0
  10. package/client/components/bookmark-form/serial-form-ui.jsx +7 -1
  11. package/client/components/bookmark-form/ssh-form-ui.jsx +14 -3
  12. package/client/components/bookmark-form/telnet-form-ui.jsx +7 -1
  13. package/client/components/bookmark-form/use-ui.jsx +68 -72
  14. package/client/components/common/ref.js +2 -0
  15. package/client/components/{sftp/confirm-modal-store.jsx → file-transfer/conflict-resolve.jsx} +86 -48
  16. package/client/components/file-transfer/transfer-queue.jsx +151 -0
  17. package/client/components/file-transfer/transfer.jsx +582 -0
  18. package/client/components/{sftp → file-transfer}/transports-action-store.jsx +35 -32
  19. package/client/components/{sftp → file-transfer}/transports-ui-store.jsx +2 -2
  20. package/client/components/main/main.jsx +25 -18
  21. package/client/components/main/wrapper.styl +16 -0
  22. package/client/components/profile/profile-list.jsx +1 -1
  23. package/client/components/quick-commands/qm.styl +4 -1
  24. package/client/components/quick-commands/quick-commands-list.jsx +16 -4
  25. package/client/components/setting-panel/list.jsx +1 -1
  26. package/client/components/setting-panel/setting-common.jsx +25 -23
  27. package/client/components/setting-panel/setting-terminal.jsx +2 -1
  28. package/client/components/setting-panel/terminal-bg-config.jsx +15 -2
  29. package/client/components/sftp/file-info-modal.jsx +3 -0
  30. package/client/components/sftp/file-item.jsx +25 -23
  31. package/client/components/sftp/file-read.js +1 -27
  32. package/client/components/sftp/list-table-ui.jsx +2 -2
  33. package/client/components/sidebar/transfer-history-modal.jsx +1 -1
  34. package/client/components/sidebar/transfer-list-control.jsx +1 -1
  35. package/client/components/sidebar/transport-ui.jsx +16 -9
  36. package/client/components/terminal/terminal.jsx +23 -1
  37. package/client/components/text-editor/simple-editor.jsx +164 -0
  38. package/client/components/text-editor/text-editor-form.jsx +6 -9
  39. package/client/css/includes/box.styl +2 -2
  40. package/client/store/tab.js +5 -1
  41. package/client/store/transfer-list.js +10 -51
  42. package/package.json +1 -1
  43. package/client/components/main/css-overwrite.jsx +0 -91
  44. package/client/components/sftp/transfer-conflict-store.jsx +0 -284
  45. package/client/components/sftp/transport-action-store.jsx +0 -422
  46. package/client/components/sftp/zip.js +0 -42
  47. /package/client/components/{main → bg}/custom-css.jsx +0 -0
  48. /package/client/components/{sftp → file-transfer}/transfer-speed-format.js +0 -0
  49. /package/client/components/{sftp → file-transfer}/transfer.styl +0 -0
@@ -38,7 +38,7 @@ export const contextMenuPaddingTop = 10
38
38
  export const sftpControlHeight = 42 + 30
39
39
  export const sidebarWidth = 43
40
40
  export const maxHistory = 50
41
- export const maxTransport = 1
41
+ export const maxTransport = 5
42
42
  export const maxSftpHistory = 20
43
43
  export const maxZoom = 8
44
44
  export const minZoom = 0.5
@@ -33,12 +33,14 @@ class Sftp {
33
33
  type: func
34
34
  })
35
35
  }
36
- const uid = func + ':' + id
36
+ const fid = generate()
37
+ const uid = func + ':' + fid
37
38
  // let ws = await initWs()
38
39
  return new Promise((resolve, reject) => {
39
40
  ws.s({
40
41
  action: 'sftp-func',
41
42
  id,
43
+ uid,
42
44
  func,
43
45
  args,
44
46
  sessionId
@@ -82,6 +82,9 @@ export default function AIConfigForm ({ initialValues, onSubmit, showAIConfig })
82
82
  type='info'
83
83
  className='mg2y'
84
84
  />
85
+ <p>
86
+ Full Url: {initialValues?.baseURLAI}{initialValues?.apiPathAI}
87
+ </p>
85
88
  <Form
86
89
  form={form}
87
90
  onFinish={handleSubmit}
@@ -112,10 +115,13 @@ export default function AIConfigForm ({ initialValues, onSubmit, showAIConfig })
112
115
  <Form.Item
113
116
  label='API PATH'
114
117
  name='apiPathAI'
118
+ rules={[
119
+ { required: true, message: 'Please input API PATH' }
120
+ ]}
115
121
  noStyle
116
122
  >
117
123
  <Input
118
- placeholder='Enter API path'
124
+ placeholder='/chat/completions'
119
125
  style={{ width: '25%' }}
120
126
  />
121
127
  </Form.Item>
@@ -18,7 +18,8 @@ import {
18
18
  sidebarWidth,
19
19
  statusMap,
20
20
  batchOpHelpLink,
21
- modals
21
+ modals,
22
+ fileActions
22
23
  } from '../../common/constants'
23
24
  import HelpIcon from '../common/help-icon'
24
25
  import download from '../../common/download'
@@ -216,9 +217,7 @@ export default class BatchOp extends PureComponent {
216
217
  toPath: resolveFilePath(isDown ? conf.localPath : conf.remotePath, name),
217
218
  typeFrom: isDown ? 'remote' : 'local',
218
219
  typeTo: isDown ? 'local' : 'remote',
219
- skipExpand: true,
220
- zip: true,
221
- skipConfirm: true
220
+ resolvePolicy: fileActions.mergeOrOverwrite
222
221
  }
223
222
  const { store } = window
224
223
  store.addTransferList([obj])
@@ -229,7 +228,7 @@ export default class BatchOp extends PureComponent {
229
228
  this.ref1 = autoRun(() => {
230
229
  const { transferHistory } = store
231
230
  const first = transferHistory.find(t => {
232
- return (t.id === obj.id || t.originalId === obj.id) && t.unzip
231
+ return t.id === obj.id || t.originalId === obj.id
233
232
  })
234
233
  if (first && first.sessionId === tab.sessionId) {
235
234
  this.ref1 && this.ref1.stop()
@@ -0,0 +1,179 @@
1
+ /**
2
+ * btns
3
+ */
4
+ import { Component } from 'react'
5
+ import fs from '../../common/fs'
6
+ import { noTerminalBgValue } from '../../common/constants'
7
+ import { generateMosaicBackground } from './shapes'
8
+
9
+ export default class CssOverwrite extends Component {
10
+ static styleTag = null
11
+
12
+ shouldComponentUpdate (nextProps) {
13
+ if (!this.props.wsInited && nextProps.wsInited) {
14
+ return true
15
+ }
16
+
17
+ const bgProps = [
18
+ 'terminalBackgroundImagePath',
19
+ 'terminalBackgroundFilterBlur',
20
+ 'terminalBackgroundFilterOpacity',
21
+ 'terminalBackgroundFilterBrightness',
22
+ 'terminalBackgroundFilterContrast',
23
+ 'terminalBackgroundFilterGrayscale'
24
+ ]
25
+ const globalChanged = bgProps.some(prop => this.props[prop] !== nextProps[prop])
26
+ if (globalChanged) {
27
+ return true
28
+ }
29
+
30
+ const currentTabs = this.props.tabs || []
31
+ const nextTabs = nextProps.tabs || []
32
+ if (currentTabs.length !== nextTabs.length) {
33
+ return true
34
+ }
35
+
36
+ // If no tabs in both cases
37
+ if (!currentTabs.length && !nextTabs.length) {
38
+ return false
39
+ }
40
+
41
+ // Since tab bg settings never change, we only need to compare tab IDs
42
+ const currentIds = new Set(currentTabs.map(t => t.id))
43
+ const nextIds = new Set(nextTabs.map(t => t.id))
44
+
45
+ // Check if all current IDs exist in next IDs
46
+ for (const id of currentIds) {
47
+ if (!nextIds.has(id)) return true
48
+ }
49
+
50
+ return false
51
+ }
52
+
53
+ componentDidUpdate (prevProps) {
54
+ if (!prevProps.wsInited && this.props.wsInited) {
55
+ this.writeCss()
56
+ return
57
+ }
58
+ this.updateCss()
59
+ }
60
+
61
+ // Common function to handle background image style creation
62
+ createBackgroundStyle = async (imagePath) => {
63
+ if (!imagePath || imagePath === '') {
64
+ return ''
65
+ }
66
+
67
+ let content = ''
68
+ let st = ''
69
+ const isWebImg = /^https?:\/\//.test(imagePath)
70
+ if (imagePath === 'randomShape') {
71
+ st = `url(${generateMosaicBackground()})`
72
+ } else if (imagePath === 'index') {
73
+ st = 'index'
74
+ } else if (noTerminalBgValue === imagePath) {
75
+ st = 'none'
76
+ } else if (imagePath && !isWebImg) {
77
+ content = await fs.readFileAsBase64(imagePath)
78
+ .catch(log.error)
79
+ if (content) {
80
+ st = `url(data:image;base64,${content})`
81
+ }
82
+ } else if (imagePath && isWebImg) {
83
+ st = `url(${imagePath})`
84
+ }
85
+ return st
86
+ }
87
+
88
+ // Common function to create filter styles
89
+ createFilterStyle = (props, tabProps = null) => {
90
+ return `blur(${
91
+ (tabProps?.terminalBackgroundFilterBlur || props.terminalBackgroundFilterBlur)
92
+ }px) opacity(${
93
+ +(tabProps?.terminalBackgroundFilterOpacity || props.terminalBackgroundFilterOpacity)
94
+ }) brightness(${
95
+ +(tabProps?.terminalBackgroundFilterBrightness || props.terminalBackgroundFilterBrightness)
96
+ }) contrast(${
97
+ +(tabProps?.terminalBackgroundFilterContrast || props.terminalBackgroundFilterContrast)
98
+ }) grayscale(${
99
+ +(tabProps?.terminalBackgroundFilterGrayscale || props.terminalBackgroundFilterGrayscale)
100
+ })`
101
+ }
102
+
103
+ createStyleForTab = async (tab) => {
104
+ const bg = tab.terminalBackground || {}
105
+ const img = bg.terminalBackgroundImagePath || this.props.terminalBackgroundImagePath
106
+ const st = await this.createBackgroundStyle(img)
107
+
108
+ if (!st) {
109
+ return ''
110
+ }
111
+
112
+ const selector = `#container .sessions .session-${tab.id} .xterm-screen::before`
113
+ const styles = []
114
+ if (st === 'index') {
115
+ styles.push(`content: '${tab.tabCount}'`)
116
+ } else if (st !== 'none') {
117
+ styles.push(
118
+ `background-image: ${st}`,
119
+ 'background-position: center',
120
+ `filter: ${this.createFilterStyle(this.props, tab)}`
121
+ )
122
+ }
123
+ return `${selector} {
124
+ ${styles.join(';')};
125
+ }`
126
+ }
127
+
128
+ createGlobalStyle = async () => {
129
+ const st = await this.createBackgroundStyle(this.props.terminalBackgroundImagePath)
130
+ if (!st) {
131
+ return '#container .session-batch-active .xterm-screen::before {' +
132
+ 'background-image: url("./images/electerm-watermark.png");' +
133
+ '}'
134
+ }
135
+
136
+ const styles = []
137
+
138
+ if (st !== 'none' && st !== 'index') {
139
+ styles.push(
140
+ `background-image: ${st}`,
141
+ 'background-position: center',
142
+ `filter: ${this.createFilterStyle(this.props)}`
143
+ )
144
+ }
145
+
146
+ return `#container .session-batch-active .xterm-screen::before {
147
+ ${styles.join(';')};
148
+ }`
149
+ }
150
+
151
+ writeCss = async () => {
152
+ if (!CssOverwrite.styleTag) {
153
+ CssOverwrite.styleTag = document.createElement('style')
154
+ CssOverwrite.styleTag.type = 'text/css'
155
+ CssOverwrite.styleTag.id = 'css-overwrite-terminal-backgrounds'
156
+ document.getElementsByTagName('head')[0].appendChild(CssOverwrite.styleTag)
157
+ }
158
+
159
+ const { tabs = [] } = this.props
160
+ const tabStyles = await Promise.all(
161
+ tabs
162
+ .map(tab => this.createStyleForTab(tab))
163
+ )
164
+ const globalStyle = await this.createGlobalStyle()
165
+ const allStyles = [
166
+ globalStyle,
167
+ ...tabStyles
168
+ ].filter(Boolean).join('\n')
169
+ CssOverwrite.styleTag.innerHTML = allStyles
170
+ }
171
+
172
+ updateCss = async () => {
173
+ await this.writeCss()
174
+ }
175
+
176
+ render () {
177
+ return null
178
+ }
179
+ }