@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.
- package/client/common/constants.js +1 -1
- package/client/common/sftp.js +3 -1
- package/client/components/ai/ai-config.jsx +7 -1
- package/client/components/batch-op/batch-op.jsx +4 -5
- package/client/components/bg/css-overwrite.jsx +179 -0
- package/client/components/bg/shapes.js +501 -0
- package/client/components/bookmark-form/form-tabs.jsx +1 -0
- package/client/components/bookmark-form/local-form-ui.jsx +7 -1
- package/client/components/bookmark-form/render-bg.jsx +43 -0
- package/client/components/bookmark-form/serial-form-ui.jsx +7 -1
- package/client/components/bookmark-form/ssh-form-ui.jsx +14 -3
- package/client/components/bookmark-form/telnet-form-ui.jsx +7 -1
- package/client/components/bookmark-form/use-ui.jsx +68 -72
- package/client/components/common/ref.js +2 -0
- package/client/components/{sftp/confirm-modal-store.jsx → file-transfer/conflict-resolve.jsx} +86 -48
- package/client/components/file-transfer/transfer-queue.jsx +151 -0
- package/client/components/file-transfer/transfer.jsx +582 -0
- package/client/components/{sftp → file-transfer}/transports-action-store.jsx +35 -32
- package/client/components/{sftp → file-transfer}/transports-ui-store.jsx +2 -2
- package/client/components/main/main.jsx +25 -18
- package/client/components/main/wrapper.styl +16 -0
- package/client/components/profile/profile-list.jsx +1 -1
- package/client/components/quick-commands/qm.styl +4 -1
- package/client/components/quick-commands/quick-commands-list.jsx +16 -4
- package/client/components/setting-panel/list.jsx +1 -1
- package/client/components/setting-panel/setting-common.jsx +25 -23
- package/client/components/setting-panel/setting-terminal.jsx +2 -1
- package/client/components/setting-panel/terminal-bg-config.jsx +15 -2
- package/client/components/sftp/file-info-modal.jsx +3 -0
- package/client/components/sftp/file-item.jsx +25 -23
- package/client/components/sftp/file-read.js +1 -27
- package/client/components/sftp/list-table-ui.jsx +2 -2
- package/client/components/sidebar/transfer-history-modal.jsx +1 -1
- package/client/components/sidebar/transfer-list-control.jsx +1 -1
- package/client/components/sidebar/transport-ui.jsx +16 -9
- package/client/components/terminal/terminal.jsx +23 -1
- package/client/components/text-editor/simple-editor.jsx +164 -0
- package/client/components/text-editor/text-editor-form.jsx +6 -9
- package/client/css/includes/box.styl +2 -2
- package/client/store/tab.js +5 -1
- package/client/store/transfer-list.js +10 -51
- package/package.json +1 -1
- package/client/components/main/css-overwrite.jsx +0 -91
- package/client/components/sftp/transfer-conflict-store.jsx +0 -284
- package/client/components/sftp/transport-action-store.jsx +0 -422
- package/client/components/sftp/zip.js +0 -42
- /package/client/components/{main → bg}/custom-css.jsx +0 -0
- /package/client/components/{sftp → file-transfer}/transfer-speed-format.js +0 -0
- /package/client/components/{sftp → file-transfer}/transfer.styl +0 -0
|
@@ -0,0 +1,501 @@
|
|
|
1
|
+
// mathematicalBackground.js
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Generates mathematical and physics-based backgrounds for terminal
|
|
5
|
+
* Replaces the text-based cat patterns with proper canvas graphics
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Generate a canvas with a mathematical or physical pattern
|
|
10
|
+
* @param {number} size - Size of the canvas
|
|
11
|
+
* @returns {string} - Data URL of the generated canvas
|
|
12
|
+
*/
|
|
13
|
+
export function generateMosaicBackground (size = 200) {
|
|
14
|
+
// Create canvas with transparent background
|
|
15
|
+
const canvas = document.createElement('canvas')
|
|
16
|
+
canvas.width = size
|
|
17
|
+
canvas.height = size
|
|
18
|
+
const ctx = canvas.getContext('2d')
|
|
19
|
+
|
|
20
|
+
// Clear with transparent background
|
|
21
|
+
ctx.clearRect(0, 0, size, size)
|
|
22
|
+
|
|
23
|
+
// Available pattern generators
|
|
24
|
+
const patterns = [
|
|
25
|
+
generateFluidDynamics,
|
|
26
|
+
generateQuantumWave,
|
|
27
|
+
generateRelativityField,
|
|
28
|
+
generateFluidFlow,
|
|
29
|
+
generateParticlePhysics,
|
|
30
|
+
generateWaveInterference,
|
|
31
|
+
generateStringTheory,
|
|
32
|
+
generateQuantumField
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
// Select a random pattern
|
|
36
|
+
const selectedPattern = patterns[Math.floor(Math.random() * patterns.length)]
|
|
37
|
+
|
|
38
|
+
// Generate random color parameters
|
|
39
|
+
const hue = Math.floor(Math.random() * 360)
|
|
40
|
+
const saturation = 70 + Math.floor(Math.random() * 20)
|
|
41
|
+
const lightness = 70 + Math.floor(Math.random() * 20)
|
|
42
|
+
|
|
43
|
+
// Generate the pattern with given color
|
|
44
|
+
selectedPattern(ctx, size, `hsla(${hue}, ${saturation}%, ${lightness}%, 0.3)`)
|
|
45
|
+
|
|
46
|
+
// Return the canvas as a data URL
|
|
47
|
+
return canvas.toDataURL()
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Generates a fluid dynamics simulation pattern
|
|
52
|
+
*/
|
|
53
|
+
function generateFluidDynamics (ctx, size, color) {
|
|
54
|
+
const points = 6 + Math.floor(Math.random() * 6)
|
|
55
|
+
const baseRadius = size * 0.3
|
|
56
|
+
const turbulence = 0.3 + Math.random() * 0.4
|
|
57
|
+
const detail = 5 + Math.floor(Math.random() * 5)
|
|
58
|
+
|
|
59
|
+
// Create multiple vortices
|
|
60
|
+
for (let i = 0; i < points; i++) {
|
|
61
|
+
const angle = (i / points) * Math.PI * 2
|
|
62
|
+
const distance = baseRadius * (0.5 + Math.random() * 0.5)
|
|
63
|
+
const cx = size / 2 + Math.cos(angle) * distance
|
|
64
|
+
const cy = size / 2 + Math.sin(angle) * distance
|
|
65
|
+
const radius = size * (0.1 + Math.random() * 0.15)
|
|
66
|
+
|
|
67
|
+
// Draw vortex
|
|
68
|
+
ctx.strokeStyle = color
|
|
69
|
+
ctx.lineWidth = 1
|
|
70
|
+
|
|
71
|
+
for (let j = 0; j < detail; j++) {
|
|
72
|
+
const spiralRadius = radius * (j / detail)
|
|
73
|
+
const spiralTurns = 2 + Math.random() * 3
|
|
74
|
+
|
|
75
|
+
ctx.beginPath()
|
|
76
|
+
for (let t = 0; t <= Math.PI * 2 * spiralTurns; t += 0.1) {
|
|
77
|
+
const r = spiralRadius * (1 - t / (Math.PI * 2 * spiralTurns))
|
|
78
|
+
const noise = Math.sin(t * 5) * turbulence * r
|
|
79
|
+
const x = cx + (r + noise) * Math.cos(t)
|
|
80
|
+
const y = cy + (r + noise) * Math.sin(t)
|
|
81
|
+
|
|
82
|
+
if (t === 0) {
|
|
83
|
+
ctx.moveTo(x, y)
|
|
84
|
+
} else {
|
|
85
|
+
ctx.lineTo(x, y)
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
ctx.stroke()
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Generates a quantum wave probability pattern
|
|
95
|
+
*/
|
|
96
|
+
function generateQuantumWave (ctx, size, color) {
|
|
97
|
+
const centerX = size / 2
|
|
98
|
+
const centerY = size / 2
|
|
99
|
+
const maxRadius = size * 0.45
|
|
100
|
+
const waveCount = 3 + Math.floor(Math.random() * 5)
|
|
101
|
+
|
|
102
|
+
ctx.strokeStyle = color
|
|
103
|
+
ctx.lineWidth = 1.5
|
|
104
|
+
|
|
105
|
+
// Generate wave packets with interference
|
|
106
|
+
for (let w = 0; w < waveCount; w++) {
|
|
107
|
+
const offsetX = (Math.random() - 0.5) * size * 0.3
|
|
108
|
+
const offsetY = (Math.random() - 0.5) * size * 0.3
|
|
109
|
+
const frequency = 5 + Math.random() * 10
|
|
110
|
+
const amplitude = 5 + Math.random() * 10
|
|
111
|
+
const phase = Math.random() * Math.PI * 2
|
|
112
|
+
|
|
113
|
+
ctx.beginPath()
|
|
114
|
+
|
|
115
|
+
for (let angle = 0; angle <= Math.PI * 2; angle += 0.02) {
|
|
116
|
+
const baseRadius = maxRadius * (0.2 + Math.random() * 0.8)
|
|
117
|
+
const waveR = baseRadius + Math.sin(angle * frequency + phase) * amplitude
|
|
118
|
+
|
|
119
|
+
const x = centerX + offsetX + waveR * Math.cos(angle)
|
|
120
|
+
const y = centerY + offsetY + waveR * Math.sin(angle)
|
|
121
|
+
|
|
122
|
+
if (angle === 0) {
|
|
123
|
+
ctx.moveTo(x, y)
|
|
124
|
+
} else {
|
|
125
|
+
ctx.lineTo(x, y)
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
ctx.closePath()
|
|
130
|
+
ctx.stroke()
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Generates a relativity field with curved spacetime
|
|
136
|
+
*/
|
|
137
|
+
function generateRelativityField (ctx, size, color) {
|
|
138
|
+
const centerX = size / 2
|
|
139
|
+
const centerY = size / 2
|
|
140
|
+
const gridLines = 8 + Math.floor(Math.random() * 7)
|
|
141
|
+
const massPoints = 2 + Math.floor(Math.random() * 3)
|
|
142
|
+
const distortion = 0.2 + Math.random() * 0.5
|
|
143
|
+
|
|
144
|
+
ctx.strokeStyle = color
|
|
145
|
+
ctx.lineWidth = 1
|
|
146
|
+
|
|
147
|
+
// Create mass points that distort spacetime
|
|
148
|
+
const masses = []
|
|
149
|
+
for (let i = 0; i < massPoints; i++) {
|
|
150
|
+
masses.push({
|
|
151
|
+
x: centerX + (Math.random() - 0.5) * size * 0.6,
|
|
152
|
+
y: centerY + (Math.random() - 0.5) * size * 0.6,
|
|
153
|
+
mass: 0.3 + Math.random() * 0.7
|
|
154
|
+
})
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// Draw a grid that gets distorted by the masses
|
|
158
|
+
for (let i = 0; i <= gridLines; i++) {
|
|
159
|
+
// Horizontal lines
|
|
160
|
+
ctx.beginPath()
|
|
161
|
+
for (let x = 0; x < size; x += 2) {
|
|
162
|
+
let y = (i / gridLines) * size
|
|
163
|
+
|
|
164
|
+
// Apply distortion from masses
|
|
165
|
+
for (const mass of masses) {
|
|
166
|
+
const dx = x - mass.x
|
|
167
|
+
const dy = y - mass.y
|
|
168
|
+
const distance = Math.sqrt(dx * dx + dy * dy)
|
|
169
|
+
const force = mass.mass * distortion * size / (distance + 10)
|
|
170
|
+
|
|
171
|
+
// Add gravitational displacement
|
|
172
|
+
y += force * (y - mass.y) / (distance + 1)
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
if (x === 0) {
|
|
176
|
+
ctx.moveTo(x, y)
|
|
177
|
+
} else {
|
|
178
|
+
ctx.lineTo(x, y)
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
ctx.stroke()
|
|
182
|
+
|
|
183
|
+
// Vertical lines
|
|
184
|
+
ctx.beginPath()
|
|
185
|
+
for (let y = 0; y < size; y += 2) {
|
|
186
|
+
let x = (i / gridLines) * size
|
|
187
|
+
|
|
188
|
+
// Apply distortion from masses
|
|
189
|
+
for (const mass of masses) {
|
|
190
|
+
const dx = x - mass.x
|
|
191
|
+
const dy = y - mass.y
|
|
192
|
+
const distance = Math.sqrt(dx * dx + dy * dy)
|
|
193
|
+
const force = mass.mass * distortion * size / (distance + 10)
|
|
194
|
+
|
|
195
|
+
// Add gravitational displacement
|
|
196
|
+
x += force * (x - mass.x) / (distance + 1)
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
if (y === 0) {
|
|
200
|
+
ctx.moveTo(x, y)
|
|
201
|
+
} else {
|
|
202
|
+
ctx.lineTo(x, y)
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
ctx.stroke()
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Generates a fluid flow field with streamlines
|
|
211
|
+
*/
|
|
212
|
+
function generateFluidFlow (ctx, size, color) {
|
|
213
|
+
const detail = 15 + Math.floor(Math.random() * 15)
|
|
214
|
+
const vectors = []
|
|
215
|
+
const streamlines = 12 + Math.floor(Math.random() * 12)
|
|
216
|
+
|
|
217
|
+
// Create a vector field using perlin-like noise
|
|
218
|
+
for (let i = 0; i < detail; i++) {
|
|
219
|
+
for (let j = 0; j < detail; j++) {
|
|
220
|
+
const x = (i + 0.5) * (size / detail)
|
|
221
|
+
const y = (j + 0.5) * (size / detail)
|
|
222
|
+
|
|
223
|
+
// Generate vector field using harmonic functions for smoother flow
|
|
224
|
+
const angle = Math.sin(x * 0.01) * Math.cos(y * 0.01) * Math.PI * 2 +
|
|
225
|
+
Math.sin(x * 0.02 + y * 0.01) * Math.PI +
|
|
226
|
+
Math.cos(x * 0.01 - y * 0.03) * Math.PI
|
|
227
|
+
|
|
228
|
+
vectors.push({
|
|
229
|
+
x,
|
|
230
|
+
y,
|
|
231
|
+
dx: Math.cos(angle),
|
|
232
|
+
dy: Math.sin(angle)
|
|
233
|
+
})
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// Interpolate vector at any position
|
|
238
|
+
function getVector (x, y) {
|
|
239
|
+
// Find the four nearest vectors
|
|
240
|
+
let totalWeight = 0
|
|
241
|
+
let dx = 0
|
|
242
|
+
let dy = 0
|
|
243
|
+
|
|
244
|
+
for (const v of vectors) {
|
|
245
|
+
const distance = Math.sqrt((x - v.x) ** 2 + (y - v.y) ** 2)
|
|
246
|
+
const weight = 1 / (distance + 0.1)
|
|
247
|
+
|
|
248
|
+
dx += v.dx * weight
|
|
249
|
+
dy += v.dy * weight
|
|
250
|
+
totalWeight += weight
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
return {
|
|
254
|
+
dx: dx / totalWeight,
|
|
255
|
+
dy: dy / totalWeight
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// Draw streamlines
|
|
260
|
+
ctx.strokeStyle = color
|
|
261
|
+
ctx.lineWidth = 1
|
|
262
|
+
|
|
263
|
+
for (let i = 0; i < streamlines; i++) {
|
|
264
|
+
// Random starting point
|
|
265
|
+
let x = Math.random() * size
|
|
266
|
+
let y = Math.random() * size
|
|
267
|
+
|
|
268
|
+
ctx.beginPath()
|
|
269
|
+
ctx.moveTo(x, y)
|
|
270
|
+
|
|
271
|
+
// Follow the vector field
|
|
272
|
+
for (let step = 0; step < 100; step++) {
|
|
273
|
+
const v = getVector(x, y)
|
|
274
|
+
x += v.dx * 5
|
|
275
|
+
y += v.dy * 5
|
|
276
|
+
|
|
277
|
+
if (x < 0 || x >= size || y < 0 || y >= size) break
|
|
278
|
+
|
|
279
|
+
ctx.lineTo(x, y)
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
ctx.stroke()
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* Generates a particle physics pattern with collision tracks
|
|
288
|
+
*/
|
|
289
|
+
function generateParticlePhysics (ctx, size, color) {
|
|
290
|
+
const centerX = size / 2
|
|
291
|
+
const centerY = size / 2
|
|
292
|
+
const particleCount = 20 + Math.floor(Math.random() * 20)
|
|
293
|
+
const maxRadius = size * 0.4
|
|
294
|
+
|
|
295
|
+
ctx.strokeStyle = color
|
|
296
|
+
ctx.lineWidth = 1
|
|
297
|
+
|
|
298
|
+
// Create a simulated particle collision
|
|
299
|
+
for (let i = 0; i < particleCount; i++) {
|
|
300
|
+
// Start from center
|
|
301
|
+
const angle = Math.random() * Math.PI * 2
|
|
302
|
+
const speed = 2 + Math.random() * 4
|
|
303
|
+
let x = centerX
|
|
304
|
+
let y = centerY
|
|
305
|
+
let vx = Math.cos(angle) * speed
|
|
306
|
+
let vy = Math.sin(angle) * speed
|
|
307
|
+
|
|
308
|
+
// Add some curvature for charged particles
|
|
309
|
+
const charge = (Math.random() - 0.5) * 0.2
|
|
310
|
+
|
|
311
|
+
ctx.beginPath()
|
|
312
|
+
ctx.moveTo(x, y)
|
|
313
|
+
|
|
314
|
+
// Trace the particle path
|
|
315
|
+
for (let step = 0; step < 100; step++) {
|
|
316
|
+
// Update velocity (magnetic field effect)
|
|
317
|
+
const perpX = -vy
|
|
318
|
+
const perpY = vx
|
|
319
|
+
vx += perpX * charge
|
|
320
|
+
vy += perpY * charge
|
|
321
|
+
|
|
322
|
+
// Normalize velocity
|
|
323
|
+
const speed = Math.sqrt(vx * vx + vy * vy)
|
|
324
|
+
vx = vx / speed * 3
|
|
325
|
+
vy = vy / speed * 3
|
|
326
|
+
|
|
327
|
+
// Update position
|
|
328
|
+
x += vx
|
|
329
|
+
y += vy
|
|
330
|
+
|
|
331
|
+
// Random scattering or decay
|
|
332
|
+
if (Math.random() < 0.05) {
|
|
333
|
+
vx += (Math.random() - 0.5) * 2
|
|
334
|
+
vy += (Math.random() - 0.5) * 2
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
ctx.lineTo(x, y)
|
|
338
|
+
|
|
339
|
+
// Stop if went too far
|
|
340
|
+
if (Math.sqrt((x - centerX) ** 2 + (y - centerY) ** 2) > maxRadius) {
|
|
341
|
+
break
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
ctx.stroke()
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* Generates a wave interference pattern
|
|
351
|
+
*/
|
|
352
|
+
function generateWaveInterference (ctx, size, color) {
|
|
353
|
+
const waveCount = 3 + Math.floor(Math.random() * 3)
|
|
354
|
+
const resolution = 2
|
|
355
|
+
|
|
356
|
+
// Generate multiple waves and compute interference
|
|
357
|
+
const sources = []
|
|
358
|
+
for (let i = 0; i < waveCount; i++) {
|
|
359
|
+
sources.push({
|
|
360
|
+
x: Math.random() * size,
|
|
361
|
+
y: Math.random() * size,
|
|
362
|
+
frequency: 0.05 + Math.random() * 0.1,
|
|
363
|
+
amplitude: 0.5 + Math.random() * 0.5
|
|
364
|
+
})
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
// Compute the interference pattern
|
|
368
|
+
for (let x = 0; x < size; x += resolution) {
|
|
369
|
+
for (let y = 0; y < size; y += resolution) {
|
|
370
|
+
let value = 0
|
|
371
|
+
|
|
372
|
+
// Sum all wave contributions
|
|
373
|
+
for (const source of sources) {
|
|
374
|
+
const dx = x - source.x
|
|
375
|
+
const dy = y - source.y
|
|
376
|
+
const distance = Math.sqrt(dx * dx + dy * dy)
|
|
377
|
+
|
|
378
|
+
// Add wave contribution
|
|
379
|
+
value += Math.cos(distance * source.frequency * Math.PI * 2) * source.amplitude
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
// Only draw peaks
|
|
383
|
+
if (value > 0.8) {
|
|
384
|
+
const opacity = (value - 0.8) * 3
|
|
385
|
+
const finalColor = color.replace(/[\d.]+\)$/, `${opacity * 0.5})`)
|
|
386
|
+
ctx.fillStyle = finalColor
|
|
387
|
+
ctx.fillRect(x, y, resolution, resolution)
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
/**
|
|
394
|
+
* Generates a string theory inspired pattern
|
|
395
|
+
*/
|
|
396
|
+
function generateStringTheory (ctx, size, color) {
|
|
397
|
+
const centerX = size / 2
|
|
398
|
+
const centerY = size / 2
|
|
399
|
+
const strings = 100 + Math.floor(Math.random() * 150)
|
|
400
|
+
const dimensions = 6 + Math.floor(Math.random() * 5)
|
|
401
|
+
|
|
402
|
+
ctx.strokeStyle = color
|
|
403
|
+
ctx.lineWidth = 0.5
|
|
404
|
+
|
|
405
|
+
for (let i = 0; i < strings; i++) {
|
|
406
|
+
// Base string params
|
|
407
|
+
const radius = 10 + Math.random() * size * 0.35
|
|
408
|
+
const startAngle = Math.random() * Math.PI * 2
|
|
409
|
+
|
|
410
|
+
// Additional dimensional parameters (projected to 2D)
|
|
411
|
+
const phases = []
|
|
412
|
+
const frequencies = []
|
|
413
|
+
for (let d = 0; d < dimensions; d++) {
|
|
414
|
+
phases.push(Math.random() * Math.PI * 2)
|
|
415
|
+
frequencies.push(1 + Math.random() * 5)
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
ctx.beginPath()
|
|
419
|
+
|
|
420
|
+
// Draw the string vibration
|
|
421
|
+
for (let t = 0; t <= Math.PI * 2; t += 0.05) {
|
|
422
|
+
let x = centerX + radius * Math.cos(t + startAngle)
|
|
423
|
+
let y = centerY + radius * Math.sin(t + startAngle)
|
|
424
|
+
|
|
425
|
+
// Add vibrational modes from extra dimensions
|
|
426
|
+
for (let d = 0; d < dimensions; d++) {
|
|
427
|
+
const vibration = Math.sin(t * frequencies[d] + phases[d])
|
|
428
|
+
x += vibration * (5 + Math.random() * 5) * Math.cos(t + Math.PI / 2)
|
|
429
|
+
y += vibration * (5 + Math.random() * 5) * Math.sin(t + Math.PI / 2)
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
if (t === 0) {
|
|
433
|
+
ctx.moveTo(x, y)
|
|
434
|
+
} else {
|
|
435
|
+
ctx.lineTo(x, y)
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
ctx.stroke()
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
/**
|
|
444
|
+
* Generates a quantum field theory inspired pattern
|
|
445
|
+
*/
|
|
446
|
+
function generateQuantumField (ctx, size, color) {
|
|
447
|
+
const points = 10 + Math.floor(Math.random() * 15)
|
|
448
|
+
const fieldStrength = 10 + Math.random() * 10
|
|
449
|
+
|
|
450
|
+
// Create virtual particles
|
|
451
|
+
const particles = []
|
|
452
|
+
for (let i = 0; i < points; i++) {
|
|
453
|
+
particles.push({
|
|
454
|
+
x: Math.random() * size,
|
|
455
|
+
y: Math.random() * size,
|
|
456
|
+
charge: Math.random() * 2 - 1
|
|
457
|
+
})
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
// Draw field lines
|
|
461
|
+
ctx.strokeStyle = color
|
|
462
|
+
ctx.lineWidth = 0.8
|
|
463
|
+
|
|
464
|
+
// Grid resolution
|
|
465
|
+
const resolution = 15
|
|
466
|
+
|
|
467
|
+
for (let i = 0; i <= resolution; i++) {
|
|
468
|
+
for (let j = 0; j <= resolution; j++) {
|
|
469
|
+
const x = (i / resolution) * size
|
|
470
|
+
const y = (j / resolution) * size
|
|
471
|
+
|
|
472
|
+
// Calculate field vector at this point
|
|
473
|
+
let fieldX = 0
|
|
474
|
+
let fieldY = 0
|
|
475
|
+
|
|
476
|
+
for (const particle of particles) {
|
|
477
|
+
const dx = x - particle.x
|
|
478
|
+
const dy = y - particle.y
|
|
479
|
+
const distance = Math.sqrt(dx * dx + dy * dy)
|
|
480
|
+
const force = fieldStrength * particle.charge / (distance * distance + 100)
|
|
481
|
+
|
|
482
|
+
fieldX += dx * force
|
|
483
|
+
fieldY += dy * force
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
// Normalize field vector
|
|
487
|
+
const magnitude = Math.sqrt(fieldX * fieldX + fieldY * fieldY)
|
|
488
|
+
if (magnitude > 0) {
|
|
489
|
+
fieldX = fieldX / magnitude
|
|
490
|
+
fieldY = fieldY / magnitude
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
// Draw field vector
|
|
494
|
+
const lineLength = 10 + Math.random() * 5
|
|
495
|
+
ctx.beginPath()
|
|
496
|
+
ctx.moveTo(x, y)
|
|
497
|
+
ctx.lineTo(x + fieldX * lineLength, y + fieldY * lineLength)
|
|
498
|
+
ctx.stroke()
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
}
|
|
@@ -20,6 +20,7 @@ import useSubmit from './use-submit'
|
|
|
20
20
|
import useUI from './use-ui'
|
|
21
21
|
import useQm from './use-quick-commands'
|
|
22
22
|
import copy from 'json-deep-copy'
|
|
23
|
+
import renderTermBg from './render-bg'
|
|
23
24
|
import { defaults } from 'lodash-es'
|
|
24
25
|
import renderRunScripts from './render-delayed-scripts.jsx'
|
|
25
26
|
import { ColorPickerItem } from './color-picker-item.jsx'
|
|
@@ -124,7 +125,12 @@ export default function LocalFormUi (props) {
|
|
|
124
125
|
key: 'settings',
|
|
125
126
|
label: e('settings'),
|
|
126
127
|
forceRender: true,
|
|
127
|
-
children:
|
|
128
|
+
children: (
|
|
129
|
+
<>
|
|
130
|
+
{uis}
|
|
131
|
+
{renderTermBg(form)}
|
|
132
|
+
</>
|
|
133
|
+
)
|
|
128
134
|
},
|
|
129
135
|
{
|
|
130
136
|
key: 'quickCommands',
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* bookmark form
|
|
3
|
+
*/
|
|
4
|
+
import React from 'react'
|
|
5
|
+
import { Form } from 'antd'
|
|
6
|
+
import TerminalBackgroundConfig from '../setting-panel/terminal-bg-config'
|
|
7
|
+
import { formItemLayout } from '../../common/form-layout'
|
|
8
|
+
|
|
9
|
+
const FormItem = Form.Item
|
|
10
|
+
|
|
11
|
+
const e = window.translate
|
|
12
|
+
|
|
13
|
+
// Custom form control that implements the antd form control interface
|
|
14
|
+
const TerminalBgControl = ({ value = {}, onChange }) => {
|
|
15
|
+
const handleChange = (newValue, name) => {
|
|
16
|
+
const updatedValue = {
|
|
17
|
+
...value,
|
|
18
|
+
[name]: newValue
|
|
19
|
+
}
|
|
20
|
+
onChange(updatedValue)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<TerminalBackgroundConfig
|
|
25
|
+
config={value}
|
|
26
|
+
onChangeValue={handleChange}
|
|
27
|
+
name='terminalBackgroundImagePath'
|
|
28
|
+
/>
|
|
29
|
+
)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export default function renderTermBg (form) {
|
|
33
|
+
const formProps = {
|
|
34
|
+
...formItemLayout,
|
|
35
|
+
name: 'terminalBackground',
|
|
36
|
+
label: e('terminalBackgroundImage')
|
|
37
|
+
}
|
|
38
|
+
return (
|
|
39
|
+
<FormItem {...formProps}>
|
|
40
|
+
<TerminalBgControl />
|
|
41
|
+
</FormItem>
|
|
42
|
+
)
|
|
43
|
+
}
|
|
@@ -31,6 +31,7 @@ import useSubmit from './use-submit'
|
|
|
31
31
|
import useUI from './use-ui'
|
|
32
32
|
import useQm from './use-quick-commands'
|
|
33
33
|
import copy from 'json-deep-copy'
|
|
34
|
+
import renderTermBg from './render-bg'
|
|
34
35
|
import { defaults } from 'lodash-es'
|
|
35
36
|
import { getRandomDefaultColor } from '../../common/rand-hex-color.js'
|
|
36
37
|
import { ColorPickerItem } from './color-picker-item.jsx'
|
|
@@ -283,7 +284,12 @@ export default function SerialFormUi (props) {
|
|
|
283
284
|
key: 'settings',
|
|
284
285
|
label: e('settings'),
|
|
285
286
|
forceRender: true,
|
|
286
|
-
children:
|
|
287
|
+
children: (
|
|
288
|
+
<>
|
|
289
|
+
{uis}
|
|
290
|
+
{renderTermBg(form)}
|
|
291
|
+
</>
|
|
292
|
+
)
|
|
287
293
|
},
|
|
288
294
|
{
|
|
289
295
|
key: 'quickCommands',
|
|
@@ -16,16 +16,18 @@ import useSubmit from './use-submit'
|
|
|
16
16
|
import useUI from './use-ui'
|
|
17
17
|
import useQm from './use-quick-commands'
|
|
18
18
|
import copy from 'json-deep-copy'
|
|
19
|
-
import { defaultsDeep } from 'lodash-es'
|
|
19
|
+
import { defaultsDeep, pick } from 'lodash-es'
|
|
20
20
|
import renderTabs from './form-tabs'
|
|
21
21
|
import renderCommon from './form-ssh-common'
|
|
22
22
|
import renderEnableSftp from './sftp-enable'
|
|
23
23
|
import renderProxy from './proxy'
|
|
24
24
|
import renderX11 from './x11'
|
|
25
25
|
import renderAuth from './render-auth-ssh'
|
|
26
|
+
import renderTermBg from './render-bg'
|
|
26
27
|
import renderSshTunnel from './render-ssh-tunnel'
|
|
27
28
|
import renderConnectionHopping from './render-connection-hopping'
|
|
28
29
|
import { getRandomDefaultColor } from '../../common/rand-hex-color.js'
|
|
30
|
+
import defaultSetting from '../../common/default-setting'
|
|
29
31
|
import './bookmark-form.styl'
|
|
30
32
|
|
|
31
33
|
export default function BookmarkFormUI (props) {
|
|
@@ -71,7 +73,15 @@ export default function BookmarkFormUI (props) {
|
|
|
71
73
|
category: initBookmarkGroupId,
|
|
72
74
|
connectionHoppings: [],
|
|
73
75
|
serverHostKey: [],
|
|
74
|
-
cipher: []
|
|
76
|
+
cipher: [],
|
|
77
|
+
terminalBackground: pick(defaultSetting, [
|
|
78
|
+
'terminalBackgroundImagePath',
|
|
79
|
+
'terminalBackgroundFilterOpacity',
|
|
80
|
+
'terminalBackgroundFilterBlur',
|
|
81
|
+
'terminalBackgroundFilterBrightness',
|
|
82
|
+
'terminalBackgroundFilterGrayscale',
|
|
83
|
+
'terminalBackgroundFilterContrast'
|
|
84
|
+
])
|
|
75
85
|
}
|
|
76
86
|
initialValues = defaultsDeep(initialValues, defaultValues)
|
|
77
87
|
function onChangeAuthType (e) {
|
|
@@ -90,7 +100,8 @@ export default function BookmarkFormUI (props) {
|
|
|
90
100
|
renderX11,
|
|
91
101
|
renderAuth,
|
|
92
102
|
renderSshTunnel,
|
|
93
|
-
renderConnectionHopping
|
|
103
|
+
renderConnectionHopping,
|
|
104
|
+
renderTermBg
|
|
94
105
|
}
|
|
95
106
|
return (
|
|
96
107
|
<Form
|
|
@@ -20,6 +20,7 @@ import useSubmit from './use-submit'
|
|
|
20
20
|
import useUI from './use-ui'
|
|
21
21
|
import useQm from './use-quick-commands'
|
|
22
22
|
import renderCommon from './form-ssh-common'
|
|
23
|
+
import renderTermBg from './render-bg'
|
|
23
24
|
import { getRandomDefaultColor } from '../../common/rand-hex-color.js'
|
|
24
25
|
import copy from 'json-deep-copy'
|
|
25
26
|
import { defaultsDeep, isEmpty } from 'lodash-es'
|
|
@@ -104,7 +105,12 @@ export default function TelnetFormUI (props) {
|
|
|
104
105
|
key: 'settings',
|
|
105
106
|
label: e('settings'),
|
|
106
107
|
forceRender: true,
|
|
107
|
-
children:
|
|
108
|
+
children: (
|
|
109
|
+
<>
|
|
110
|
+
{uis}
|
|
111
|
+
{renderTermBg(form)}
|
|
112
|
+
</>
|
|
113
|
+
)
|
|
108
114
|
},
|
|
109
115
|
{
|
|
110
116
|
key: 'quickCommands',
|