dsh-remote-workspaces 0.1.0 → 0.1.1
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/package.json +1 -1
- package/src/client.js +139 -40
package/package.json
CHANGED
package/src/client.js
CHANGED
|
@@ -75,15 +75,81 @@ window.__ModuleLoader__.load({
|
|
|
75
75
|
var exports = module.exports
|
|
76
76
|
var React = require('react')
|
|
77
77
|
|
|
78
|
-
var sectionStyle = { padding: 16, fontSize: 14, lineHeight: 1.6, maxWidth: 820 }
|
|
79
|
-
var labelStyle = { color: '
|
|
78
|
+
var sectionStyle = { padding: 16, fontSize: 14, lineHeight: 1.6, maxWidth: 820, color: 'inherit' }
|
|
79
|
+
var labelStyle = { color: '#8b8f98', margin: 0, fontSize: 12.5 }
|
|
80
80
|
var monoStyle = { fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Consolas, monospace', fontSize: 12.5 }
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
var
|
|
86
|
-
|
|
81
|
+
// Control styling mirrors the "网关接入 → 查询状态" button (plugins/
|
|
82
|
+
// dsh-gateway-agent): neutral translucent surfaces + `color: inherit` so the
|
|
83
|
+
// text follows the host theme in both dark and light themes. The primary
|
|
84
|
+
// button is a fixed brand fill, matching the reference's S.primary.
|
|
85
|
+
var btnStyle = {
|
|
86
|
+
padding: '7px 14px', fontSize: 13.5, cursor: 'pointer',
|
|
87
|
+
background: 'rgba(127,127,127,0.12)', color: 'inherit',
|
|
88
|
+
border: '1px solid rgba(127,127,127,0.3)', borderRadius: 6, whiteSpace: 'nowrap',
|
|
89
|
+
}
|
|
90
|
+
var mobileBtnStyle = {
|
|
91
|
+
padding: '11px 14px', fontSize: 14, cursor: 'pointer',
|
|
92
|
+
background: 'rgba(127,127,127,0.12)', color: 'inherit',
|
|
93
|
+
border: '1px solid rgba(127,127,127,0.3)', borderRadius: 6, minHeight: 44, whiteSpace: 'nowrap',
|
|
94
|
+
}
|
|
95
|
+
var btnPrim = {
|
|
96
|
+
padding: '7px 14px', fontSize: 13.5, cursor: 'pointer',
|
|
97
|
+
background: '#6e56cf', color: '#fff', border: '1px solid transparent',
|
|
98
|
+
borderRadius: 6, fontWeight: 600, whiteSpace: 'nowrap',
|
|
99
|
+
}
|
|
100
|
+
var btnPrimMob = {
|
|
101
|
+
padding: '11px 14px', fontSize: 14, cursor: 'pointer',
|
|
102
|
+
background: '#6e56cf', color: '#fff', border: '1px solid transparent',
|
|
103
|
+
borderRadius: 6, fontWeight: 600, minHeight: 44, whiteSpace: 'nowrap',
|
|
104
|
+
}
|
|
105
|
+
var btnDanger = {
|
|
106
|
+
padding: '7px 14px', fontSize: 13.5, cursor: 'pointer',
|
|
107
|
+
background: '#e5484d', color: '#fff', border: '1px solid transparent',
|
|
108
|
+
borderRadius: 6, fontWeight: 600, whiteSpace: 'nowrap',
|
|
109
|
+
}
|
|
110
|
+
var btnDangerMob = {
|
|
111
|
+
padding: '11px 14px', fontSize: 14, cursor: 'pointer',
|
|
112
|
+
background: '#e5484d', color: '#fff', border: '1px solid transparent',
|
|
113
|
+
borderRadius: 6, fontWeight: 600, minHeight: 44, whiteSpace: 'nowrap',
|
|
114
|
+
}
|
|
115
|
+
var inputStyle = {
|
|
116
|
+
padding: '7px 10px', fontSize: 13.5, width: '100%', boxSizing: 'border-box',
|
|
117
|
+
background: 'rgba(127,127,127,0.08)', color: 'inherit',
|
|
118
|
+
border: '1px solid rgba(127,127,127,0.3)', borderRadius: 6,
|
|
119
|
+
}
|
|
120
|
+
var mobileInputStyle = {
|
|
121
|
+
padding: '9px 12px', fontSize: 16, width: '100%', boxSizing: 'border-box', minHeight: 44,
|
|
122
|
+
background: 'rgba(127,127,127,0.08)', color: 'inherit',
|
|
123
|
+
border: '1px solid rgba(127,127,127,0.3)', borderRadius: 6,
|
|
124
|
+
}
|
|
125
|
+
var mobileSectionStyle = { padding: 12, fontSize: 14, lineHeight: 1.6, color: 'inherit' }
|
|
126
|
+
var dangerColor = '#e5484d'
|
|
127
|
+
var successColor = '#46a758'
|
|
128
|
+
var borderColor = 'rgba(127,127,127,0.3)'
|
|
129
|
+
var modalBg = '#1f1f21'
|
|
130
|
+
var modalText = '#e8e8e8'
|
|
131
|
+
var chipStyle = { display: 'inline-block', padding: '1px 8px', borderRadius: 10, background: 'rgba(127,127,127,0.18)', fontSize: 11.5, lineHeight: '18px', color: 'inherit' }
|
|
132
|
+
|
|
133
|
+
// Detect a narrow (mobile) viewport so the UI can switch to a stacked,
|
|
134
|
+
// larger-touch-target layout. Pure clickable hooks; no CSS build step.
|
|
135
|
+
function useIsMobile() {
|
|
136
|
+
var state = React.useState(false)
|
|
137
|
+
var matches = state[0]
|
|
138
|
+
var setMatches = state[1]
|
|
139
|
+
React.useEffect(function () {
|
|
140
|
+
if (typeof window === 'undefined' || !window.matchMedia) return
|
|
141
|
+
var mq = window.matchMedia('(max-width: 640px)')
|
|
142
|
+
function onChange(e) { setMatches(e.matches) }
|
|
143
|
+
setMatches(mq.matches)
|
|
144
|
+
if (mq.addEventListener) mq.addEventListener('change', onChange)
|
|
145
|
+
else if (mq.addListener) mq.addListener(onChange)
|
|
146
|
+
return function () {
|
|
147
|
+
if (mq.removeEventListener) mq.removeEventListener('change', onChange)
|
|
148
|
+
else if (mq.removeListener) mq.removeListener(onChange)
|
|
149
|
+
}
|
|
150
|
+
}, [])
|
|
151
|
+
return matches
|
|
152
|
+
}
|
|
87
153
|
|
|
88
154
|
function pathBasename(p) {
|
|
89
155
|
if (!p) return ''
|
|
@@ -135,6 +201,7 @@ window.__ModuleLoader__.load({
|
|
|
135
201
|
var deletingState = React.useState(false)
|
|
136
202
|
var deleting = deletingState[0]
|
|
137
203
|
var setDeleting = deletingState[1]
|
|
204
|
+
var isMobile = useIsMobile()
|
|
138
205
|
|
|
139
206
|
React.useEffect(function () {
|
|
140
207
|
var alive = true
|
|
@@ -285,7 +352,7 @@ window.__ModuleLoader__.load({
|
|
|
285
352
|
|
|
286
353
|
return React.createElement(
|
|
287
354
|
'div',
|
|
288
|
-
{ style: sectionStyle },
|
|
355
|
+
{ className: 'dsh-rw-btn', style: isMobile ? mobileSectionStyle : sectionStyle },
|
|
289
356
|
React.createElement('div', { style: { fontWeight: 600, fontSize: 16, marginBottom: 8 } }, '远程工作区'),
|
|
290
357
|
React.createElement('p', { style: { margin: '0 0 12px' } },
|
|
291
358
|
'管理 SSH 主机与已打开的远程工作区。添加远程工作区请在侧边栏「添加工作区」里选「远程目录」。'),
|
|
@@ -295,9 +362,9 @@ window.__ModuleLoader__.load({
|
|
|
295
362
|
error !== null
|
|
296
363
|
? React.createElement('p', { style: { color: dangerColor, margin: '0 0 12px' } }, error)
|
|
297
364
|
: null,
|
|
298
|
-
React.createElement('div', { style: { display: 'flex', gap: 8, marginBottom: 12 } },
|
|
299
|
-
React.createElement('button', { type: 'button', onClick: openNew, disabled: !remote, style:
|
|
300
|
-
React.createElement('button', { type: 'button', onClick: toggleAliases, disabled: !remote, style: btnStyle }, '从 ~/.ssh/config 导入'),
|
|
365
|
+
React.createElement('div', { style: Object.assign({ display: 'flex', gap: 8, marginBottom: 12, flexWrap: 'wrap' }, isMobile ? { flexDirection: 'column' } : {}) },
|
|
366
|
+
React.createElement('button', { type: 'button', onClick: openNew, disabled: !remote, style: Object.assign({}, btnPrim, isMobile ? btnPrimMob : {}) }, '添加主机'),
|
|
367
|
+
React.createElement('button', { type: 'button', onClick: toggleAliases, disabled: !remote, style: Object.assign({}, btnStyle, isMobile ? mobileBtnStyle : {}) }, '从 ~/.ssh/config 导入'),
|
|
301
368
|
),
|
|
302
369
|
showAliases
|
|
303
370
|
? React.createElement('div', { style: { border: '1px solid ' + borderColor, borderRadius: 6, padding: 10, marginBottom: 12 } },
|
|
@@ -334,18 +401,19 @@ window.__ModuleLoader__.load({
|
|
|
334
401
|
function () { doTest(machine) },
|
|
335
402
|
function () { openEdit(machine) },
|
|
336
403
|
function () { doDelete(machine) },
|
|
404
|
+
isMobile,
|
|
337
405
|
)
|
|
338
406
|
}),
|
|
339
407
|
),
|
|
340
408
|
deleteTarget !== null
|
|
341
|
-
? React.createElement('div', { style: { position: 'fixed', inset: 0, background: 'rgba(0,0,0,0.45)', display: 'flex', alignItems: 'center', justifyContent: 'center', zIndex: 10000 } },
|
|
342
|
-
React.createElement('div', { style: { background:
|
|
409
|
+
? React.createElement('div', { style: { position: 'fixed', inset: 0, background: 'rgba(0,0,0,0.45)', display: 'flex', alignItems: 'center', justifyContent: 'center', zIndex: 10000, padding: 16 } },
|
|
410
|
+
React.createElement('div', { style: { background: modalBg, border: '1px solid ' + borderColor, borderRadius: 8, padding: isMobile ? 14 : 16, width: 440, maxWidth: '100%', color: modalText } },
|
|
343
411
|
React.createElement('div', { style: { fontWeight: 600, fontSize: 15, marginBottom: 10 } }, '删除主机'),
|
|
344
412
|
React.createElement('p', { style: { margin: '0 0 12px', lineHeight: 1.6 } },
|
|
345
413
|
'确定删除主机「' + (deleteTarget.alias || deleteTarget.host) + '」吗?(远端数据不受影响)'),
|
|
346
|
-
React.createElement('div', { style: { display: 'flex', gap: 8, justifyContent: 'flex-end' } },
|
|
347
|
-
React.createElement('button', { type: 'button', onClick: closeDelete, disabled: deleting, style: btnStyle }, '取消'),
|
|
348
|
-
React.createElement('button', { type: 'button', onClick: confirmDelete, disabled: deleting, style:
|
|
414
|
+
React.createElement('div', { style: Object.assign({ display: 'flex', gap: 8, justifyContent: 'flex-end' }, isMobile ? { flexDirection: 'column' } : {}) },
|
|
415
|
+
React.createElement('button', { type: 'button', onClick: closeDelete, disabled: deleting, style: Object.assign({}, btnStyle, isMobile ? mobileBtnStyle : {}) }, '取消'),
|
|
416
|
+
React.createElement('button', { type: 'button', onClick: confirmDelete, disabled: deleting, style: isMobile ? btnDangerMob : btnDanger }, deleting ? '删除中…' : '删除'),
|
|
349
417
|
),
|
|
350
418
|
),
|
|
351
419
|
)
|
|
@@ -353,22 +421,33 @@ window.__ModuleLoader__.load({
|
|
|
353
421
|
)
|
|
354
422
|
}
|
|
355
423
|
|
|
356
|
-
function MachineRow(machine, result, open, onToggle, onTest, onEdit, onDelete) {
|
|
424
|
+
function MachineRow(machine, result, open, onToggle, onTest, onEdit, onDelete, isMobile) {
|
|
357
425
|
var summary = [machine.alias || '(未命名)']
|
|
358
426
|
if (machine.host) summary.push(machine.host)
|
|
359
427
|
if (machine.user) summary.push('@' + machine.user)
|
|
360
428
|
if (machine.port) summary.push(':' + machine.port)
|
|
429
|
+
var mobileBtn = isMobile ? Object.assign({}, mobileBtnStyle) : btnStyle
|
|
430
|
+
var dangerBtn = isMobile ? btnDangerMob : btnDanger
|
|
431
|
+
function action(label, handler, style) {
|
|
432
|
+
return React.createElement('button', { type: 'button', onClick: function (e) { e.stopPropagation(); handler() }, style: style }, label)
|
|
433
|
+
}
|
|
434
|
+
var testBtn = action('测试连接', onTest, mobileBtn)
|
|
435
|
+
var editBtn = action('编辑', onEdit, mobileBtn)
|
|
436
|
+
var deleteBtn = action('删除', onDelete, dangerBtn)
|
|
361
437
|
return React.createElement(
|
|
362
438
|
'div',
|
|
363
439
|
{ style: { borderTop: '1px solid ' + borderColor, padding: '8px 0' } },
|
|
364
440
|
React.createElement('div', { onClick: onToggle, style: { display: 'flex', alignItems: 'center', gap: 8, cursor: 'pointer' } },
|
|
365
|
-
React.createElement('span', { style: { color: '
|
|
441
|
+
React.createElement('span', { style: { color: '#8b8f98', width: 16, flexShrink: 0 } }, open ? '▾' : '▸'),
|
|
366
442
|
React.createElement('span', { style: Object.assign({}, monoStyle, { fontWeight: 600, minWidth: 0, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }) }, summary.join(' ')),
|
|
367
443
|
React.createElement('span', { style: { flex: 1 } }),
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
444
|
+
isMobile ? null : testBtn,
|
|
445
|
+
isMobile ? null : editBtn,
|
|
446
|
+
isMobile ? null : deleteBtn,
|
|
371
447
|
),
|
|
448
|
+
isMobile
|
|
449
|
+
? React.createElement('div', { style: { display: 'flex', gap: 8, marginTop: 6, paddingLeft: 24, flexWrap: 'wrap' } }, testBtn, editBtn, deleteBtn)
|
|
450
|
+
: null,
|
|
372
451
|
React.createElement('div', { style: { display: 'flex', gap: 6, marginTop: 4, flexWrap: 'wrap', paddingLeft: 24 } },
|
|
373
452
|
machine.identityFile
|
|
374
453
|
? React.createElement('span', { title: '私钥:' + machine.identityFile, style: chipStyle }, '私钥 ' + pathBasename(machine.identityFile))
|
|
@@ -403,6 +482,7 @@ window.__ModuleLoader__.load({
|
|
|
403
482
|
})
|
|
404
483
|
var values = valuesState[0]
|
|
405
484
|
var setValues = valuesState[1]
|
|
485
|
+
var isMobile = useIsMobile()
|
|
406
486
|
|
|
407
487
|
function set(field) {
|
|
408
488
|
return function (e) {
|
|
@@ -420,13 +500,15 @@ window.__ModuleLoader__.load({
|
|
|
420
500
|
function field(label, name, type, placeholder) {
|
|
421
501
|
return React.createElement('div', { style: { marginBottom: 8 } },
|
|
422
502
|
React.createElement('div', { style: labelStyle }, label),
|
|
423
|
-
React.createElement('input', { type: type || 'text', value: values[name], onChange: set(name), placeholder: placeholder || '', style: inputStyle }),
|
|
503
|
+
React.createElement('input', { type: type || 'text', value: values[name], onChange: set(name), placeholder: placeholder || '', style: isMobile ? mobileInputStyle : inputStyle }),
|
|
424
504
|
)
|
|
425
505
|
}
|
|
426
506
|
|
|
507
|
+
var formBtn = isMobile ? mobileBtnStyle : btnStyle
|
|
508
|
+
var formBtnPrim = isMobile ? btnPrimMob : btnPrim
|
|
427
509
|
return React.createElement(
|
|
428
510
|
'form',
|
|
429
|
-
{ onSubmit: submit, style: { border: '1px solid ' + borderColor, borderRadius: 6, padding: 12, marginBottom: 12 } },
|
|
511
|
+
{ onSubmit: submit, style: { border: '1px solid ' + borderColor, borderRadius: 6, padding: isMobile ? 10 : 12, marginBottom: 12 } },
|
|
430
512
|
React.createElement('div', { style: { fontWeight: 600, marginBottom: 8 } }, props.form.isNew ? '添加主机' : '编辑主机'),
|
|
431
513
|
field('别名(alias)', 'alias', 'text', '如 dev'),
|
|
432
514
|
field('主机地址(host)', 'host', 'text', '如 192.168.1.10 或 example.com'),
|
|
@@ -435,9 +517,9 @@ window.__ModuleLoader__.load({
|
|
|
435
517
|
field('私钥路径(identityFile)', 'identityFile', 'text', '如 ~/.ssh/id_rsa,留空用默认密钥'),
|
|
436
518
|
field('密码(password)', 'password', 'password', props.form.isNew ? '可选' : '留空保持不变,输入则替换'),
|
|
437
519
|
field('私钥口令(passphrase)', 'passphrase', 'password', props.form.isNew ? '可选' : '留空保持不变'),
|
|
438
|
-
React.createElement('div', { style: { display: 'flex', gap: 8, marginTop: 4 } },
|
|
439
|
-
React.createElement('button', { type: 'submit', style:
|
|
440
|
-
React.createElement('button', { type: 'button', onClick: props.onCancel, style:
|
|
520
|
+
React.createElement('div', { style: Object.assign({ display: 'flex', gap: 8, marginTop: 4 }, isMobile ? { flexDirection: 'column' } : {}) },
|
|
521
|
+
React.createElement('button', { type: 'submit', style: formBtnPrim }, '保存'),
|
|
522
|
+
React.createElement('button', { type: 'button', onClick: props.onCancel, style: formBtn }, '取消'),
|
|
441
523
|
),
|
|
442
524
|
)
|
|
443
525
|
}
|
|
@@ -477,7 +559,7 @@ window.__ModuleLoader__.load({
|
|
|
477
559
|
background: hover ? 'rgba(127,127,127,0.16)' : 'transparent',
|
|
478
560
|
fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Consolas, monospace',
|
|
479
561
|
fontSize: 13,
|
|
480
|
-
color: entry.dir ? '
|
|
562
|
+
color: entry.dir ? 'inherit' : 'rgba(232,232,232,0.55)',
|
|
481
563
|
}
|
|
482
564
|
return React.createElement(
|
|
483
565
|
'div',
|
|
@@ -490,7 +572,7 @@ window.__ModuleLoader__.load({
|
|
|
490
572
|
},
|
|
491
573
|
React.createElement('span', { style: { width: 18, textAlign: 'center', flexShrink: 0 } }, entry.dir ? '📁' : '📄'),
|
|
492
574
|
React.createElement('span', { style: { flex: 1, minWidth: 0, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' } }, entry.name),
|
|
493
|
-
entry.dir ? React.createElement('span', { style: { color: '
|
|
575
|
+
entry.dir ? React.createElement('span', { style: { color: '#8b8f98', flexShrink: 0 } }, '/') : null,
|
|
494
576
|
)
|
|
495
577
|
}
|
|
496
578
|
|
|
@@ -527,6 +609,7 @@ window.__ModuleLoader__.load({
|
|
|
527
609
|
var pathInputState = React.useState('')
|
|
528
610
|
var pathInput = pathInputState[0]
|
|
529
611
|
var setPathInput = pathInputState[1]
|
|
612
|
+
var isMobile = useIsMobile()
|
|
530
613
|
|
|
531
614
|
// Reset per open edge, then load machines.
|
|
532
615
|
React.useEffect(function () {
|
|
@@ -636,20 +719,20 @@ window.__ModuleLoader__.load({
|
|
|
636
719
|
{ style: { position: 'fixed', inset: 0, background: 'rgba(0,0,0,0.45)', display: 'flex', alignItems: 'center', justifyContent: 'center', zIndex: 10000 } },
|
|
637
720
|
React.createElement(
|
|
638
721
|
'div',
|
|
639
|
-
{ style: { background:
|
|
722
|
+
{ className: 'dsh-rw-btn', style: { background: modalBg, border: '1px solid ' + borderColor, borderRadius: 8, padding: isMobile ? 14 : 16, width: 560, maxWidth: '92vw', maxHeight: '82vh', overflow: 'auto', color: modalText } },
|
|
640
723
|
React.createElement('div', { style: { display: 'flex', alignItems: 'center', marginBottom: 12 } },
|
|
641
724
|
React.createElement('span', { style: { fontWeight: 600, fontSize: 15 } }, '打开文件夹'),
|
|
642
725
|
React.createElement('span', { style: { flex: 1 } }),
|
|
643
|
-
React.createElement('button', { type: 'button', onClick: onCancel, style: btnStyle }, '取消'),
|
|
726
|
+
React.createElement('button', { type: 'button', onClick: onCancel, style: isMobile ? mobileBtnStyle : btnStyle }, '取消'),
|
|
644
727
|
),
|
|
645
728
|
React.createElement('div', { style: { display: 'flex', gap: 8, marginBottom: 12 } },
|
|
646
|
-
React.createElement('button', { type: 'button', onClick: function () { setMode('local') }, style: Object.assign({}, btnStyle, mode === 'local' ? { border: '
|
|
647
|
-
React.createElement('button', { type: 'button', onClick: function () { setMode('remote') }, style: Object.assign({}, btnStyle, mode === 'remote' ? { border: '
|
|
729
|
+
React.createElement('button', { type: 'button', onClick: function () { setMode('local') }, style: Object.assign({}, btnStyle, isMobile ? { flex: 1 } : {}, isMobile ? mobileBtnStyle : {}, mode === 'local' ? { background: '#6e56cf', color: '#fff', border: '1px solid transparent' } : {}) }, '本地文件夹'),
|
|
730
|
+
React.createElement('button', { type: 'button', onClick: function () { setMode('remote') }, style: Object.assign({}, btnStyle, isMobile ? { flex: 1 } : {}, isMobile ? mobileBtnStyle : {}, mode === 'remote' ? { background: '#6e56cf', color: '#fff', border: '1px solid transparent' } : {}) }, '远程目录'),
|
|
648
731
|
),
|
|
649
732
|
mode === 'local'
|
|
650
733
|
? React.createElement('div', {},
|
|
651
734
|
React.createElement('p', { style: { margin: '0 0 12px' } }, '在本机打开系统文件夹选择器,选取一个本地目录作为工作区。'),
|
|
652
|
-
React.createElement('button', { type: 'button', onClick: doLocal, disabled: localPicking || busy, style: btnStyle }, localPicking ? '等待选择…' : '选择本地文件夹'),
|
|
735
|
+
React.createElement('button', { type: 'button', onClick: doLocal, disabled: localPicking || busy, style: Object.assign({}, btnStyle, isMobile ? { width: '100%' } : {}, isMobile ? mobileBtnStyle : {}) }, localPicking ? '等待选择…' : '选择本地文件夹'),
|
|
653
736
|
)
|
|
654
737
|
: React.createElement('div', {},
|
|
655
738
|
React.createElement('div', { style: { marginBottom: 8 } }, '选择 SSH 主机(在「设置 → 远程工作区」中配置):'),
|
|
@@ -662,7 +745,7 @@ window.__ModuleLoader__.load({
|
|
|
662
745
|
var m = machines.find(function (x) { return x.id === id })
|
|
663
746
|
if (m) pickMachine(m)
|
|
664
747
|
},
|
|
665
|
-
style: Object.assign({}, inputStyle, { marginBottom: 8 }),
|
|
748
|
+
style: Object.assign({}, isMobile ? mobileInputStyle : inputStyle, { marginBottom: 8 }),
|
|
666
749
|
},
|
|
667
750
|
React.createElement('option', { value: '' }, '选择主机…'),
|
|
668
751
|
machines.map(function (m) {
|
|
@@ -671,7 +754,7 @@ window.__ModuleLoader__.load({
|
|
|
671
754
|
),
|
|
672
755
|
selected
|
|
673
756
|
? React.createElement('div', { style: { border: '1px solid ' + borderColor, borderRadius: 6, padding: 10 } },
|
|
674
|
-
React.createElement('div', { style: { display: 'flex', alignItems: 'center', gap: 8, marginBottom: 8 } },
|
|
757
|
+
React.createElement('div', { style: { display: 'flex', alignItems: 'center', gap: 8, marginBottom: 8, flexWrap: 'wrap' } },
|
|
675
758
|
React.createElement('input', {
|
|
676
759
|
type: 'text',
|
|
677
760
|
value: pathInput,
|
|
@@ -679,10 +762,12 @@ window.__ModuleLoader__.load({
|
|
|
679
762
|
onKeyDown: function (e) { if (e.key === 'Enter') jumpTo() },
|
|
680
763
|
placeholder: '输入绝对路径,或 ~ 回到主目录',
|
|
681
764
|
spellCheck: false,
|
|
682
|
-
style: Object.assign({}, monoStyle,
|
|
765
|
+
style: Object.assign({}, monoStyle, isMobile
|
|
766
|
+
? { flex: '1 1 100%', minWidth: 0, padding: '9px 8px', fontSize: 16, boxSizing: 'border-box' }
|
|
767
|
+
: { flex: 1, minWidth: 0, padding: '5px 8px', fontSize: 13, boxSizing: 'border-box' }),
|
|
683
768
|
}),
|
|
684
|
-
React.createElement('button', { type: 'button', onClick: jumpTo, disabled: !browse || browse.loading, style: btnStyle }, '跳转'),
|
|
685
|
-
React.createElement('button', { type: 'button', onClick: goUp, disabled: !browse || browse.loading || !browse.path || browse.path === '/', style: btnStyle }, '上一级'),
|
|
769
|
+
React.createElement('button', { type: 'button', onClick: jumpTo, disabled: !browse || browse.loading, style: Object.assign({}, btnStyle, isMobile ? { flex: 1 } : {}, isMobile ? mobileBtnStyle : {}) }, '跳转'),
|
|
770
|
+
React.createElement('button', { type: 'button', onClick: goUp, disabled: !browse || browse.loading || !browse.path || browse.path === '/', style: Object.assign({}, btnStyle, isMobile ? { flex: 1 } : {}, isMobile ? mobileBtnStyle : {}) }, '上一级'),
|
|
686
771
|
),
|
|
687
772
|
browse && browse.loading
|
|
688
773
|
? React.createElement('div', { style: labelStyle }, '加载中…')
|
|
@@ -701,7 +786,7 @@ window.__ModuleLoader__.load({
|
|
|
701
786
|
)
|
|
702
787
|
: null,
|
|
703
788
|
React.createElement('div', { style: { marginTop: 10 } },
|
|
704
|
-
React.createElement('button', { type: 'button', onClick: doOpenRemote, disabled: opening || busy || (browse && browse.loading), style:
|
|
789
|
+
React.createElement('button', { type: 'button', onClick: doOpenRemote, disabled: opening || busy || (browse && browse.loading), style: Object.assign({}, btnPrim, isMobile ? { width: '100%' } : {}, isMobile ? btnPrimMob : {}) },
|
|
705
790
|
opening ? '打开中…' : '打开此目录'),
|
|
706
791
|
),
|
|
707
792
|
)
|
|
@@ -714,6 +799,20 @@ window.__ModuleLoader__.load({
|
|
|
714
799
|
exports.inject = ['slots', 'remote', 'uiWorkspace']
|
|
715
800
|
|
|
716
801
|
exports.apply = function apply(ctx) {
|
|
802
|
+
// Inject a small set of theme-aware control styles (hover / focus /
|
|
803
|
+
// disabled). Backgrounds are deliberately left to the theme so buttons
|
|
804
|
+
// adapt to dark and light instead of forcing a hard-coded box.
|
|
805
|
+
if (typeof document !== 'undefined' && document.head && !document.getElementById('dsh-rw-controls')) {
|
|
806
|
+
var styleEl = document.createElement('style')
|
|
807
|
+
styleEl.id = 'dsh-rw-controls'
|
|
808
|
+
styleEl.textContent = [
|
|
809
|
+
'.dsh-rw-btn button:disabled{opacity:.5;cursor:not-allowed}',
|
|
810
|
+
'.dsh-rw-btn button:focus-visible{outline:2px solid #6e56cf;outline-offset:2px}',
|
|
811
|
+
'.dsh-rw-btn input:focus,.dsh-rw-btn select:focus{box-shadow:0 0 0 1px #6e56cf}',
|
|
812
|
+
].join('\n')
|
|
813
|
+
document.head.appendChild(styleEl)
|
|
814
|
+
}
|
|
815
|
+
|
|
717
816
|
var mount = ctx.remote.$mount({ package: PACKAGE, descriptors: INVOCATIONS })
|
|
718
817
|
var getRemote = function () { return ctx.get('remote.' + NAMESPACE) }
|
|
719
818
|
|