@minato-aqukin/autodl-cli 0.1.2 → 0.2.0
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/README.md +61 -6
- package/README.zh-CN.md +55 -5
- package/dist/{app-3QXI65BE.js → app-V5GCG3MC.js} +1641 -208
- package/dist/chunk-2E2Y5GFH.js +1704 -0
- package/dist/{chunk-6QR4ZYQR.js → chunk-GHJVQKKC.js} +78 -32
- package/dist/{chunk-DLCDJE6I.js → chunk-JOOIUQLJ.js} +4 -4
- package/dist/{chunk-BMKVXRT7.js → chunk-MWYYK755.js} +4 -4
- package/dist/{chunk-NBWWTYSL.js → chunk-VEDMEYCW.js} +2 -2
- package/dist/{chunk-GJGHX55T.js → chunk-WN2CXPD2.js} +2 -2
- package/dist/cli.js +289 -22
- package/dist/index.d.ts +11 -2
- package/dist/index.js +6 -4
- package/dist/{tui-2JGNYYRA.js → tui-ZT5ZBVSQ.js} +4 -4
- package/package.json +1 -1
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire as __nodeCreateRequire } from "node:module";
|
|
3
3
|
const require = __nodeCreateRequire(import.meta.url);
|
|
4
|
+
import {
|
|
5
|
+
FileWorkspace,
|
|
6
|
+
TransferQueue,
|
|
7
|
+
connectTerminal,
|
|
8
|
+
identityFromToken,
|
|
9
|
+
tokenOverrideNote
|
|
10
|
+
} from "./chunk-2E2Y5GFH.js";
|
|
4
11
|
import {
|
|
5
12
|
BASE_IMAGES,
|
|
6
13
|
DEFAULT_BASE_IMAGE,
|
|
@@ -11,9 +18,10 @@ import {
|
|
|
11
18
|
getBalance,
|
|
12
19
|
getStockByRegion,
|
|
13
20
|
parseCudaVersion
|
|
14
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-WN2CXPD2.js";
|
|
15
22
|
import {
|
|
16
23
|
AutoDLClient,
|
|
24
|
+
DEFAULT_BASE_URL,
|
|
17
25
|
__commonJS,
|
|
18
26
|
__export,
|
|
19
27
|
__require,
|
|
@@ -29,6 +37,7 @@ import {
|
|
|
29
37
|
formatRate,
|
|
30
38
|
formatTime,
|
|
31
39
|
formatYuan,
|
|
40
|
+
getCredentials,
|
|
32
41
|
getInstanceSnapshot,
|
|
33
42
|
getInstanceStatus,
|
|
34
43
|
isAuthError,
|
|
@@ -47,7 +56,7 @@ import {
|
|
|
47
56
|
tryResolveToken,
|
|
48
57
|
updateConfig,
|
|
49
58
|
waitForShutdown
|
|
50
|
-
} from "./chunk-
|
|
59
|
+
} from "./chunk-GHJVQKKC.js";
|
|
51
60
|
|
|
52
61
|
// node_modules/react/cjs/react.production.js
|
|
53
62
|
var require_react_production = __commonJS({
|
|
@@ -914,21 +923,21 @@ var require_react_development = __commonJS({
|
|
|
914
923
|
);
|
|
915
924
|
actScopeDepth = prevActScopeDepth;
|
|
916
925
|
}
|
|
917
|
-
function recursivelyFlushAsyncActWork(returnValue,
|
|
926
|
+
function recursivelyFlushAsyncActWork(returnValue, resolve2, reject) {
|
|
918
927
|
var queue = ReactSharedInternals.actQueue;
|
|
919
928
|
if (null !== queue)
|
|
920
929
|
if (0 !== queue.length)
|
|
921
930
|
try {
|
|
922
931
|
flushActQueue(queue);
|
|
923
932
|
enqueueTask(function() {
|
|
924
|
-
return recursivelyFlushAsyncActWork(returnValue,
|
|
933
|
+
return recursivelyFlushAsyncActWork(returnValue, resolve2, reject);
|
|
925
934
|
});
|
|
926
935
|
return;
|
|
927
936
|
} catch (error) {
|
|
928
937
|
ReactSharedInternals.thrownErrors.push(error);
|
|
929
938
|
}
|
|
930
939
|
else ReactSharedInternals.actQueue = null;
|
|
931
|
-
0 < ReactSharedInternals.thrownErrors.length ? (queue = aggregateErrors(ReactSharedInternals.thrownErrors), ReactSharedInternals.thrownErrors.length = 0, reject(queue)) :
|
|
940
|
+
0 < ReactSharedInternals.thrownErrors.length ? (queue = aggregateErrors(ReactSharedInternals.thrownErrors), ReactSharedInternals.thrownErrors.length = 0, reject(queue)) : resolve2(returnValue);
|
|
932
941
|
}
|
|
933
942
|
function flushActQueue(queue) {
|
|
934
943
|
if (!isFlushing) {
|
|
@@ -1115,7 +1124,7 @@ var require_react_development = __commonJS({
|
|
|
1115
1124
|
));
|
|
1116
1125
|
});
|
|
1117
1126
|
return {
|
|
1118
|
-
then: function(
|
|
1127
|
+
then: function(resolve2, reject) {
|
|
1119
1128
|
didAwaitActCall = true;
|
|
1120
1129
|
thenable.then(
|
|
1121
1130
|
function(returnValue) {
|
|
@@ -1125,7 +1134,7 @@ var require_react_development = __commonJS({
|
|
|
1125
1134
|
flushActQueue(queue), enqueueTask(function() {
|
|
1126
1135
|
return recursivelyFlushAsyncActWork(
|
|
1127
1136
|
returnValue,
|
|
1128
|
-
|
|
1137
|
+
resolve2,
|
|
1129
1138
|
reject
|
|
1130
1139
|
);
|
|
1131
1140
|
});
|
|
@@ -1139,7 +1148,7 @@ var require_react_development = __commonJS({
|
|
|
1139
1148
|
ReactSharedInternals.thrownErrors.length = 0;
|
|
1140
1149
|
reject(_thrownError);
|
|
1141
1150
|
}
|
|
1142
|
-
} else
|
|
1151
|
+
} else resolve2(returnValue);
|
|
1143
1152
|
},
|
|
1144
1153
|
function(error) {
|
|
1145
1154
|
popActScope(prevActQueue, prevActScopeDepth);
|
|
@@ -1161,15 +1170,15 @@ var require_react_development = __commonJS({
|
|
|
1161
1170
|
if (0 < ReactSharedInternals.thrownErrors.length)
|
|
1162
1171
|
throw callback = aggregateErrors(ReactSharedInternals.thrownErrors), ReactSharedInternals.thrownErrors.length = 0, callback;
|
|
1163
1172
|
return {
|
|
1164
|
-
then: function(
|
|
1173
|
+
then: function(resolve2, reject) {
|
|
1165
1174
|
didAwaitActCall = true;
|
|
1166
1175
|
0 === prevActScopeDepth ? (ReactSharedInternals.actQueue = queue, enqueueTask(function() {
|
|
1167
1176
|
return recursivelyFlushAsyncActWork(
|
|
1168
1177
|
returnValue$jscomp$0,
|
|
1169
|
-
|
|
1178
|
+
resolve2,
|
|
1170
1179
|
reject
|
|
1171
1180
|
);
|
|
1172
|
-
})) :
|
|
1181
|
+
})) : resolve2(returnValue$jscomp$0);
|
|
1173
1182
|
}
|
|
1174
1183
|
};
|
|
1175
1184
|
};
|
|
@@ -3253,8 +3262,8 @@ var require_react_reconciler_production = __commonJS({
|
|
|
3253
3262
|
currentEntangledActionThenable = {
|
|
3254
3263
|
status: "pending",
|
|
3255
3264
|
value: void 0,
|
|
3256
|
-
then: function(
|
|
3257
|
-
entangledListeners.push(
|
|
3265
|
+
then: function(resolve2) {
|
|
3266
|
+
entangledListeners.push(resolve2);
|
|
3258
3267
|
}
|
|
3259
3268
|
};
|
|
3260
3269
|
}
|
|
@@ -3277,8 +3286,8 @@ var require_react_reconciler_production = __commonJS({
|
|
|
3277
3286
|
status: "pending",
|
|
3278
3287
|
value: null,
|
|
3279
3288
|
reason: null,
|
|
3280
|
-
then: function(
|
|
3281
|
-
listeners.push(
|
|
3289
|
+
then: function(resolve2) {
|
|
3290
|
+
listeners.push(resolve2);
|
|
3282
3291
|
}
|
|
3283
3292
|
};
|
|
3284
3293
|
thenable.then(
|
|
@@ -12877,8 +12886,8 @@ var require_react_reconciler_development = __commonJS({
|
|
|
12877
12886
|
currentEntangledActionThenable = {
|
|
12878
12887
|
status: "pending",
|
|
12879
12888
|
value: void 0,
|
|
12880
|
-
then: function(
|
|
12881
|
-
entangledListeners.push(
|
|
12889
|
+
then: function(resolve2) {
|
|
12890
|
+
entangledListeners.push(resolve2);
|
|
12882
12891
|
}
|
|
12883
12892
|
};
|
|
12884
12893
|
}
|
|
@@ -12901,8 +12910,8 @@ var require_react_reconciler_development = __commonJS({
|
|
|
12901
12910
|
status: "pending",
|
|
12902
12911
|
value: null,
|
|
12903
12912
|
reason: null,
|
|
12904
|
-
then: function(
|
|
12905
|
-
listeners.push(
|
|
12913
|
+
then: function(resolve2) {
|
|
12914
|
+
listeners.push(resolve2);
|
|
12906
12915
|
}
|
|
12907
12916
|
};
|
|
12908
12917
|
thenable.then(
|
|
@@ -25031,6 +25040,9 @@ var require_jsx_runtime = __commonJS({
|
|
|
25031
25040
|
}
|
|
25032
25041
|
});
|
|
25033
25042
|
|
|
25043
|
+
// src/tui/app.tsx
|
|
25044
|
+
import { createHash } from "crypto";
|
|
25045
|
+
|
|
25034
25046
|
// node_modules/ink/build/render.js
|
|
25035
25047
|
import { Stream } from "stream";
|
|
25036
25048
|
import process13 from "process";
|
|
@@ -27678,21 +27690,21 @@ var getClosingSgrSequence = (activeStyles) => [...activeStyles].reverse().map((a
|
|
|
27678
27690
|
var getOpeningSgrSequence = (activeStyles) => activeStyles.map((activeStyle) => wrapAnsiCode(activeStyle.open)).join("");
|
|
27679
27691
|
var wrapWord = (rows, word, columns2, rowWidth2) => {
|
|
27680
27692
|
const tokens = getTokens(word);
|
|
27681
|
-
let
|
|
27693
|
+
let visible2 = rowWidth2;
|
|
27682
27694
|
for (let index = 0; index < tokens.length; index++) {
|
|
27683
27695
|
const token = tokens[index];
|
|
27684
|
-
if (token.width > 0 &&
|
|
27696
|
+
if (token.width > 0 && visible2 > 0 && visible2 + token.width > columns2) {
|
|
27685
27697
|
rows.push("");
|
|
27686
|
-
|
|
27698
|
+
visible2 = 0;
|
|
27687
27699
|
}
|
|
27688
27700
|
rows[rows.length - 1] += token.value;
|
|
27689
|
-
|
|
27690
|
-
if (
|
|
27701
|
+
visible2 += token.width;
|
|
27702
|
+
if (visible2 === columns2 && index < tokens.length - 1) {
|
|
27691
27703
|
rows.push("");
|
|
27692
|
-
|
|
27704
|
+
visible2 = 0;
|
|
27693
27705
|
}
|
|
27694
27706
|
}
|
|
27695
|
-
if (!
|
|
27707
|
+
if (!visible2 && rows.at(-1).length > 0 && rows.length > 1) {
|
|
27696
27708
|
rows[rows.length - 2] += rows.pop();
|
|
27697
27709
|
}
|
|
27698
27710
|
return getWidth(rows.at(-1));
|
|
@@ -27727,7 +27739,7 @@ var expandTabs = (line) => {
|
|
|
27727
27739
|
if (!line.includes(" ")) {
|
|
27728
27740
|
return line;
|
|
27729
27741
|
}
|
|
27730
|
-
let
|
|
27742
|
+
let visible2 = 0;
|
|
27731
27743
|
let expandedLine = "";
|
|
27732
27744
|
let plainTextSinceTab = "";
|
|
27733
27745
|
const expandPlainText = (plainText) => {
|
|
@@ -27736,11 +27748,11 @@ var expandTabs = (line) => {
|
|
|
27736
27748
|
expandedLine += segment;
|
|
27737
27749
|
plainTextSinceTab += segment;
|
|
27738
27750
|
if (index < segments.length - 1) {
|
|
27739
|
-
|
|
27751
|
+
visible2 += getStringWidth(plainTextSinceTab);
|
|
27740
27752
|
plainTextSinceTab = "";
|
|
27741
|
-
const spaces = TAB_SIZE -
|
|
27753
|
+
const spaces = TAB_SIZE - visible2 % TAB_SIZE;
|
|
27742
27754
|
expandedLine += " ".repeat(spaces);
|
|
27743
|
-
|
|
27755
|
+
visible2 += spaces;
|
|
27744
27756
|
}
|
|
27745
27757
|
}
|
|
27746
27758
|
};
|
|
@@ -29247,19 +29259,19 @@ function cliTruncate(text, columns2, options = {}) {
|
|
|
29247
29259
|
}
|
|
29248
29260
|
return start;
|
|
29249
29261
|
}
|
|
29250
|
-
function appendWithInheritedStyleFromEnd(
|
|
29251
|
-
const start = trailingSgrSpanStartIndex(
|
|
29252
|
-
if (start ===
|
|
29253
|
-
return
|
|
29262
|
+
function appendWithInheritedStyleFromEnd(visible2, suffix) {
|
|
29263
|
+
const start = trailingSgrSpanStartIndex(visible2);
|
|
29264
|
+
if (start === visible2.length) {
|
|
29265
|
+
return visible2 + suffix;
|
|
29254
29266
|
}
|
|
29255
|
-
return
|
|
29267
|
+
return visible2.slice(0, start) + suffix + visible2.slice(start);
|
|
29256
29268
|
}
|
|
29257
|
-
function prependWithInheritedStyleFromStart(prefix,
|
|
29258
|
-
const end = leadingSgrSpanEndIndex(
|
|
29269
|
+
function prependWithInheritedStyleFromStart(prefix, visible2) {
|
|
29270
|
+
const end = leadingSgrSpanEndIndex(visible2);
|
|
29259
29271
|
if (end === 0) {
|
|
29260
|
-
return prefix +
|
|
29272
|
+
return prefix + visible2;
|
|
29261
29273
|
}
|
|
29262
|
-
return
|
|
29274
|
+
return visible2.slice(0, end) + prefix + visible2.slice(end);
|
|
29263
29275
|
}
|
|
29264
29276
|
if (position === "start") {
|
|
29265
29277
|
if (preferTruncationOnSpace) {
|
|
@@ -31650,7 +31662,7 @@ function splitCompoundSGRSequences(code) {
|
|
|
31650
31662
|
}
|
|
31651
31663
|
function tokenize(str, endChar = Number.POSITIVE_INFINITY) {
|
|
31652
31664
|
const ret = [];
|
|
31653
|
-
let
|
|
31665
|
+
let visible2 = 0;
|
|
31654
31666
|
let codeEndIndex = 0;
|
|
31655
31667
|
for (const { segment, index } of segmenter6.segment(str)) {
|
|
31656
31668
|
if (index < codeEndIndex)
|
|
@@ -31700,8 +31712,8 @@ function tokenize(str, endChar = Number.POSITIVE_INFINITY) {
|
|
|
31700
31712
|
value: segment,
|
|
31701
31713
|
fullWidth
|
|
31702
31714
|
});
|
|
31703
|
-
|
|
31704
|
-
if (
|
|
31715
|
+
visible2 += fullWidth ? 2 : 1;
|
|
31716
|
+
if (visible2 >= endChar) {
|
|
31705
31717
|
break;
|
|
31706
31718
|
}
|
|
31707
31719
|
}
|
|
@@ -33374,8 +33386,8 @@ var kittyModifiers = {
|
|
|
33374
33386
|
var noop = () => {
|
|
33375
33387
|
};
|
|
33376
33388
|
var textEncoder = new TextEncoder();
|
|
33377
|
-
var yieldImmediate = async () => new Promise((
|
|
33378
|
-
setImmediate(
|
|
33389
|
+
var yieldImmediate = async () => new Promise((resolve2) => {
|
|
33390
|
+
setImmediate(resolve2);
|
|
33379
33391
|
});
|
|
33380
33392
|
var kittyQueryEscapeByte = 27;
|
|
33381
33393
|
var kittyQueryOpenBracketByte = 91;
|
|
@@ -33592,8 +33604,8 @@ var Ink = class {
|
|
|
33592
33604
|
};
|
|
33593
33605
|
}
|
|
33594
33606
|
this.initKittyKeyboard();
|
|
33595
|
-
this.exitPromise = new Promise((
|
|
33596
|
-
this.resolveExitPromise =
|
|
33607
|
+
this.exitPromise = new Promise((resolve2, reject) => {
|
|
33608
|
+
this.resolveExitPromise = resolve2;
|
|
33597
33609
|
this.rejectExitPromise = reject;
|
|
33598
33610
|
});
|
|
33599
33611
|
void this.exitPromise.catch(noop);
|
|
@@ -33904,9 +33916,9 @@ var Ink = class {
|
|
|
33904
33916
|
settleThrottle(this.throttledOnRender, canWriteToStdout);
|
|
33905
33917
|
settleThrottle(this.throttledLog, canWriteToStdout);
|
|
33906
33918
|
if (canWriteToStdout && hasWritableState) {
|
|
33907
|
-
await new Promise((
|
|
33919
|
+
await new Promise((resolve2) => {
|
|
33908
33920
|
this.options.stdout.write("", () => {
|
|
33909
|
-
|
|
33921
|
+
resolve2();
|
|
33910
33922
|
});
|
|
33911
33923
|
});
|
|
33912
33924
|
return;
|
|
@@ -33992,8 +34004,8 @@ var Ink = class {
|
|
|
33992
34004
|
async awaitNextRender() {
|
|
33993
34005
|
if (!this.nextRenderCommit) {
|
|
33994
34006
|
let resolveRender;
|
|
33995
|
-
const promise = new Promise((
|
|
33996
|
-
resolveRender =
|
|
34007
|
+
const promise = new Promise((resolve2) => {
|
|
34008
|
+
resolveRender = resolve2;
|
|
33997
34009
|
});
|
|
33998
34010
|
this.nextRenderCommit = { promise, resolve: resolveRender };
|
|
33999
34011
|
}
|
|
@@ -34789,36 +34801,10 @@ var import_react32 = __toESM(require_react(), 1);
|
|
|
34789
34801
|
var import_react33 = __toESM(require_react(), 1);
|
|
34790
34802
|
|
|
34791
34803
|
// src/tui/app.tsx
|
|
34792
|
-
var
|
|
34793
|
-
|
|
34794
|
-
// src/tui/account.ts
|
|
34795
|
-
import { Buffer as Buffer2 } from "buffer";
|
|
34796
|
-
function identityFromToken(token) {
|
|
34797
|
-
const empty = { uid: null, uuid: null, tenant: null };
|
|
34798
|
-
const parts = token.split(".");
|
|
34799
|
-
if (parts.length < 2) return empty;
|
|
34800
|
-
try {
|
|
34801
|
-
const segment = parts[1];
|
|
34802
|
-
const padded = segment + "=".repeat((4 - segment.length % 4) % 4);
|
|
34803
|
-
const payload = JSON.parse(Buffer2.from(padded, "base64url").toString("utf8"));
|
|
34804
|
-
return {
|
|
34805
|
-
uid: typeof payload.uid === "number" ? payload.uid : null,
|
|
34806
|
-
uuid: typeof payload.uuid === "string" ? payload.uuid : null,
|
|
34807
|
-
tenant: typeof payload.tenant === "string" ? payload.tenant : null
|
|
34808
|
-
};
|
|
34809
|
-
} catch {
|
|
34810
|
-
return empty;
|
|
34811
|
-
}
|
|
34812
|
-
}
|
|
34813
|
-
function tokenOverrideNote(source) {
|
|
34814
|
-
if (source === "env")
|
|
34815
|
-
return "\u6CE8\u610F\uFF1A\u73AF\u5883\u53D8\u91CF AUTODL_TOKEN \u4ECD\u7136\u751F\u6548\uFF0C\u5176\u4F18\u5148\u7EA7\u9AD8\u4E8E\u8FD9\u91CC\u4FDD\u5B58\u7684 Token\u3002";
|
|
34816
|
-
if (source === "flag") return "\u6CE8\u610F\uFF1A\u672C\u6B21\u542F\u52A8\u5E26\u4E86 --token \u53C2\u6570\uFF0C\u5176\u4F18\u5148\u7EA7\u9AD8\u4E8E\u8FD9\u91CC\u4FDD\u5B58\u7684 Token\u3002";
|
|
34817
|
-
return null;
|
|
34818
|
-
}
|
|
34804
|
+
var import_react40 = __toESM(require_react(), 1);
|
|
34819
34805
|
|
|
34820
34806
|
// src/tui/clipboard.ts
|
|
34821
|
-
import { Buffer as
|
|
34807
|
+
import { Buffer as Buffer2 } from "buffer";
|
|
34822
34808
|
import { spawn } from "child_process";
|
|
34823
34809
|
import { platform as platform2 } from "os";
|
|
34824
34810
|
function candidates() {
|
|
@@ -34837,22 +34823,22 @@ function candidates() {
|
|
|
34837
34823
|
}
|
|
34838
34824
|
}
|
|
34839
34825
|
function runCopy(command, args, text) {
|
|
34840
|
-
return new Promise((
|
|
34826
|
+
return new Promise((resolve2) => {
|
|
34841
34827
|
let child;
|
|
34842
34828
|
try {
|
|
34843
34829
|
child = spawn(command, args, { stdio: ["pipe", "ignore", "ignore"] });
|
|
34844
34830
|
} catch {
|
|
34845
|
-
|
|
34831
|
+
resolve2(false);
|
|
34846
34832
|
return;
|
|
34847
34833
|
}
|
|
34848
|
-
child.on("error", () =>
|
|
34849
|
-
child.on("close", (code) =>
|
|
34850
|
-
child.stdin?.on("error", () =>
|
|
34834
|
+
child.on("error", () => resolve2(false));
|
|
34835
|
+
child.on("close", (code) => resolve2(code === 0));
|
|
34836
|
+
child.stdin?.on("error", () => resolve2(false));
|
|
34851
34837
|
child.stdin?.end(text);
|
|
34852
34838
|
});
|
|
34853
34839
|
}
|
|
34854
34840
|
function writeOsc52(text) {
|
|
34855
|
-
const payload =
|
|
34841
|
+
const payload = Buffer2.from(text, "utf8").toString("base64");
|
|
34856
34842
|
const ESC3 = String.fromCharCode(27);
|
|
34857
34843
|
const BEL3 = String.fromCharCode(7);
|
|
34858
34844
|
process.stdout.write(`${ESC3}]52;c;${payload}${BEL3}`);
|
|
@@ -35430,12 +35416,12 @@ function Table({
|
|
|
35430
35416
|
if (rows.length === 0) {
|
|
35431
35417
|
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Box_default, { paddingX: 1, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { dimColor: true, children: emptyMessage }) });
|
|
35432
35418
|
}
|
|
35433
|
-
const
|
|
35419
|
+
const visible2 = maxRows && maxRows > 0 ? Math.min(maxRows, rows.length) : rows.length;
|
|
35434
35420
|
const start = Math.max(
|
|
35435
35421
|
0,
|
|
35436
|
-
Math.min(selectedIndex - Math.floor((
|
|
35422
|
+
Math.min(selectedIndex - Math.floor((visible2 - 1) / 2), rows.length - visible2)
|
|
35437
35423
|
);
|
|
35438
|
-
const window2 = rows.slice(start, start +
|
|
35424
|
+
const window2 = rows.slice(start, start + visible2);
|
|
35439
35425
|
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Box_default, { flexDirection: "column", children: [
|
|
35440
35426
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Box_default, { paddingX: 1, children: [
|
|
35441
35427
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: CURSOR.blank }),
|
|
@@ -35809,19 +35795,1213 @@ function SessionExpired({
|
|
|
35809
35795
|
] });
|
|
35810
35796
|
}
|
|
35811
35797
|
|
|
35798
|
+
// src/tui/screens/files.tsx
|
|
35799
|
+
import { basename, dirname, join, posix, resolve } from "path";
|
|
35800
|
+
var import_react37 = __toESM(require_react(), 1);
|
|
35801
|
+
var import_jsx_runtime11 = __toESM(require_jsx_runtime(), 1);
|
|
35802
|
+
var REMOTE_HOME = "/root/autodl-tmp";
|
|
35803
|
+
function isVisibleCode(code) {
|
|
35804
|
+
if (code < 32 || code === 127) return false;
|
|
35805
|
+
if (code >= 128 && code <= 159) return false;
|
|
35806
|
+
return true;
|
|
35807
|
+
}
|
|
35808
|
+
function visible(input) {
|
|
35809
|
+
let out = "";
|
|
35810
|
+
for (const char of input) {
|
|
35811
|
+
if (isVisibleCode(char.codePointAt(0) ?? 0)) out += char;
|
|
35812
|
+
}
|
|
35813
|
+
return out || "?";
|
|
35814
|
+
}
|
|
35815
|
+
function sanitizeInput(input) {
|
|
35816
|
+
let out = "";
|
|
35817
|
+
for (const char of input) {
|
|
35818
|
+
if (isVisibleCode(char.codePointAt(0) ?? 0)) out += char;
|
|
35819
|
+
}
|
|
35820
|
+
return out;
|
|
35821
|
+
}
|
|
35822
|
+
var joinSide = (side, dir, name) => side === "remote" ? posix.join(dir, name) : join(dir, name);
|
|
35823
|
+
function resolveSide(side, base, value) {
|
|
35824
|
+
return side === "remote" ? posix.resolve(base, value) : resolve(base, value);
|
|
35825
|
+
}
|
|
35826
|
+
var parentSide = (side, p) => side === "remote" ? posix.dirname(p) : dirname(p);
|
|
35827
|
+
var baseSide = (side, p) => side === "remote" ? posix.basename(p) : basename(p);
|
|
35828
|
+
function kindMark(kind) {
|
|
35829
|
+
if (kind === "directory") return "/";
|
|
35830
|
+
if (kind === "symlink") return "@";
|
|
35831
|
+
if (kind === "other") return "?";
|
|
35832
|
+
return "";
|
|
35833
|
+
}
|
|
35834
|
+
var directionText = (direction) => direction === "upload" ? "\u4E0A\u4F20" : "\u4E0B\u8F7D";
|
|
35835
|
+
function jobStateText(state) {
|
|
35836
|
+
switch (state) {
|
|
35837
|
+
case "queued":
|
|
35838
|
+
return "\u6392\u961F";
|
|
35839
|
+
case "running":
|
|
35840
|
+
return "\u4F20\u8F93\u4E2D";
|
|
35841
|
+
case "conflict":
|
|
35842
|
+
return "\u5F85\u786E\u8BA4";
|
|
35843
|
+
case "paused":
|
|
35844
|
+
return "\u5DF2\u6682\u505C";
|
|
35845
|
+
case "completed":
|
|
35846
|
+
return "\u5B8C\u6210";
|
|
35847
|
+
case "cancelled":
|
|
35848
|
+
return "\u5DF2\u53D6\u6D88";
|
|
35849
|
+
}
|
|
35850
|
+
}
|
|
35851
|
+
function useQueueJobs(queue) {
|
|
35852
|
+
const subscribe = (0, import_react37.useCallback)((listener) => queue.subscribe(listener), [queue]);
|
|
35853
|
+
const snapshot = (0, import_react37.useCallback)(() => queue.snapshot(), [queue]);
|
|
35854
|
+
return (0, import_react37.useSyncExternalStore)(subscribe, snapshot);
|
|
35855
|
+
}
|
|
35856
|
+
var emptyPane = (p) => ({
|
|
35857
|
+
path: p,
|
|
35858
|
+
entries: [],
|
|
35859
|
+
loading: true,
|
|
35860
|
+
error: null,
|
|
35861
|
+
cursor: 0,
|
|
35862
|
+
checked: []
|
|
35863
|
+
});
|
|
35864
|
+
function dialogRows(mode, selectionCount) {
|
|
35865
|
+
switch (mode.name) {
|
|
35866
|
+
case "none":
|
|
35867
|
+
return 0;
|
|
35868
|
+
case "pathNav":
|
|
35869
|
+
case "mkdir":
|
|
35870
|
+
case "rename":
|
|
35871
|
+
return 4;
|
|
35872
|
+
case "delete":
|
|
35873
|
+
return 5 + Math.min(selectionCount, 3) + (selectionCount > 3 ? 1 : 0);
|
|
35874
|
+
case "transfer":
|
|
35875
|
+
return 6 + Math.min(selectionCount, 2);
|
|
35876
|
+
case "pathTransfer":
|
|
35877
|
+
return 7;
|
|
35878
|
+
}
|
|
35879
|
+
}
|
|
35880
|
+
function useFlash() {
|
|
35881
|
+
const [notice, setNotice] = (0, import_react37.useState)(null);
|
|
35882
|
+
const timer = (0, import_react37.useRef)(void 0);
|
|
35883
|
+
const mounted = (0, import_react37.useRef)(true);
|
|
35884
|
+
(0, import_react37.useEffect)(() => {
|
|
35885
|
+
mounted.current = true;
|
|
35886
|
+
return () => {
|
|
35887
|
+
mounted.current = false;
|
|
35888
|
+
clearTimeout(timer.current);
|
|
35889
|
+
};
|
|
35890
|
+
}, []);
|
|
35891
|
+
const flash = (0, import_react37.useCallback)((message) => {
|
|
35892
|
+
if (!mounted.current) return;
|
|
35893
|
+
setNotice(message);
|
|
35894
|
+
clearTimeout(timer.current);
|
|
35895
|
+
timer.current = setTimeout(() => {
|
|
35896
|
+
if (mounted.current) setNotice(null);
|
|
35897
|
+
}, 6e3);
|
|
35898
|
+
}, []);
|
|
35899
|
+
return { notice, flash };
|
|
35900
|
+
}
|
|
35901
|
+
function fitLine(text, width) {
|
|
35902
|
+
return clip(visible(text), Math.max(1, width));
|
|
35903
|
+
}
|
|
35904
|
+
function skippedPageStart(index) {
|
|
35905
|
+
return Math.floor(Math.max(0, index) / 3) * 3;
|
|
35906
|
+
}
|
|
35907
|
+
function detailRows(job, show, skippedOpen, skippedIndex) {
|
|
35908
|
+
if (!job || !show) return 0;
|
|
35909
|
+
let n = 2;
|
|
35910
|
+
n += Math.min(job.request.sources.length, 2) + (job.request.sources.length > 2 ? 1 : 0);
|
|
35911
|
+
if (job.progress) n += 2;
|
|
35912
|
+
if (job.state === "conflict" && job.conflict) n += 2;
|
|
35913
|
+
if (job.result) {
|
|
35914
|
+
n += 1;
|
|
35915
|
+
const total = job.result.skipped.length;
|
|
35916
|
+
if (total > 0) {
|
|
35917
|
+
if (!skippedOpen) {
|
|
35918
|
+
n += 1;
|
|
35919
|
+
} else {
|
|
35920
|
+
const clamped = Math.min(Math.max(0, skippedIndex), total - 1);
|
|
35921
|
+
n += Math.min(3, total - skippedPageStart(clamped)) + 2;
|
|
35922
|
+
}
|
|
35923
|
+
}
|
|
35924
|
+
}
|
|
35925
|
+
if (job.error) n += 1;
|
|
35926
|
+
return n;
|
|
35927
|
+
}
|
|
35928
|
+
function renderQueueBody(ui) {
|
|
35929
|
+
const { jobs, cursor, listRows } = ui;
|
|
35930
|
+
const width = Math.max(20, ui.width);
|
|
35931
|
+
const rowWidth2 = Math.max(1, width - 2);
|
|
35932
|
+
const start = Math.max(0, Math.min(cursor, Math.max(0, jobs.length - listRows)));
|
|
35933
|
+
const shown = jobs.slice(start, start + listRows);
|
|
35934
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Box_default, { flexDirection: "column", children: [
|
|
35935
|
+
jobs.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Box_default, { paddingX: 1, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { dimColor: true, wrap: "truncate", children: fitLine("\u961F\u5217\u4E3A\u7A7A\u3002\u5728\u6D4F\u89C8\u5668\u6309 u \u5C06\u9009\u4E2D\u6587\u4EF6\u52A0\u5165\u4F20\u8F93\u961F\u5217\u3002", rowWidth2) }) }) : shown.map((job, i) => {
|
|
35936
|
+
const index = start + i;
|
|
35937
|
+
const active = index === cursor;
|
|
35938
|
+
const req = job.request;
|
|
35939
|
+
const label = `${req.direction === "upload" ? "\u2191" : "\u2193"} ${req.sources.length}\u9879 \u2192 ${req.destination}`;
|
|
35940
|
+
const pct = job.progress && job.progress.total > 0 ? job.progress.transferred / job.progress.total * 100 : job.state === "completed" ? 100 : 0;
|
|
35941
|
+
const speed = job.state === "running" && job.progress ? ` ${formatBytes(job.progress.bytesPerSecond)}/s` : "";
|
|
35942
|
+
const row = `${active ? "\u203A" : " "} ${label} ${jobStateText(job.state)} ${Math.round(pct)}%${speed}${job.state === "conflict" ? " \u5F85\u786E\u8BA4" : ""}${job.error ? " \u2716" : ""}`;
|
|
35943
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Box_default, { children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { color: active ? "green" : void 0, inverse: active, wrap: "truncate", children: fitLine(row, rowWidth2) }) }, job.request.id);
|
|
35944
|
+
}),
|
|
35945
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(QueueDetail, { ui })
|
|
35946
|
+
] });
|
|
35947
|
+
}
|
|
35948
|
+
function SkippedBrowser({
|
|
35949
|
+
ui,
|
|
35950
|
+
job,
|
|
35951
|
+
width
|
|
35952
|
+
}) {
|
|
35953
|
+
const skipped = job.result?.skipped;
|
|
35954
|
+
if (!skipped || skipped.length === 0) return null;
|
|
35955
|
+
if (!ui.skippedOpen) {
|
|
35956
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { dimColor: true, wrap: "truncate", children: fitLine(`\u8DF3\u8FC7 ${skipped.length} \u9879 \xB7 v \u67E5\u770B\u5168\u90E8`, width) });
|
|
35957
|
+
}
|
|
35958
|
+
const total = skipped.length;
|
|
35959
|
+
const clamped = Math.min(ui.skippedIndex, Math.max(0, total - 1));
|
|
35960
|
+
const start = skippedPageStart(clamped);
|
|
35961
|
+
const shown = skipped.slice(start, start + 3);
|
|
35962
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
35963
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { bold: true, wrap: "truncate", children: fitLine(`\u8DF3\u8FC7 ${total} \u9879\uFF08${clamped + 1}/${total}\uFF09\xB7 \u2191\u2193 \u9009\u62E9 \xB7 Esc \u6536\u8D77`, width) }),
|
|
35964
|
+
shown.map((entry, i) => {
|
|
35965
|
+
const absolute = start + i;
|
|
35966
|
+
const active = absolute === clamped;
|
|
35967
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { dimColor: !active, inverse: active, wrap: "truncate", children: fitLine(`${active ? "\u203A" : "\xB7"} ${entry}`, width) }, `${absolute}`);
|
|
35968
|
+
}),
|
|
35969
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { dimColor: true, wrap: "truncate", children: fitLine(
|
|
35970
|
+
total > 3 ? `\u7B2C ${Math.floor(start / 3) + 1}/${Math.ceil(total / 3)} \u9875 \xB7 Esc \u6536\u8D77\u8DF3\u8FC7\u5217\u8868` : "Esc \u6536\u8D77\u8DF3\u8FC7\u5217\u8868",
|
|
35971
|
+
width
|
|
35972
|
+
) })
|
|
35973
|
+
] });
|
|
35974
|
+
}
|
|
35975
|
+
function QueueDetail({ ui }) {
|
|
35976
|
+
const job = ui.jobs[Math.min(ui.cursor, Math.max(0, ui.jobs.length - 1))];
|
|
35977
|
+
if (!job || !ui.showDetail) return null;
|
|
35978
|
+
const req = job.request;
|
|
35979
|
+
const width = Math.max(20, ui.width - 4);
|
|
35980
|
+
const lines = [
|
|
35981
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { bold: true, wrap: "truncate", children: fitLine(
|
|
35982
|
+
`${directionText(req.direction)} \xB7 ${req.sources.length} \u4E2A\u6765\u6E90${req.sync ? " \xB7 \u540C\u6B65" : ""}${req.checksum ? " \xB7 \u54C8\u5E0C\u6821\u9A8C" : ""}`,
|
|
35983
|
+
width
|
|
35984
|
+
) }, "h"),
|
|
35985
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { dimColor: true, wrap: "truncate", children: fitLine(`\u2192 ${req.destination}`, width) }, "d")
|
|
35986
|
+
];
|
|
35987
|
+
for (const [i, source] of req.sources.slice(0, 2).entries()) {
|
|
35988
|
+
lines.push(
|
|
35989
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { dimColor: true, wrap: "truncate", children: fitLine(`\xB7 ${source}`, width) }, `s-${i}`)
|
|
35990
|
+
);
|
|
35991
|
+
}
|
|
35992
|
+
if (req.sources.length > 2) {
|
|
35993
|
+
lines.push(
|
|
35994
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { dimColor: true, wrap: "truncate", children: fitLine(`\xB7 \u2026\u53E6 ${req.sources.length - 2} \u4E2A`, width) }, "more")
|
|
35995
|
+
);
|
|
35996
|
+
}
|
|
35997
|
+
if (job.progress) {
|
|
35998
|
+
const p = job.progress;
|
|
35999
|
+
lines.push(
|
|
36000
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { wrap: "truncate", children: fitLine(
|
|
36001
|
+
`${p.file} ${formatBytes(p.transferred)}/${formatBytes(p.total)} \xB7 ${p.filesDone}/${p.filesTotal} \u6587\u4EF6 \xB7 ${formatBytes(p.bytesPerSecond)}/s`,
|
|
36002
|
+
width
|
|
36003
|
+
) }, "p")
|
|
36004
|
+
);
|
|
36005
|
+
lines.push(
|
|
36006
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { wrap: "truncate", children: fitLine(
|
|
36007
|
+
bar(p.total > 0 ? p.transferred / p.total * 100 : 0, Math.min(30, width)),
|
|
36008
|
+
width
|
|
36009
|
+
) }, "b")
|
|
36010
|
+
);
|
|
36011
|
+
}
|
|
36012
|
+
if (job.state === "conflict" && job.conflict) {
|
|
36013
|
+
lines.push(
|
|
36014
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { color: "yellow", wrap: "truncate", children: fitLine(
|
|
36015
|
+
`\u51B2\u7A81\uFF1A${job.conflict.source} \u2192 ${job.conflict.destination} (${formatBytes(job.conflict.sourceSize)}/${formatBytes(job.conflict.destinationSize)})`,
|
|
36016
|
+
width
|
|
36017
|
+
) }, "c")
|
|
36018
|
+
);
|
|
36019
|
+
lines.push(
|
|
36020
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { color: "yellow", wrap: "truncate", children: fitLine(
|
|
36021
|
+
`o \u8986\u76D6 \xB7 s \u8DF3\u8FC7 \xB7 b \u4FDD\u7559\u4E24\u8005 \xB7 a \u5E94\u7528\u4E8E\u5168\u90E8[${ui.applyAll ? "\u2713" : " "}] \xB7 \u76EE\u6807\u4E3A\u9009\u4E2D\u4EFB\u52A1`,
|
|
36022
|
+
width
|
|
36023
|
+
) }, "ck")
|
|
36024
|
+
);
|
|
36025
|
+
}
|
|
36026
|
+
if (job.result) {
|
|
36027
|
+
lines.push(
|
|
36028
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { color: "green", wrap: "truncate", children: fitLine(
|
|
36029
|
+
`\u5B8C\u6210\uFF1A${job.result.files} \u6587\u4EF6 \xB7 ${formatBytes(job.result.bytes)}${job.result.skipped.length > 0 ? ` \xB7 \u8DF3\u8FC7 ${job.result.skipped.length} \u9879` : ""}`,
|
|
36030
|
+
width
|
|
36031
|
+
) }, "r")
|
|
36032
|
+
);
|
|
36033
|
+
lines.push(/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SkippedBrowser, { ui, job, width }, "skipped"));
|
|
36034
|
+
}
|
|
36035
|
+
if (job.error) {
|
|
36036
|
+
lines.push(
|
|
36037
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { color: "red", wrap: "truncate", children: fitLine(`\u2716 ${job.error}`, width) }, "e")
|
|
36038
|
+
);
|
|
36039
|
+
}
|
|
36040
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Box_default, { flexDirection: "column", paddingX: 1, children: lines });
|
|
36041
|
+
}
|
|
36042
|
+
function handleQueueInput(input, key, ui, queue, onExit) {
|
|
36043
|
+
const job = ui.jobs[Math.min(ui.cursor, Math.max(0, ui.jobs.length - 1))];
|
|
36044
|
+
const skippedTotal = ui.showDetail && !ui.skippedOpen ? job?.result?.skipped.length ?? 0 : 0;
|
|
36045
|
+
if (ui.showDetail && ui.skippedOpen && job?.result) {
|
|
36046
|
+
const total = job.result.skipped.length;
|
|
36047
|
+
if (key.upArrow || input === "k") {
|
|
36048
|
+
ui.setSkippedIndex((v) => Math.max(0, v - 1));
|
|
36049
|
+
return true;
|
|
36050
|
+
}
|
|
36051
|
+
if (key.downArrow || input === "j") {
|
|
36052
|
+
ui.setSkippedIndex((v) => Math.max(0, Math.min(total - 1, v + 1)));
|
|
36053
|
+
return true;
|
|
36054
|
+
}
|
|
36055
|
+
if (input === "q" || key.escape || key.return || input === "v") {
|
|
36056
|
+
ui.setSkippedOpen(() => false);
|
|
36057
|
+
return true;
|
|
36058
|
+
}
|
|
36059
|
+
return false;
|
|
36060
|
+
}
|
|
36061
|
+
if (key.upArrow || input === "k") {
|
|
36062
|
+
ui.setCursor((v) => Math.max(0, v - 1));
|
|
36063
|
+
return true;
|
|
36064
|
+
}
|
|
36065
|
+
if (key.downArrow || input === "j") {
|
|
36066
|
+
ui.setCursor((v) => Math.max(0, Math.min(ui.jobs.length - 1, v + 1)));
|
|
36067
|
+
return true;
|
|
36068
|
+
}
|
|
36069
|
+
if (key.return) {
|
|
36070
|
+
if (ui.showDetail) {
|
|
36071
|
+
ui.setShowDetail(() => false);
|
|
36072
|
+
ui.setSkippedOpen(() => false);
|
|
36073
|
+
} else {
|
|
36074
|
+
ui.setShowDetail(() => true);
|
|
36075
|
+
}
|
|
36076
|
+
return true;
|
|
36077
|
+
}
|
|
36078
|
+
if (input === "v" && ui.showDetail && skippedTotal > 0) {
|
|
36079
|
+
ui.setSkippedIndex(() => 0);
|
|
36080
|
+
ui.setSkippedOpen(() => true);
|
|
36081
|
+
return true;
|
|
36082
|
+
}
|
|
36083
|
+
if (input === "q" || key.escape) {
|
|
36084
|
+
if (ui.showDetail) {
|
|
36085
|
+
ui.setShowDetail(() => false);
|
|
36086
|
+
ui.setSkippedOpen(() => false);
|
|
36087
|
+
} else onExit();
|
|
36088
|
+
return true;
|
|
36089
|
+
}
|
|
36090
|
+
if (input === "r") {
|
|
36091
|
+
if (!job) {
|
|
36092
|
+
ui.flash("\u961F\u5217\u4E3A\u7A7A");
|
|
36093
|
+
return true;
|
|
36094
|
+
}
|
|
36095
|
+
if (job.state === "paused" || job.state === "cancelled") ui.resume(job.request.id);
|
|
36096
|
+
else ui.flash("\u53EA\u6709\u5DF2\u6682\u505C/\u5DF2\u53D6\u6D88\u7684\u4EFB\u52A1\u53EF\u4EE5\u6062\u590D");
|
|
36097
|
+
return true;
|
|
36098
|
+
}
|
|
36099
|
+
if (input === "c") {
|
|
36100
|
+
if (!job) {
|
|
36101
|
+
ui.flash("\u961F\u5217\u4E3A\u7A7A");
|
|
36102
|
+
return true;
|
|
36103
|
+
}
|
|
36104
|
+
if (job.state === "queued" || job.state === "running" || job.state === "paused" || job.state === "conflict") {
|
|
36105
|
+
queue.cancel(job.request.id);
|
|
36106
|
+
} else ui.flash("\u5DF2\u5B8C\u6210/\u5DF2\u53D6\u6D88\u7684\u4EFB\u52A1\u65E0\u9700\u53D6\u6D88");
|
|
36107
|
+
return true;
|
|
36108
|
+
}
|
|
36109
|
+
if (input === "a" && job && job.state === "conflict") {
|
|
36110
|
+
ui.setApplyAll((v) => !v);
|
|
36111
|
+
return true;
|
|
36112
|
+
}
|
|
36113
|
+
if ((input === "o" || input === "s" || input === "b") && job && job.state === "conflict") {
|
|
36114
|
+
queue.resolveConflict(job.request.id, {
|
|
36115
|
+
choice: input === "o" ? "overwrite" : input === "s" ? "skip" : "keep-both",
|
|
36116
|
+
applyToAll: ui.applyAll
|
|
36117
|
+
});
|
|
36118
|
+
return true;
|
|
36119
|
+
}
|
|
36120
|
+
return false;
|
|
36121
|
+
}
|
|
36122
|
+
function queueHints(job, skippedOpen) {
|
|
36123
|
+
const base = "\u2191\u2193/jk \u9009\u62E9 \xB7 Enter \u8BE6\u60C5 \xB7 r \u6062\u590D\u6682\u505C/\u53D6\u6D88 \xB7 c \u53D6\u6D88\u6392\u961F/\u4F20\u8F93";
|
|
36124
|
+
const skipped = job?.result && job.result.skipped.length > 0 ? " \xB7 \u8BE6\u60C5\u4E2D\u6309 v \u67E5\u770B\u8DF3\u8FC7" : "";
|
|
36125
|
+
if (skippedOpen) {
|
|
36126
|
+
return [base, "\u8DF3\u8FC7\u5217\u8868\uFF1A\u2191\u2193 \u9009\u62E9 \xB7 Enter/Esc/q/v \u6536\u8D77"];
|
|
36127
|
+
}
|
|
36128
|
+
const second = job?.state === "conflict" ? "o \u8986\u76D6 \xB7 s \u8DF3\u8FC7 \xB7 b \u4FDD\u7559\u4E24\u8005 \xB7 a \u5E94\u7528\u4E8E\u5168\u90E8 \xB7 Esc/q \u6536\u8D77\u8BE6\u60C5\u6216\u8FD4\u56DE" : "Esc/q \u6536\u8D77\u8BE6\u60C5\u6216\u8FD4\u56DE \xB7 \u8DF3\u8FC7\u5217\u8868\u4E2D \u2191\u2193 \u7FFB\u770B Esc \u6536\u8D77";
|
|
36129
|
+
return [`${base}${skipped}`, second];
|
|
36130
|
+
}
|
|
36131
|
+
function TransferJobs({
|
|
36132
|
+
queue,
|
|
36133
|
+
width,
|
|
36134
|
+
height,
|
|
36135
|
+
onBack,
|
|
36136
|
+
onResume
|
|
36137
|
+
}) {
|
|
36138
|
+
const jobs = useQueueJobs(queue);
|
|
36139
|
+
const [cursor, setCursor] = (0, import_react37.useState)(0);
|
|
36140
|
+
const [showDetail, setShowDetail] = (0, import_react37.useState)(false);
|
|
36141
|
+
const [skippedOpen, setSkippedOpen] = (0, import_react37.useState)(false);
|
|
36142
|
+
const [skippedIndex, setSkippedIndex] = (0, import_react37.useState)(0);
|
|
36143
|
+
const [applyAll, setApplyAll] = (0, import_react37.useState)(false);
|
|
36144
|
+
const { notice, flash } = useFlash();
|
|
36145
|
+
const resume = (0, import_react37.useCallback)(
|
|
36146
|
+
(id) => onResume ? onResume(id) : queue.resume(id),
|
|
36147
|
+
[onResume, queue]
|
|
36148
|
+
);
|
|
36149
|
+
const clamped = Math.min(cursor, Math.max(0, jobs.length - 1));
|
|
36150
|
+
const selected = jobs[clamped];
|
|
36151
|
+
const selectedId = selected?.request.id;
|
|
36152
|
+
const previousSelectedId = (0, import_react37.useRef)(selectedId);
|
|
36153
|
+
(0, import_react37.useEffect)(() => {
|
|
36154
|
+
if (previousSelectedId.current === selectedId) return;
|
|
36155
|
+
previousSelectedId.current = selectedId;
|
|
36156
|
+
setSkippedOpen(false);
|
|
36157
|
+
setSkippedIndex(0);
|
|
36158
|
+
}, [selectedId]);
|
|
36159
|
+
const listRows = Math.max(
|
|
36160
|
+
1,
|
|
36161
|
+
height - 3 - detailRows(selected, showDetail, skippedOpen, skippedIndex) - (notice ? 1 : 0)
|
|
36162
|
+
);
|
|
36163
|
+
const ui = {
|
|
36164
|
+
jobs,
|
|
36165
|
+
cursor: clamped,
|
|
36166
|
+
setCursor,
|
|
36167
|
+
showDetail,
|
|
36168
|
+
setShowDetail,
|
|
36169
|
+
skippedOpen,
|
|
36170
|
+
setSkippedOpen,
|
|
36171
|
+
skippedIndex,
|
|
36172
|
+
setSkippedIndex,
|
|
36173
|
+
applyAll,
|
|
36174
|
+
setApplyAll,
|
|
36175
|
+
resume,
|
|
36176
|
+
flash,
|
|
36177
|
+
width,
|
|
36178
|
+
listRows
|
|
36179
|
+
};
|
|
36180
|
+
use_input_default((input, key) => {
|
|
36181
|
+
if (key.ctrl) return;
|
|
36182
|
+
handleQueueInput(input, key, ui, queue, onBack);
|
|
36183
|
+
});
|
|
36184
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Box_default, { flexDirection: "column", width, height, overflow: "hidden", children: [
|
|
36185
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Box_default, { paddingX: 1, children: [
|
|
36186
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { bold: true, children: "\u4F20\u8F93\u961F\u5217" }),
|
|
36187
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { dimColor: true, children: [
|
|
36188
|
+
jobs.length,
|
|
36189
|
+
" \u4E2A\u4EFB\u52A1\uFF08\u4E32\u884C\uFF09",
|
|
36190
|
+
jobs.length > 0 ? ` \xB7 ${clamped + 1}/${jobs.length}` : ""
|
|
36191
|
+
] })
|
|
36192
|
+
] }),
|
|
36193
|
+
renderQueueBody(ui),
|
|
36194
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Box_default, { flexGrow: 1 }),
|
|
36195
|
+
notice ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Box_default, { paddingX: 1, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { color: "cyan", children: clip(visible(notice), Math.max(10, width - 2)) }) }) : null,
|
|
36196
|
+
queueHints(selected, skippedOpen).map((hint) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Box_default, { paddingX: 1, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { dimColor: true, wrap: "truncate", children: fitLine(hint, Math.max(10, width - 2)) }) }, hint))
|
|
36197
|
+
] });
|
|
36198
|
+
}
|
|
36199
|
+
function FilesScreen({
|
|
36200
|
+
workspace,
|
|
36201
|
+
queue,
|
|
36202
|
+
uuid,
|
|
36203
|
+
width,
|
|
36204
|
+
height,
|
|
36205
|
+
onBack,
|
|
36206
|
+
onResume,
|
|
36207
|
+
whenRunning
|
|
36208
|
+
}) {
|
|
36209
|
+
const [tab2, setTab] = (0, import_react37.useState)("browser");
|
|
36210
|
+
const [panes, setPanes] = (0, import_react37.useState)(() => ({
|
|
36211
|
+
local: emptyPane(process.cwd()),
|
|
36212
|
+
remote: emptyPane(REMOTE_HOME)
|
|
36213
|
+
}));
|
|
36214
|
+
const [activeSide, setActiveSide] = (0, import_react37.useState)("local");
|
|
36215
|
+
const [mode, setMode] = (0, import_react37.useState)({ name: "none" });
|
|
36216
|
+
const [field, setField] = (0, import_react37.useState)("");
|
|
36217
|
+
const [confirmYes, setConfirmYes] = (0, import_react37.useState)(false);
|
|
36218
|
+
const [syncDefault, setSyncDefault] = (0, import_react37.useState)(false);
|
|
36219
|
+
const [checksumDefault, setChecksumDefault] = (0, import_react37.useState)(false);
|
|
36220
|
+
const [pending, setPending] = (0, import_react37.useState)(null);
|
|
36221
|
+
const [pathForm, setPathForm] = (0, import_react37.useState)({
|
|
36222
|
+
direction: "upload",
|
|
36223
|
+
source: "",
|
|
36224
|
+
dest: "",
|
|
36225
|
+
sync: false,
|
|
36226
|
+
checksum: false
|
|
36227
|
+
});
|
|
36228
|
+
const [busy, setBusy] = (0, import_react37.useState)(false);
|
|
36229
|
+
const { notice, flash } = useFlash();
|
|
36230
|
+
const jobs = useQueueJobs(queue);
|
|
36231
|
+
const [queueCursor, setQueueCursor] = (0, import_react37.useState)(0);
|
|
36232
|
+
const [queueDetail, setQueueDetail] = (0, import_react37.useState)(false);
|
|
36233
|
+
const [skippedOpen, setSkippedOpen] = (0, import_react37.useState)(false);
|
|
36234
|
+
const [skippedIndex, setSkippedIndex] = (0, import_react37.useState)(0);
|
|
36235
|
+
const [applyAll, setApplyAll] = (0, import_react37.useState)(false);
|
|
36236
|
+
const resume = (0, import_react37.useCallback)(
|
|
36237
|
+
(id) => onResume ? onResume(id) : queue.resume(id),
|
|
36238
|
+
[onResume, queue]
|
|
36239
|
+
);
|
|
36240
|
+
const mounted = (0, import_react37.useRef)(true);
|
|
36241
|
+
(0, import_react37.useEffect)(
|
|
36242
|
+
() => () => {
|
|
36243
|
+
mounted.current = false;
|
|
36244
|
+
workspace.dispose();
|
|
36245
|
+
},
|
|
36246
|
+
[workspace]
|
|
36247
|
+
);
|
|
36248
|
+
const gen = (0, import_react37.useRef)({ local: 0, remote: 0 });
|
|
36249
|
+
const queueJobId = jobs[Math.min(queueCursor, Math.max(0, jobs.length - 1))]?.request.id;
|
|
36250
|
+
const previousQueueJobId = (0, import_react37.useRef)(queueJobId);
|
|
36251
|
+
(0, import_react37.useEffect)(() => {
|
|
36252
|
+
if (previousQueueJobId.current === queueJobId) return;
|
|
36253
|
+
previousQueueJobId.current = queueJobId;
|
|
36254
|
+
setSkippedOpen(false);
|
|
36255
|
+
setSkippedIndex(0);
|
|
36256
|
+
}, [queueJobId]);
|
|
36257
|
+
const pathRef = (0, import_react37.useRef)({
|
|
36258
|
+
local: process.cwd(),
|
|
36259
|
+
remote: REMOTE_HOME
|
|
36260
|
+
});
|
|
36261
|
+
(0, import_react37.useEffect)(() => {
|
|
36262
|
+
pathRef.current = { local: panes.local.path, remote: panes.remote.path };
|
|
36263
|
+
});
|
|
36264
|
+
const loadPane = (0, import_react37.useCallback)(
|
|
36265
|
+
(side, nextPath) => {
|
|
36266
|
+
gen.current[side] += 1;
|
|
36267
|
+
const g = gen.current[side];
|
|
36268
|
+
if (side === "local") {
|
|
36269
|
+
setPanes((prev) => ({ ...prev, local: { ...emptyPane(nextPath), cursor: 0 } }));
|
|
36270
|
+
} else {
|
|
36271
|
+
setPanes((prev) => ({ ...prev, remote: { ...emptyPane(nextPath), cursor: 0 } }));
|
|
36272
|
+
}
|
|
36273
|
+
const run = () => {
|
|
36274
|
+
if (!mounted.current || gen.current[side] !== g) return;
|
|
36275
|
+
workspace.list(side, nextPath).then((entries) => {
|
|
36276
|
+
if (!mounted.current || gen.current[side] !== g) return;
|
|
36277
|
+
const sorted = [...entries].sort((a, b) => {
|
|
36278
|
+
if (a.kind === "directory" && b.kind !== "directory") return -1;
|
|
36279
|
+
if (a.kind !== "directory" && b.kind === "directory") return 1;
|
|
36280
|
+
return a.name.localeCompare(b.name);
|
|
36281
|
+
});
|
|
36282
|
+
setPanes(
|
|
36283
|
+
(prev) => side === "local" ? { ...prev, local: { ...prev.local, entries: sorted, loading: false } } : { ...prev, remote: { ...prev.remote, entries: sorted, loading: false } }
|
|
36284
|
+
);
|
|
36285
|
+
}).catch((err) => {
|
|
36286
|
+
if (!mounted.current || gen.current[side] !== g) return;
|
|
36287
|
+
const message = err.message;
|
|
36288
|
+
setPanes(
|
|
36289
|
+
(prev) => side === "local" ? { ...prev, local: { ...prev.local, entries: [], loading: false, error: message } } : {
|
|
36290
|
+
...prev,
|
|
36291
|
+
remote: { ...prev.remote, entries: [], loading: false, error: message }
|
|
36292
|
+
}
|
|
36293
|
+
);
|
|
36294
|
+
});
|
|
36295
|
+
};
|
|
36296
|
+
if (side === "remote" && whenRunning) {
|
|
36297
|
+
void whenRunning.then(
|
|
36298
|
+
() => run(),
|
|
36299
|
+
(err) => {
|
|
36300
|
+
if (!mounted.current || gen.current[side] !== g) return;
|
|
36301
|
+
const message = err.message;
|
|
36302
|
+
setPanes((prev) => ({
|
|
36303
|
+
...prev,
|
|
36304
|
+
remote: { ...prev.remote, entries: [], loading: false, error: message }
|
|
36305
|
+
}));
|
|
36306
|
+
}
|
|
36307
|
+
);
|
|
36308
|
+
return;
|
|
36309
|
+
}
|
|
36310
|
+
run();
|
|
36311
|
+
},
|
|
36312
|
+
[workspace, whenRunning]
|
|
36313
|
+
);
|
|
36314
|
+
(0, import_react37.useEffect)(() => {
|
|
36315
|
+
loadPane("local", process.cwd());
|
|
36316
|
+
loadPane("remote", REMOTE_HOME);
|
|
36317
|
+
}, [loadPane]);
|
|
36318
|
+
const completedJobs = (0, import_react37.useRef)(
|
|
36319
|
+
new Set(jobs.filter((job) => job.state === "completed").map((job) => job.request.id))
|
|
36320
|
+
);
|
|
36321
|
+
(0, import_react37.useEffect)(() => {
|
|
36322
|
+
for (const job of jobs) {
|
|
36323
|
+
if (job.state !== "completed" || completedJobs.current.has(job.request.id)) continue;
|
|
36324
|
+
completedJobs.current.add(job.request.id);
|
|
36325
|
+
if (job.request.uuid !== uuid) continue;
|
|
36326
|
+
const side = job.request.direction === "upload" ? "remote" : "local";
|
|
36327
|
+
loadPane(side, pathRef.current[side]);
|
|
36328
|
+
}
|
|
36329
|
+
}, [jobs, loadPane, uuid]);
|
|
36330
|
+
const pane = panes[activeSide];
|
|
36331
|
+
const otherSide = activeSide === "local" ? "remote" : "local";
|
|
36332
|
+
const cursorIndex = Math.min(pane.cursor, Math.max(0, pane.entries.length - 1));
|
|
36333
|
+
const cursorEntry = pane.entries[cursorIndex];
|
|
36334
|
+
const selection = (0, import_react37.useMemo)(() => {
|
|
36335
|
+
if (pane.checked.length > 0) return pane.entries.filter((e) => pane.checked.includes(e.path));
|
|
36336
|
+
return cursorEntry ? [cursorEntry] : [];
|
|
36337
|
+
}, [pane.checked, pane.entries, cursorEntry]);
|
|
36338
|
+
const setPaneCursor = (0, import_react37.useCallback)((side, fn) => {
|
|
36339
|
+
setPanes((prev) => {
|
|
36340
|
+
const current = prev[side];
|
|
36341
|
+
const next = fn(current.cursor);
|
|
36342
|
+
return side === "local" ? { ...prev, local: { ...current, cursor: next } } : { ...prev, remote: { ...current, cursor: next } };
|
|
36343
|
+
});
|
|
36344
|
+
}, []);
|
|
36345
|
+
const runOp = (0, import_react37.useCallback)(
|
|
36346
|
+
async (label, fn, side) => {
|
|
36347
|
+
setBusy(true);
|
|
36348
|
+
try {
|
|
36349
|
+
await fn();
|
|
36350
|
+
if (!mounted.current) return;
|
|
36351
|
+
flash(`\u2714 ${label}`);
|
|
36352
|
+
loadPane(side, pathRef.current[side]);
|
|
36353
|
+
} catch (err) {
|
|
36354
|
+
if (!mounted.current) return;
|
|
36355
|
+
flash(`\u2716 ${label}\u5931\u8D25\uFF1A${err.message}`);
|
|
36356
|
+
} finally {
|
|
36357
|
+
if (mounted.current) setBusy(false);
|
|
36358
|
+
}
|
|
36359
|
+
},
|
|
36360
|
+
[flash, loadPane]
|
|
36361
|
+
);
|
|
36362
|
+
const doDelete = (0, import_react37.useCallback)(() => {
|
|
36363
|
+
const targets = selection.map((e) => e.path);
|
|
36364
|
+
const side = activeSide;
|
|
36365
|
+
const count = targets.length;
|
|
36366
|
+
setMode({ name: "none" });
|
|
36367
|
+
setConfirmYes(false);
|
|
36368
|
+
void runOp(
|
|
36369
|
+
`\u5DF2\u5220\u9664 ${count} \u9879`,
|
|
36370
|
+
async () => {
|
|
36371
|
+
const results = await Promise.allSettled(targets.map((t) => workspace.remove(side, t)));
|
|
36372
|
+
const failed = results.filter((r) => r.status === "rejected");
|
|
36373
|
+
if (failed.length > 0) throw new Error(`${failed.length}/${count} \u9879\u5220\u9664\u5931\u8D25`);
|
|
36374
|
+
},
|
|
36375
|
+
side
|
|
36376
|
+
);
|
|
36377
|
+
}, [selection, activeSide, runOp, workspace]);
|
|
36378
|
+
const openTransferConfirm = (0, import_react37.useCallback)(() => {
|
|
36379
|
+
if (selection.length === 0) {
|
|
36380
|
+
flash("\u6CA1\u6709\u53EF\u4F20\u8F93\u7684\u9009\u4E2D\u9879");
|
|
36381
|
+
return;
|
|
36382
|
+
}
|
|
36383
|
+
setPending({
|
|
36384
|
+
sources: selection.map((e) => e.path),
|
|
36385
|
+
kinds: selection.map((e) => e.kind),
|
|
36386
|
+
direction: activeSide === "local" ? "upload" : "download",
|
|
36387
|
+
destDir: panes[otherSide].path
|
|
36388
|
+
});
|
|
36389
|
+
setMode({ name: "transfer" });
|
|
36390
|
+
}, [selection, activeSide, panes, otherSide, flash]);
|
|
36391
|
+
const submitTransfer = (0, import_react37.useCallback)(
|
|
36392
|
+
(sync, checksum) => {
|
|
36393
|
+
if (!pending) return;
|
|
36394
|
+
queue.enqueue({
|
|
36395
|
+
uuid,
|
|
36396
|
+
direction: pending.direction,
|
|
36397
|
+
sources: pending.sources,
|
|
36398
|
+
destination: pending.destDir,
|
|
36399
|
+
sync,
|
|
36400
|
+
checksum
|
|
36401
|
+
});
|
|
36402
|
+
flash(`\u2714 \u5DF2\u52A0\u5165\u961F\u5217\uFF1A${pending.sources.length} \u9879\uFF0C\u6309 Q \u67E5\u770B`);
|
|
36403
|
+
setPending(null);
|
|
36404
|
+
setMode({ name: "none" });
|
|
36405
|
+
},
|
|
36406
|
+
[pending, queue, uuid, flash]
|
|
36407
|
+
);
|
|
36408
|
+
const submitPathForm = (0, import_react37.useCallback)(() => {
|
|
36409
|
+
const rawSource = pathForm.source.trim();
|
|
36410
|
+
const rawDest = pathForm.dest.trim();
|
|
36411
|
+
if (!rawSource || !rawDest) {
|
|
36412
|
+
flash("\u6765\u6E90\u548C\u76EE\u6807\u8DEF\u5F84\u90FD\u4E0D\u80FD\u4E3A\u7A7A");
|
|
36413
|
+
return;
|
|
36414
|
+
}
|
|
36415
|
+
const direction = pathForm.direction;
|
|
36416
|
+
const fromSide = direction === "upload" ? "local" : "remote";
|
|
36417
|
+
const toSide = direction === "upload" ? "remote" : "local";
|
|
36418
|
+
const source = resolveSide(fromSide, panes[fromSide].path, rawSource);
|
|
36419
|
+
const dest = resolveSide(toSide, panes[toSide].path, rawDest);
|
|
36420
|
+
queue.enqueue({
|
|
36421
|
+
uuid,
|
|
36422
|
+
direction,
|
|
36423
|
+
sources: [source],
|
|
36424
|
+
destination: dest,
|
|
36425
|
+
sync: pathForm.sync,
|
|
36426
|
+
checksum: pathForm.checksum
|
|
36427
|
+
});
|
|
36428
|
+
flash("\u2714 \u5DF2\u52A0\u5165\u961F\u5217\uFF0C\u6309 Q \u67E5\u770B");
|
|
36429
|
+
setMode({ name: "none" });
|
|
36430
|
+
}, [pathForm, panes, queue, uuid, flash]);
|
|
36431
|
+
const updatePaneChecked = (0, import_react37.useCallback)((side, fn) => {
|
|
36432
|
+
setPanes((prev) => {
|
|
36433
|
+
const current = prev[side];
|
|
36434
|
+
const next = fn(current.checked);
|
|
36435
|
+
return side === "local" ? { ...prev, local: { ...current, checked: next } } : { ...prev, remote: { ...current, checked: next } };
|
|
36436
|
+
});
|
|
36437
|
+
}, []);
|
|
36438
|
+
use_input_default((input, key) => {
|
|
36439
|
+
if (key.ctrl) return;
|
|
36440
|
+
if (busy) {
|
|
36441
|
+
if (key.escape || input === "q") {
|
|
36442
|
+
if (tab2 === "queue") {
|
|
36443
|
+
if (queueDetail) {
|
|
36444
|
+
setQueueDetail(false);
|
|
36445
|
+
setSkippedOpen(false);
|
|
36446
|
+
} else setTab("browser");
|
|
36447
|
+
} else if (mode.name !== "none") {
|
|
36448
|
+
setMode({ name: "none" });
|
|
36449
|
+
setPending(null);
|
|
36450
|
+
setConfirmYes(false);
|
|
36451
|
+
} else onBack();
|
|
36452
|
+
}
|
|
36453
|
+
return;
|
|
36454
|
+
}
|
|
36455
|
+
if (tab2 === "queue") {
|
|
36456
|
+
const ui = {
|
|
36457
|
+
jobs,
|
|
36458
|
+
cursor: Math.min(queueCursor, Math.max(0, jobs.length - 1)),
|
|
36459
|
+
setCursor: setQueueCursor,
|
|
36460
|
+
showDetail: queueDetail,
|
|
36461
|
+
setShowDetail: setQueueDetail,
|
|
36462
|
+
skippedOpen,
|
|
36463
|
+
setSkippedOpen,
|
|
36464
|
+
skippedIndex,
|
|
36465
|
+
setSkippedIndex,
|
|
36466
|
+
applyAll,
|
|
36467
|
+
setApplyAll,
|
|
36468
|
+
resume,
|
|
36469
|
+
flash,
|
|
36470
|
+
width,
|
|
36471
|
+
listRows: 1
|
|
36472
|
+
};
|
|
36473
|
+
if (handleQueueInput(input, key, ui, queue, () => setTab("browser"))) return;
|
|
36474
|
+
if (input === "Q") {
|
|
36475
|
+
setTab("browser");
|
|
36476
|
+
return;
|
|
36477
|
+
}
|
|
36478
|
+
return;
|
|
36479
|
+
}
|
|
36480
|
+
if (mode.name === "pathNav" || mode.name === "mkdir" || mode.name === "rename") {
|
|
36481
|
+
if (key.escape) {
|
|
36482
|
+
setMode({ name: "none" });
|
|
36483
|
+
return;
|
|
36484
|
+
}
|
|
36485
|
+
if (key.return) {
|
|
36486
|
+
const value = field.trim();
|
|
36487
|
+
if (mode.name === "pathNav") {
|
|
36488
|
+
if (value) loadPane(activeSide, resolveSide(activeSide, pane.path, value));
|
|
36489
|
+
setMode({ name: "none" });
|
|
36490
|
+
} else if (mode.name === "mkdir") {
|
|
36491
|
+
if (!value) {
|
|
36492
|
+
flash("\u76EE\u5F55\u540D\u4E0D\u80FD\u4E3A\u7A7A");
|
|
36493
|
+
return;
|
|
36494
|
+
}
|
|
36495
|
+
const target = resolveSide(activeSide, pane.path, value);
|
|
36496
|
+
setMode({ name: "none" });
|
|
36497
|
+
void runOp("\u5DF2\u521B\u5EFA\u76EE\u5F55", () => workspace.mkdir(activeSide, target), activeSide);
|
|
36498
|
+
} else if (mode.name === "rename") {
|
|
36499
|
+
if (!value) {
|
|
36500
|
+
flash("\u76EE\u6807\u8DEF\u5F84\u4E0D\u80FD\u4E3A\u7A7A");
|
|
36501
|
+
return;
|
|
36502
|
+
}
|
|
36503
|
+
const targets = selection;
|
|
36504
|
+
setMode({ name: "none" });
|
|
36505
|
+
if (mode.multi) {
|
|
36506
|
+
const destDir = resolveSide(activeSide, pane.path, value);
|
|
36507
|
+
void runOp(
|
|
36508
|
+
`\u5DF2\u79FB\u52A8 ${targets.length} \u9879`,
|
|
36509
|
+
async () => {
|
|
36510
|
+
const failures = [];
|
|
36511
|
+
for (const t of targets) {
|
|
36512
|
+
try {
|
|
36513
|
+
await workspace.rename(
|
|
36514
|
+
activeSide,
|
|
36515
|
+
t.path,
|
|
36516
|
+
joinSide(activeSide, destDir, baseSide(activeSide, t.path))
|
|
36517
|
+
);
|
|
36518
|
+
} catch {
|
|
36519
|
+
failures.push(t.path);
|
|
36520
|
+
}
|
|
36521
|
+
}
|
|
36522
|
+
if (failures.length > 0) {
|
|
36523
|
+
throw new Error(
|
|
36524
|
+
`${failures.length}/${targets.length} \u9879\u79FB\u52A8\u5931\u8D25\uFF1A${failures[0]}`
|
|
36525
|
+
);
|
|
36526
|
+
}
|
|
36527
|
+
},
|
|
36528
|
+
activeSide
|
|
36529
|
+
);
|
|
36530
|
+
} else {
|
|
36531
|
+
const first = targets[0];
|
|
36532
|
+
if (targets.length === 1 && first) {
|
|
36533
|
+
const from = first.path;
|
|
36534
|
+
void runOp(
|
|
36535
|
+
"\u5DF2\u6539\u540D/\u79FB\u52A8",
|
|
36536
|
+
() => workspace.rename(activeSide, from, resolveSide(activeSide, pane.path, value)),
|
|
36537
|
+
activeSide
|
|
36538
|
+
);
|
|
36539
|
+
}
|
|
36540
|
+
}
|
|
36541
|
+
}
|
|
36542
|
+
return;
|
|
36543
|
+
}
|
|
36544
|
+
if (key.backspace || key.delete) {
|
|
36545
|
+
setField((v) => v.slice(0, -1));
|
|
36546
|
+
return;
|
|
36547
|
+
}
|
|
36548
|
+
if (key.tab) return;
|
|
36549
|
+
const clean = sanitizeInput(input);
|
|
36550
|
+
if (clean) setField((v) => v + clean);
|
|
36551
|
+
return;
|
|
36552
|
+
}
|
|
36553
|
+
if (mode.name === "pathTransfer") {
|
|
36554
|
+
if (key.escape) {
|
|
36555
|
+
setMode({ name: "none" });
|
|
36556
|
+
return;
|
|
36557
|
+
}
|
|
36558
|
+
if (key.tab || key.upArrow || key.downArrow) {
|
|
36559
|
+
const delta = key.upArrow ? -1 : 1;
|
|
36560
|
+
setMode({ name: "pathTransfer", field: (mode.field + delta + 3) % 3 });
|
|
36561
|
+
return;
|
|
36562
|
+
}
|
|
36563
|
+
if (mode.field === 0) {
|
|
36564
|
+
if (key.return) {
|
|
36565
|
+
submitPathForm();
|
|
36566
|
+
return;
|
|
36567
|
+
}
|
|
36568
|
+
if (key.leftArrow || key.rightArrow) {
|
|
36569
|
+
setPathForm((v) => ({
|
|
36570
|
+
...v,
|
|
36571
|
+
direction: v.direction === "upload" ? "download" : "upload"
|
|
36572
|
+
}));
|
|
36573
|
+
return;
|
|
36574
|
+
}
|
|
36575
|
+
if (input === "u" || input === "d") {
|
|
36576
|
+
setPathForm((v) => ({ ...v, direction: input === "u" ? "upload" : "download" }));
|
|
36577
|
+
return;
|
|
36578
|
+
}
|
|
36579
|
+
if (input === "s") {
|
|
36580
|
+
setPathForm((v) => ({ ...v, sync: !v.sync }));
|
|
36581
|
+
return;
|
|
36582
|
+
}
|
|
36583
|
+
if (input === "c") {
|
|
36584
|
+
setPathForm((v) => ({ ...v, checksum: !v.checksum }));
|
|
36585
|
+
return;
|
|
36586
|
+
}
|
|
36587
|
+
return;
|
|
36588
|
+
}
|
|
36589
|
+
if (key.return) {
|
|
36590
|
+
submitPathForm();
|
|
36591
|
+
return;
|
|
36592
|
+
}
|
|
36593
|
+
if (key.backspace || key.delete) {
|
|
36594
|
+
const f = mode.field;
|
|
36595
|
+
setPathForm(
|
|
36596
|
+
(v) => f === 1 ? { ...v, source: v.source.slice(0, -1) } : { ...v, dest: v.dest.slice(0, -1) }
|
|
36597
|
+
);
|
|
36598
|
+
return;
|
|
36599
|
+
}
|
|
36600
|
+
if (key.leftArrow || key.rightArrow) return;
|
|
36601
|
+
const clean = sanitizeInput(input);
|
|
36602
|
+
if (clean) {
|
|
36603
|
+
const f = mode.field;
|
|
36604
|
+
if (f === 1) setPathForm((v) => ({ ...v, source: v.source + clean }));
|
|
36605
|
+
else setPathForm((v) => ({ ...v, dest: v.dest + clean }));
|
|
36606
|
+
}
|
|
36607
|
+
return;
|
|
36608
|
+
}
|
|
36609
|
+
if (mode.name === "delete") {
|
|
36610
|
+
if (key.leftArrow || key.rightArrow || key.tab || input === "h" || input === "l") {
|
|
36611
|
+
setConfirmYes((v) => !v);
|
|
36612
|
+
return;
|
|
36613
|
+
}
|
|
36614
|
+
if (key.return) {
|
|
36615
|
+
if (!confirmYes) {
|
|
36616
|
+
setMode({ name: "none" });
|
|
36617
|
+
return;
|
|
36618
|
+
}
|
|
36619
|
+
doDelete();
|
|
36620
|
+
return;
|
|
36621
|
+
}
|
|
36622
|
+
if (key.escape || input === "q" || input === "n") {
|
|
36623
|
+
setMode({ name: "none" });
|
|
36624
|
+
setConfirmYes(false);
|
|
36625
|
+
return;
|
|
36626
|
+
}
|
|
36627
|
+
if (input === "y") {
|
|
36628
|
+
doDelete();
|
|
36629
|
+
return;
|
|
36630
|
+
}
|
|
36631
|
+
return;
|
|
36632
|
+
}
|
|
36633
|
+
if (mode.name === "transfer") {
|
|
36634
|
+
if (key.escape || input === "q") {
|
|
36635
|
+
setMode({ name: "none" });
|
|
36636
|
+
setPending(null);
|
|
36637
|
+
return;
|
|
36638
|
+
}
|
|
36639
|
+
if (key.return || input === "y") {
|
|
36640
|
+
submitTransfer(syncDefault, checksumDefault);
|
|
36641
|
+
return;
|
|
36642
|
+
}
|
|
36643
|
+
if (input === "s") {
|
|
36644
|
+
setSyncDefault((v) => !v);
|
|
36645
|
+
return;
|
|
36646
|
+
}
|
|
36647
|
+
if (input === "c") {
|
|
36648
|
+
setChecksumDefault((v) => !v);
|
|
36649
|
+
return;
|
|
36650
|
+
}
|
|
36651
|
+
return;
|
|
36652
|
+
}
|
|
36653
|
+
if (key.tab) {
|
|
36654
|
+
setActiveSide((v) => v === "local" ? "remote" : "local");
|
|
36655
|
+
return;
|
|
36656
|
+
}
|
|
36657
|
+
if (key.upArrow || input === "k") {
|
|
36658
|
+
setPaneCursor(activeSide, (v) => Math.max(0, v - 1));
|
|
36659
|
+
return;
|
|
36660
|
+
}
|
|
36661
|
+
if (key.downArrow || input === "j") {
|
|
36662
|
+
setPaneCursor(activeSide, (v) => Math.max(0, Math.min(pane.entries.length - 1, v + 1)));
|
|
36663
|
+
return;
|
|
36664
|
+
}
|
|
36665
|
+
if (key.return || key.rightArrow || input === "l") {
|
|
36666
|
+
if (cursorEntry?.kind === "directory") loadPane(activeSide, cursorEntry.path);
|
|
36667
|
+
else if (cursorEntry) flash("\u6587\u4EF6\u4E0D\u80FD\u8FDB\u5165\uFF1Au \u4F20\u8F93 \xB7 r \u6539\u540D \xB7 x \u5220\u9664");
|
|
36668
|
+
return;
|
|
36669
|
+
}
|
|
36670
|
+
if (key.leftArrow || key.backspace || key.delete || input === "h") {
|
|
36671
|
+
const parent = parentSide(activeSide, pane.path);
|
|
36672
|
+
if (parent !== pane.path) loadPane(activeSide, parent);
|
|
36673
|
+
return;
|
|
36674
|
+
}
|
|
36675
|
+
if (input === " ") {
|
|
36676
|
+
if (!cursorEntry) return;
|
|
36677
|
+
const p = cursorEntry.path;
|
|
36678
|
+
updatePaneChecked(
|
|
36679
|
+
activeSide,
|
|
36680
|
+
(checked) => checked.includes(p) ? checked.filter((x) => x !== p) : [...checked, p]
|
|
36681
|
+
);
|
|
36682
|
+
setPaneCursor(activeSide, (v) => Math.min(pane.entries.length - 1, v + 1));
|
|
36683
|
+
return;
|
|
36684
|
+
}
|
|
36685
|
+
if (key.escape || input === "q" || input === "Q") {
|
|
36686
|
+
if (input === "Q") {
|
|
36687
|
+
setTab("queue");
|
|
36688
|
+
return;
|
|
36689
|
+
}
|
|
36690
|
+
onBack();
|
|
36691
|
+
return;
|
|
36692
|
+
}
|
|
36693
|
+
if (input === "a") {
|
|
36694
|
+
updatePaneChecked(
|
|
36695
|
+
activeSide,
|
|
36696
|
+
(checked) => checked.length === pane.entries.length && pane.entries.length > 0 ? [] : pane.entries.map((e) => e.path)
|
|
36697
|
+
);
|
|
36698
|
+
return;
|
|
36699
|
+
}
|
|
36700
|
+
if (input === "r" && cursorEntry) {
|
|
36701
|
+
const multi = selection.length > 1;
|
|
36702
|
+
setField(multi ? pane.path : cursorEntry.path);
|
|
36703
|
+
setMode({ name: "rename", multi });
|
|
36704
|
+
return;
|
|
36705
|
+
}
|
|
36706
|
+
if (input === "g") {
|
|
36707
|
+
setField(pane.path);
|
|
36708
|
+
setMode({ name: "pathNav" });
|
|
36709
|
+
return;
|
|
36710
|
+
}
|
|
36711
|
+
if (input === "m") {
|
|
36712
|
+
setField("");
|
|
36713
|
+
setMode({ name: "mkdir" });
|
|
36714
|
+
return;
|
|
36715
|
+
}
|
|
36716
|
+
if (input === "x") {
|
|
36717
|
+
if (selection.length === 0) {
|
|
36718
|
+
flash("\u6CA1\u6709\u53EF\u5220\u9664\u7684\u9009\u4E2D\u9879");
|
|
36719
|
+
return;
|
|
36720
|
+
}
|
|
36721
|
+
setConfirmYes(false);
|
|
36722
|
+
setMode({ name: "delete" });
|
|
36723
|
+
return;
|
|
36724
|
+
}
|
|
36725
|
+
if (input === "u") {
|
|
36726
|
+
openTransferConfirm();
|
|
36727
|
+
return;
|
|
36728
|
+
}
|
|
36729
|
+
if (input === "p") {
|
|
36730
|
+
setPathForm({
|
|
36731
|
+
direction: activeSide === "local" ? "upload" : "download",
|
|
36732
|
+
source: "",
|
|
36733
|
+
dest: panes[otherSide].path,
|
|
36734
|
+
sync: syncDefault,
|
|
36735
|
+
checksum: checksumDefault
|
|
36736
|
+
});
|
|
36737
|
+
setMode({ name: "pathTransfer", field: 1 });
|
|
36738
|
+
return;
|
|
36739
|
+
}
|
|
36740
|
+
if (input === "s") {
|
|
36741
|
+
setSyncDefault((v) => !v);
|
|
36742
|
+
flash(`\u540C\u6B65\u6A21\u5F0F\uFF1A${!syncDefault ? "\u5F00\uFF08\u76EE\u5F55\u6309\u5927\u5C0F+\u65F6\u95F4\u8DF3\u8FC7\u672A\u53D8\u6587\u4EF6\uFF09" : "\u5173\uFF08\u5168\u90E8\u4F20\u8F93\uFF09"}`);
|
|
36743
|
+
return;
|
|
36744
|
+
}
|
|
36745
|
+
if (input === "c") {
|
|
36746
|
+
setChecksumDefault((v) => !v);
|
|
36747
|
+
flash(`\u5185\u5BB9\u54C8\u5E0C\u6821\u9A8C\uFF1A${!checksumDefault ? "\u5F00" : "\u5173"}`);
|
|
36748
|
+
return;
|
|
36749
|
+
}
|
|
36750
|
+
});
|
|
36751
|
+
const narrow = width < 64;
|
|
36752
|
+
const hintLines = mode.name === "none" ? narrow ? [
|
|
36753
|
+
"Tab \u5207\u4FA7 \xB7 \u2191\u2193 \u79FB\u52A8 \xB7 Enter \u8FDB\u5165",
|
|
36754
|
+
"\u2190 \u8FD4\u56DE \xB7 Space \u591A\u9009 \xB7 a \u5168\u9009",
|
|
36755
|
+
"u \u4F20\u8F93 \xB7 p \u8DEF\u5F84\u76F4\u4F20 \xB7 g \u8DF3\u8F6C",
|
|
36756
|
+
"m \u65B0\u5EFA \xB7 r \u79FB\u52A8 \xB7 x \u5220\u9664",
|
|
36757
|
+
`s \u540C\u6B65[${syncDefault ? "\u5F00" : "\u5173"}] c \u6821\u9A8C[${checksumDefault ? "\u5F00" : "\u5173"}] \xB7 Q \u961F\u5217`,
|
|
36758
|
+
"Esc/q \u8FD4\u56DE"
|
|
36759
|
+
] : [
|
|
36760
|
+
"Tab \u5207\u4FA7 \xB7 \u2191\u2193 \u79FB\u52A8 \xB7 Enter \u8FDB\u5165 \xB7 \u2190 \u8FD4\u56DE \xB7 Space \u591A\u9009 \xB7 a \u5168\u9009",
|
|
36761
|
+
"u \u4F20\u8F93 \xB7 p \u8DEF\u5F84\u76F4\u4F20 \xB7 g \u8DF3\u8F6C \xB7 Q \u961F\u5217 \xB7 Esc/q \u8FD4\u56DE",
|
|
36762
|
+
`m \u65B0\u5EFA \xB7 r \u6539\u540D/\u79FB\u52A8 \xB7 x \u5220\u9664 \xB7 s \u540C\u6B65[${syncDefault ? "\u5F00" : "\u5173"}] c \u6821\u9A8C[${checksumDefault ? "\u5F00" : "\u5173"}]`
|
|
36763
|
+
] : mode.name === "delete" ? ["\u2190\u2192 \u9009\u62E9 \xB7 Enter \u786E\u5B9A \xB7 y \u5220\u9664 \xB7 Esc/q/n \u53D6\u6D88"] : mode.name === "transfer" ? ["Enter/y \u52A0\u5165\u961F\u5217 \xB7 s \u540C\u6B65 \xB7 c \u6821\u9A8C \xB7 Esc/q \u53D6\u6D88"] : ["\u8F93\u5165\u8DEF\u5F84 \xB7 \u232B \u5220\u9664 \xB7 Enter \u786E\u5B9A \xB7 Esc \u53D6\u6D88"];
|
|
36764
|
+
const dialogH = dialogRows(mode, selection.length);
|
|
36765
|
+
const hintCount = hintLines.length;
|
|
36766
|
+
const listRows = Math.max(1, height - 3 - dialogH - (notice ? 1 : 0) - hintCount);
|
|
36767
|
+
const renderPane = (side, paneWidth) => {
|
|
36768
|
+
const p = panes[side];
|
|
36769
|
+
const activePane = side === activeSide && !(narrow && side !== activeSide);
|
|
36770
|
+
const idx = side === activeSide ? cursorIndex : Math.min(p.cursor, Math.max(0, p.entries.length - 1));
|
|
36771
|
+
const nameWidth = Math.max(8, paneWidth - 14);
|
|
36772
|
+
const start = Math.max(0, Math.min(idx, Math.max(0, p.entries.length - listRows)));
|
|
36773
|
+
const shown = p.entries.slice(start, start + listRows);
|
|
36774
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Box_default, { flexDirection: "column", width: paneWidth, flexShrink: 0, children: [
|
|
36775
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Box_default, { paddingX: 1, children: [
|
|
36776
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { bold: activePane, color: activePane ? "green" : void 0, children: side === "local" ? "\u25B8\u672C\u5730" : "\u25B8\u8FDC\u7A0B" }),
|
|
36777
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { dimColor: true, children: [
|
|
36778
|
+
" ",
|
|
36779
|
+
clip(visible(p.path), Math.max(8, paneWidth - 10))
|
|
36780
|
+
] })
|
|
36781
|
+
] }),
|
|
36782
|
+
p.loading ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Box_default, { paddingX: 1, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { dimColor: true, children: "\u8BFB\u53D6\u4E2D\u2026" }) }) : p.error ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Box_default, { paddingX: 1, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { color: "red", children: [
|
|
36783
|
+
"\u2716 ",
|
|
36784
|
+
clip(visible(p.error), Math.max(8, paneWidth - 4))
|
|
36785
|
+
] }) }) : p.entries.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Box_default, { paddingX: 1, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { dimColor: true, children: "\u7A7A\u76EE\u5F55" }) }) : shown.map((entry, i) => {
|
|
36786
|
+
const absolute = start + i;
|
|
36787
|
+
const isCursor = side === activeSide && absolute === idx;
|
|
36788
|
+
const checked = p.checked.includes(entry.path);
|
|
36789
|
+
const label = `${checked ? "[\u2713]" : "[ ]"}${isCursor ? "\u203A" : " "}${visible(entry.name)}${kindMark(entry.kind)}`;
|
|
36790
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Box_default, { children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { children: [
|
|
36791
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { inverse: isCursor, children: clip(label, nameWidth) }),
|
|
36792
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { dimColor: true, children: [
|
|
36793
|
+
" ",
|
|
36794
|
+
entry.kind === "directory" ? "-" : formatBytes(entry.size)
|
|
36795
|
+
] }),
|
|
36796
|
+
entry.kind === "symlink" ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { color: "yellow", children: " \u8DF3\u8FC7" }) : null
|
|
36797
|
+
] }) }, entry.path);
|
|
36798
|
+
}),
|
|
36799
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Box_default, { paddingX: 1, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { dimColor: true, children: [
|
|
36800
|
+
p.entries.length > listRows ? `${idx + 1}/` : "",
|
|
36801
|
+
p.entries.length,
|
|
36802
|
+
" \u9879",
|
|
36803
|
+
p.checked.length > 0 ? ` \xB7 \u5DF2\u9009 ${p.checked.length}` : "",
|
|
36804
|
+
p.entries.some((e) => e.kind === "symlink") ? " \xB7 @\u7B26\u53F7\u94FE\u63A5\u5C06\u8DF3\u8FC7" : ""
|
|
36805
|
+
] }) })
|
|
36806
|
+
] });
|
|
36807
|
+
};
|
|
36808
|
+
const renderDialog = () => {
|
|
36809
|
+
const inner = Math.max(10, width - 4);
|
|
36810
|
+
if (mode.name === "pathNav") {
|
|
36811
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Box_default, { flexDirection: "column", paddingX: 1, borderStyle: "round", borderColor: "cyan", children: [
|
|
36812
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { children: [
|
|
36813
|
+
"\u8DF3\u8F6C\uFF08",
|
|
36814
|
+
activeSide === "local" ? "\u672C\u5730" : "\u8FDC\u7A0B",
|
|
36815
|
+
"\uFF09\uFF1A",
|
|
36816
|
+
clip(visible(field), inner - 8),
|
|
36817
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { dimColor: true, children: "\u2588" })
|
|
36818
|
+
] }),
|
|
36819
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { dimColor: true, children: "\u76F8\u5BF9\u8DEF\u5F84\u4EE5\u672C\u4FA7\u5F53\u524D\u76EE\u5F55\u4E3A\u57FA\u51C6 \xB7 Enter \u8DF3\u8F6C \xB7 Esc \u53D6\u6D88" })
|
|
36820
|
+
] });
|
|
36821
|
+
}
|
|
36822
|
+
if (mode.name === "mkdir") {
|
|
36823
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Box_default, { flexDirection: "column", paddingX: 1, borderStyle: "round", borderColor: "cyan", children: [
|
|
36824
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { children: [
|
|
36825
|
+
"\u5728 ",
|
|
36826
|
+
clip(visible(pane.path), Math.max(8, inner - 24)),
|
|
36827
|
+
" \u4E0B\u65B0\u5EFA\u76EE\u5F55\uFF1A",
|
|
36828
|
+
clip(visible(field), Math.max(8, inner - 24)),
|
|
36829
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { dimColor: true, children: "\u2588" })
|
|
36830
|
+
] }),
|
|
36831
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { dimColor: true, children: "\u76F8\u5BF9\u540D\u5EFA\u4E8E\u5F53\u524D\u76EE\u5F55\uFF0C\u7EDD\u5BF9\u8DEF\u5F84\u4EA6\u53EF \xB7 Enter \u521B\u5EFA \xB7 Esc \u53D6\u6D88" })
|
|
36832
|
+
] });
|
|
36833
|
+
}
|
|
36834
|
+
if (mode.name === "rename") {
|
|
36835
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Box_default, { flexDirection: "column", paddingX: 1, borderStyle: "round", borderColor: "cyan", children: [
|
|
36836
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { children: [
|
|
36837
|
+
mode.multi ? `\u79FB\u52A8 ${selection.length} \u9879\u5230\u76EE\u5F55\uFF1A` : "\u6539\u540D/\u79FB\u52A8\u4E3A\uFF1A",
|
|
36838
|
+
clip(visible(field), inner - 8),
|
|
36839
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { dimColor: true, children: "\u2588" })
|
|
36840
|
+
] }),
|
|
36841
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { dimColor: true, children: "\u76F8\u5BF9\u8DEF\u5F84\u4EE5\u5F53\u524D\u76EE\u5F55\u4E3A\u57FA\u51C6 \xB7 Enter \u786E\u5B9A \xB7 Esc \u53D6\u6D88" })
|
|
36842
|
+
] });
|
|
36843
|
+
}
|
|
36844
|
+
if (mode.name === "delete") {
|
|
36845
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Box_default, { flexDirection: "column", paddingX: 1, borderStyle: "round", borderColor: "red", children: [
|
|
36846
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { bold: true, color: "red", children: [
|
|
36847
|
+
"\u6C38\u4E45\u5220\u9664 ",
|
|
36848
|
+
selection.length,
|
|
36849
|
+
" \u9879\uFF08\u9012\u5F52\uFF0C\u4E0D\u53EF\u6062\u590D\uFF09\uFF1A"
|
|
36850
|
+
] }),
|
|
36851
|
+
selection.slice(0, 3).map((e) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { dimColor: true, children: [
|
|
36852
|
+
"\xB7 ",
|
|
36853
|
+
clip(visible(e.path), inner - 4)
|
|
36854
|
+
] }, e.path)),
|
|
36855
|
+
selection.length > 3 ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { dimColor: true, children: [
|
|
36856
|
+
"\xB7 \u2026\u53E6 ",
|
|
36857
|
+
selection.length - 3,
|
|
36858
|
+
" \u9879"
|
|
36859
|
+
] }) : null,
|
|
36860
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Box_default, { children: [
|
|
36861
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { inverse: !confirmYes, children: " \u53D6\u6D88 " }),
|
|
36862
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { children: " " }),
|
|
36863
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { inverse: confirmYes, color: confirmYes ? "red" : void 0, children: " \u5220\u9664 " })
|
|
36864
|
+
] }),
|
|
36865
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { dimColor: true, children: "\u2190\u2192 \u5207\u6362 \xB7 Enter \u786E\u5B9A \xB7 y \u76F4\u63A5\u5220 \xB7 Esc/q/n \u53D6\u6D88" })
|
|
36866
|
+
] });
|
|
36867
|
+
}
|
|
36868
|
+
if (mode.name === "transfer" && pending) {
|
|
36869
|
+
const hasSymlink = pending.kinds.some((k) => k === "symlink");
|
|
36870
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Box_default, { flexDirection: "column", paddingX: 1, borderStyle: "round", borderColor: "cyan", children: [
|
|
36871
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { bold: true, children: [
|
|
36872
|
+
directionText(pending.direction),
|
|
36873
|
+
" ",
|
|
36874
|
+
pending.sources.length,
|
|
36875
|
+
" \u9879 \u2192",
|
|
36876
|
+
" ",
|
|
36877
|
+
clip(visible(pending.destDir), inner - 16)
|
|
36878
|
+
] }),
|
|
36879
|
+
pending.sources.slice(0, 2).map((s) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { dimColor: true, children: [
|
|
36880
|
+
"\xB7 ",
|
|
36881
|
+
clip(visible(s), inner - 4)
|
|
36882
|
+
] }, s)),
|
|
36883
|
+
pending.sources.length > 2 ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { dimColor: true, children: [
|
|
36884
|
+
"\xB7 \u2026\u53E6 ",
|
|
36885
|
+
pending.sources.length - 2,
|
|
36886
|
+
" \u9879"
|
|
36887
|
+
] }) : null,
|
|
36888
|
+
hasSymlink ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { color: "yellow", children: "\u7B26\u53F7\u94FE\u63A5\u5C06\u88AB\u8DF3\u8FC7\u5E76\u8BA1\u5165\u7ED3\u679C\u3002" }) : null,
|
|
36889
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { dimColor: true, children: [
|
|
36890
|
+
"s \u540C\u6B65[",
|
|
36891
|
+
syncDefault ? "\u2713" : " ",
|
|
36892
|
+
"] c \u54C8\u5E0C\u6821\u9A8C[",
|
|
36893
|
+
checksumDefault ? "\u2713" : " ",
|
|
36894
|
+
"] \xB7 Enter \u52A0\u5165\u961F\u5217 \xB7 Esc \u53D6\u6D88"
|
|
36895
|
+
] })
|
|
36896
|
+
] });
|
|
36897
|
+
}
|
|
36898
|
+
if (mode.name === "pathTransfer") {
|
|
36899
|
+
const f = mode.field;
|
|
36900
|
+
const marker = (i) => f === i ? "\u203A" : " ";
|
|
36901
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Box_default, { flexDirection: "column", paddingX: 1, borderStyle: "round", borderColor: "cyan", children: [
|
|
36902
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { bold: true, children: "\u6309\u8DEF\u5F84\u76F4\u63A5\u4F20\u8F93" }),
|
|
36903
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { children: [
|
|
36904
|
+
marker(0),
|
|
36905
|
+
"\u65B9\u5411\uFF1A",
|
|
36906
|
+
directionText(pathForm.direction),
|
|
36907
|
+
"\uFF08\u2190\u2192/u/d \u5207\u6362\uFF09"
|
|
36908
|
+
] }),
|
|
36909
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { children: [
|
|
36910
|
+
marker(1),
|
|
36911
|
+
"\u6765\u6E90\uFF1A",
|
|
36912
|
+
clip(visible(pathForm.source), inner - 8),
|
|
36913
|
+
f === 1 ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { dimColor: true, children: "\u2588" }) : null
|
|
36914
|
+
] }),
|
|
36915
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { children: [
|
|
36916
|
+
marker(2),
|
|
36917
|
+
"\u76EE\u6807\uFF1A",
|
|
36918
|
+
clip(visible(pathForm.dest), inner - 8),
|
|
36919
|
+
f === 2 ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { dimColor: true, children: "\u2588" }) : null
|
|
36920
|
+
] }),
|
|
36921
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { dimColor: true, children: [
|
|
36922
|
+
"\u6765\u6E90\u76F8\u5BF9\u53D1\u8D77\u4FA7\u5F53\u524D\u76EE\u5F55\uFF0C\u76EE\u6807\u76F8\u5BF9\u63A5\u6536\u4FA7\u5F53\u524D\u76EE\u5F55 \xB7 Tab/\u2191\u2193 \u6362\u884C \xB7",
|
|
36923
|
+
" ",
|
|
36924
|
+
f === 0 ? "s \u540C\u6B65 c \u6821\u9A8C \xB7 " : "",
|
|
36925
|
+
"Enter \u63D0\u4EA4 \xB7 Esc \u53D6\u6D88"
|
|
36926
|
+
] })
|
|
36927
|
+
] });
|
|
36928
|
+
}
|
|
36929
|
+
return null;
|
|
36930
|
+
};
|
|
36931
|
+
if (tab2 === "queue") {
|
|
36932
|
+
const clamped = Math.min(queueCursor, Math.max(0, jobs.length - 1));
|
|
36933
|
+
const selected = jobs[clamped];
|
|
36934
|
+
const detail = detailRows(selected, queueDetail, skippedOpen, skippedIndex);
|
|
36935
|
+
const queueListRows = Math.max(1, height - 4 - detail - (notice ? 1 : 0));
|
|
36936
|
+
const ui = {
|
|
36937
|
+
jobs,
|
|
36938
|
+
cursor: clamped,
|
|
36939
|
+
setCursor: setQueueCursor,
|
|
36940
|
+
showDetail: queueDetail,
|
|
36941
|
+
setShowDetail: setQueueDetail,
|
|
36942
|
+
skippedOpen,
|
|
36943
|
+
setSkippedOpen,
|
|
36944
|
+
skippedIndex,
|
|
36945
|
+
setSkippedIndex,
|
|
36946
|
+
applyAll,
|
|
36947
|
+
setApplyAll,
|
|
36948
|
+
resume,
|
|
36949
|
+
flash,
|
|
36950
|
+
width,
|
|
36951
|
+
listRows: queueListRows
|
|
36952
|
+
};
|
|
36953
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Box_default, { flexDirection: "column", width, height, overflow: "hidden", children: [
|
|
36954
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Box_default, { paddingX: 1, children: [
|
|
36955
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { bold: true, children: "\u6587\u4EF6" }),
|
|
36956
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { dimColor: true, children: [
|
|
36957
|
+
clip(visible(uuid), 12),
|
|
36958
|
+
" \xB7 \u6D4F\u89C8\u5668 | \u961F\u5217(",
|
|
36959
|
+
jobs.length,
|
|
36960
|
+
")",
|
|
36961
|
+
jobs.length > 0 ? ` \xB7 ${clamped + 1}/${jobs.length}` : ""
|
|
36962
|
+
] })
|
|
36963
|
+
] }),
|
|
36964
|
+
renderQueueBody(ui),
|
|
36965
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Box_default, { flexGrow: 1 }),
|
|
36966
|
+
notice ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Box_default, { paddingX: 1, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { color: "cyan", children: clip(visible(notice), Math.max(10, width - 2)) }) }) : null,
|
|
36967
|
+
queueHints(selected, skippedOpen).map((hint) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Box_default, { paddingX: 1, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { dimColor: true, wrap: "truncate", children: fitLine(hint, Math.max(10, width - 2)) }) }, hint)),
|
|
36968
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Box_default, { paddingX: 1, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { dimColor: true, children: clip("Q/Esc \u8FD4\u56DE\u6D4F\u89C8\u5668", Math.max(10, width - 2)) }) })
|
|
36969
|
+
] });
|
|
36970
|
+
}
|
|
36971
|
+
const half = Math.max(20, Math.floor((width - 1) / 2));
|
|
36972
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Box_default, { flexDirection: "column", width, height, overflow: "hidden", children: [
|
|
36973
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Box_default, { paddingX: 1, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { bold: true, wrap: "truncate", children: [
|
|
36974
|
+
"\u6587\u4EF6 \xB7 ",
|
|
36975
|
+
narrow ? activeSide === "local" ? "\u672C\u5730" : "\u8FDC\u7A0B" : "\u672C\u5730 / \u8FDC\u7A0B",
|
|
36976
|
+
" \xB7 Q \u961F\u5217(",
|
|
36977
|
+
jobs.length,
|
|
36978
|
+
")",
|
|
36979
|
+
busy ? " \xB7 \u5904\u7406\u4E2D\u2026" : ""
|
|
36980
|
+
] }) }),
|
|
36981
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Box_default, { flexDirection: "row", children: narrow ? renderPane(activeSide, Math.max(20, width - 2)) : /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
36982
|
+
renderPane("local", half),
|
|
36983
|
+
renderPane("remote", width - 1 - half)
|
|
36984
|
+
] }) }),
|
|
36985
|
+
renderDialog(),
|
|
36986
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Box_default, { flexGrow: 1 }),
|
|
36987
|
+
notice ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Box_default, { paddingX: 1, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { color: "cyan", children: clip(visible(notice), Math.max(10, width - 2)) }) }) : null,
|
|
36988
|
+
hintLines.map((hint) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Box_default, { paddingX: 1, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { dimColor: true, children: clip(hint, Math.max(10, width - 2)) }) }, hint))
|
|
36989
|
+
] });
|
|
36990
|
+
}
|
|
36991
|
+
|
|
35812
36992
|
// src/tui/screens/login.tsx
|
|
35813
|
-
var
|
|
36993
|
+
var import_react39 = __toESM(require_react(), 1);
|
|
35814
36994
|
|
|
35815
36995
|
// src/tui/useTerminalSize.ts
|
|
35816
|
-
var
|
|
36996
|
+
var import_react38 = __toESM(require_react(), 1);
|
|
35817
36997
|
function useTerminalSize() {
|
|
35818
36998
|
const { stdout } = use_stdout_default();
|
|
35819
36999
|
const read = () => ({
|
|
35820
37000
|
columns: stdout?.columns || 80,
|
|
35821
37001
|
rows: stdout?.rows || 24
|
|
35822
37002
|
});
|
|
35823
|
-
const [size, setSize] = (0,
|
|
35824
|
-
(0,
|
|
37003
|
+
const [size, setSize] = (0, import_react38.useState)(read);
|
|
37004
|
+
(0, import_react38.useEffect)(() => {
|
|
35825
37005
|
if (!stdout) return;
|
|
35826
37006
|
const onResize = () => setSize({ columns: stdout.columns || 80, rows: stdout.rows || 24 });
|
|
35827
37007
|
stdout.on("resize", onResize);
|
|
@@ -35834,7 +37014,7 @@ function useTerminalSize() {
|
|
|
35834
37014
|
}
|
|
35835
37015
|
|
|
35836
37016
|
// src/tui/screens/login.tsx
|
|
35837
|
-
var
|
|
37017
|
+
var import_jsx_runtime12 = __toESM(require_jsx_runtime(), 1);
|
|
35838
37018
|
function sanitize(input) {
|
|
35839
37019
|
let out = "";
|
|
35840
37020
|
for (const char of input) {
|
|
@@ -35851,10 +37031,11 @@ function Login({
|
|
|
35851
37031
|
notice
|
|
35852
37032
|
}) {
|
|
35853
37033
|
const { columns: columns2, rows } = useTerminalSize();
|
|
35854
|
-
const [stage, setStage] = (0,
|
|
35855
|
-
const [choice, setChoice] = (0,
|
|
35856
|
-
const [token, setToken] = (0,
|
|
37034
|
+
const [stage, setStage] = (0, import_react39.useState)("menu");
|
|
37035
|
+
const [choice, setChoice] = (0, import_react39.useState)(0);
|
|
37036
|
+
const [token, setToken] = (0, import_react39.useState)("");
|
|
35857
37037
|
use_input_default((input, key) => {
|
|
37038
|
+
if (key.ctrl && input.toLowerCase() === "c") return onQuit();
|
|
35858
37039
|
if (verifying) return;
|
|
35859
37040
|
if (stage === "menu") {
|
|
35860
37041
|
if (key.upArrow || key.downArrow || input === "j" || input === "k") {
|
|
@@ -35885,37 +37066,37 @@ function Login({
|
|
|
35885
37066
|
const clean = sanitize(input);
|
|
35886
37067
|
if (clean) setToken((v) => v + clean);
|
|
35887
37068
|
});
|
|
35888
|
-
return /* @__PURE__ */ (0,
|
|
35889
|
-
/* @__PURE__ */ (0,
|
|
35890
|
-
/* @__PURE__ */ (0,
|
|
35891
|
-
stage === "menu" ? /* @__PURE__ */ (0,
|
|
35892
|
-
notice ? /* @__PURE__ */ (0,
|
|
35893
|
-
/* @__PURE__ */ (0,
|
|
35894
|
-
/* @__PURE__ */ (0,
|
|
37069
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Box_default, { flexDirection: "column", height: rows, width: columns2, children: [
|
|
37070
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(BrandMark, { subtitle: "\u767B\u5165", columns: columns2 }),
|
|
37071
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Box_default, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1, children: [
|
|
37072
|
+
stage === "menu" ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Box_default, { flexDirection: "column", marginTop: 1, children: [
|
|
37073
|
+
notice ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Text, { color: "yellow", children: notice }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Text, { dimColor: true, children: "\u5C1A\u672A\u914D\u7F6E\u5F00\u53D1\u8005 Token\uFF0C\u8BF7\u5148\u767B\u5165\u3002" }),
|
|
37074
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Box_default, { flexDirection: "column", marginTop: 1, children: [
|
|
37075
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Text, { inverse: choice === 0, children: [
|
|
35895
37076
|
choice === 0 ? "\u203A " : " ",
|
|
35896
37077
|
"\u914D\u7F6E Token \u767B\u5165"
|
|
35897
37078
|
] }),
|
|
35898
|
-
/* @__PURE__ */ (0,
|
|
37079
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Text, { inverse: choice === 1, children: [
|
|
35899
37080
|
choice === 1 ? "\u203A " : " ",
|
|
35900
37081
|
"\u9000\u51FA"
|
|
35901
37082
|
] })
|
|
35902
37083
|
] }),
|
|
35903
|
-
/* @__PURE__ */ (0,
|
|
35904
|
-
] }) : /* @__PURE__ */ (0,
|
|
35905
|
-
/* @__PURE__ */ (0,
|
|
35906
|
-
/* @__PURE__ */ (0,
|
|
35907
|
-
/* @__PURE__ */ (0,
|
|
35908
|
-
/* @__PURE__ */ (0,
|
|
35909
|
-
/* @__PURE__ */ (0,
|
|
35910
|
-
/* @__PURE__ */ (0,
|
|
37084
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Box_default, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Text, { dimColor: true, children: "\u2191\u2193 \u9009\u62E9 \xB7 Enter \u786E\u5B9A \xB7 q \u9000\u51FA" }) })
|
|
37085
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Box_default, { flexDirection: "column", marginTop: 1, children: [
|
|
37086
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Text, { dimColor: true, children: "\u7C98\u8D34\u4F60\u7684\u5F00\u53D1\u8005 Token\uFF1A" }),
|
|
37087
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Text, { dimColor: true, children: "AutoDL \u63A7\u5236\u53F0 \u2192 \u8BBE\u7F6E \u2192 \u5F00\u53D1\u8005 Token\uFF08\u9700\u5148\u5B8C\u6210\u5B9E\u540D\u8BA4\u8BC1\uFF09" }),
|
|
37088
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Box_default, { marginTop: 1, children: [
|
|
37089
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Text, { children: "\u203A " }),
|
|
37090
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Text, { color: "green", children: token ? "\u2022".repeat(Math.min(token.length, 48)) : "" }),
|
|
37091
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Text, { dimColor: true, children: token ? ` (${token.length} \u5B57\u7B26)` : "\u7B49\u5F85\u8F93\u5165\u2026" })
|
|
35911
37092
|
] }),
|
|
35912
|
-
/* @__PURE__ */ (0,
|
|
37093
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Box_default, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Text, { dimColor: true, children: verifying ? "\u6B63\u5728\u9A8C\u8BC1\u2026" : "Enter \u9A8C\u8BC1\u5E76\u4FDD\u5B58 \xB7 Esc \u8FD4\u56DE \xB7 \u652F\u6301\u76F4\u63A5\u7C98\u8D34" }) })
|
|
35913
37094
|
] }),
|
|
35914
|
-
error ? /* @__PURE__ */ (0,
|
|
37095
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Box_default, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Text, { color: "red", children: [
|
|
35915
37096
|
"\u2716 ",
|
|
35916
37097
|
error
|
|
35917
37098
|
] }) }) : null,
|
|
35918
|
-
/* @__PURE__ */ (0,
|
|
37099
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Box_default, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Text, { dimColor: true, children: [
|
|
35919
37100
|
"\u9A8C\u8BC1\u901A\u8FC7\u540E\u4F1A\u4FDD\u5B58\u5230 ",
|
|
35920
37101
|
configPath(),
|
|
35921
37102
|
"\uFF08\u6743\u9650 0600\uFF09"
|
|
@@ -35925,7 +37106,7 @@ function Login({
|
|
|
35925
37106
|
}
|
|
35926
37107
|
|
|
35927
37108
|
// src/tui/screens/stock.tsx
|
|
35928
|
-
var
|
|
37109
|
+
var import_jsx_runtime13 = __toESM(require_jsx_runtime(), 1);
|
|
35929
37110
|
function toStockRows(snapshots, showEmpty) {
|
|
35930
37111
|
const rentable = new Map(GPU_SPECS.map((spec) => [spec.stockName, spec.id]));
|
|
35931
37112
|
const proRegions = new Set(PRO_CREATE_REGIONS.map((region) => region.id));
|
|
@@ -35951,7 +37132,7 @@ var columns = [
|
|
|
35951
37132
|
header: "\u53EF\u5EFAPro",
|
|
35952
37133
|
width: 8,
|
|
35953
37134
|
text: (row) => row.proCreate ? "\u662F" : "\u5426",
|
|
35954
|
-
render: (row) => row.proCreate ? /* @__PURE__ */ (0,
|
|
37135
|
+
render: (row) => row.proCreate ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Text, { color: "green", children: "\u662F" }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Text, { dimColor: true, children: "\u5426" })
|
|
35955
37136
|
},
|
|
35956
37137
|
{
|
|
35957
37138
|
header: "GPU",
|
|
@@ -35962,19 +37143,19 @@ var columns = [
|
|
|
35962
37143
|
header: "\u53EF\u79DF\u89C4\u683C",
|
|
35963
37144
|
width: 12,
|
|
35964
37145
|
text: (row) => row.gpuSpec ?? "\u2014",
|
|
35965
|
-
render: (row, clipped) => row.gpuSpec ? /* @__PURE__ */ (0,
|
|
37146
|
+
render: (row, clipped) => row.gpuSpec ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Text, { color: "green", children: clipped }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Text, { dimColor: true, children: clipped })
|
|
35966
37147
|
},
|
|
35967
37148
|
{
|
|
35968
37149
|
header: "\u7A7A\u95F2",
|
|
35969
37150
|
width: 7,
|
|
35970
37151
|
text: (row) => String(row.idle),
|
|
35971
|
-
render: (row, clipped) => /* @__PURE__ */ (0,
|
|
37152
|
+
render: (row, clipped) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Text, { bold: row.idle > 0, children: clipped })
|
|
35972
37153
|
},
|
|
35973
37154
|
{
|
|
35974
37155
|
header: "\u603B\u6570",
|
|
35975
37156
|
width: 7,
|
|
35976
37157
|
text: (row) => String(row.total),
|
|
35977
|
-
render: (_row, clipped) => /* @__PURE__ */ (0,
|
|
37158
|
+
render: (_row, clipped) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Text, { dimColor: true, children: clipped })
|
|
35978
37159
|
}
|
|
35979
37160
|
];
|
|
35980
37161
|
function StockScreen({
|
|
@@ -35982,8 +37163,8 @@ function StockScreen({
|
|
|
35982
37163
|
selectedIndex,
|
|
35983
37164
|
loading
|
|
35984
37165
|
}) {
|
|
35985
|
-
return /* @__PURE__ */ (0,
|
|
35986
|
-
/* @__PURE__ */ (0,
|
|
37166
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Box_default, { flexDirection: "column", children: [
|
|
37167
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
35987
37168
|
Table,
|
|
35988
37169
|
{
|
|
35989
37170
|
columns,
|
|
@@ -35993,27 +37174,29 @@ function StockScreen({
|
|
|
35993
37174
|
emptyMessage: loading ? "\u6B63\u5728\u67E5\u8BE2\u5E93\u5B58\u2026" : "\u67E5\u8BE2\u8303\u56F4\u5185\u6CA1\u6709\u7A7A\u95F2 GPU"
|
|
35994
37175
|
}
|
|
35995
37176
|
),
|
|
35996
|
-
/* @__PURE__ */ (0,
|
|
35997
|
-
/* @__PURE__ */ (0,
|
|
37177
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Box_default, { flexDirection: "column", paddingX: 1, marginTop: 1, children: [
|
|
37178
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Text, { dimColor: true, children: [
|
|
35998
37179
|
"\u300C\u53EF\u5EFAPro\u300D\u53EA\u6709 ",
|
|
35999
37180
|
PRO_CREATE_REGIONS.map((r) => r.displayName).join(" / "),
|
|
36000
37181
|
" \u4E3A\u662F\uFF0C \u5176\u4F59\u5730\u533A\u4EC5\u7528\u4E8E\u5F39\u6027\u90E8\u7F72\u3002"
|
|
36001
37182
|
] }),
|
|
36002
|
-
/* @__PURE__ */ (0,
|
|
37183
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Text, { color: "yellow", children: "\u6570\u5B57\u6765\u81EA\u300C\u5F39\u6027\u90E8\u7F72 GPU \u5E93\u5B58\u300D\uFF0C\u4E0D\u4EE3\u8868 Pro \u5B9E\u4F8B\u53EF\u7528\u91CF\u2014\u2014\u5B9E\u6D4B\u51FA\u73B0\u8FC7\u663E\u793A 140 \u5F20\u7A7A\u95F2\u3001\u521B\u5EFA\u5374\u63D0\u793A\u6682\u65E0\u5E93\u5B58\u7684\u60C5\u51B5\u3002" })
|
|
36003
37184
|
] })
|
|
36004
37185
|
] });
|
|
36005
37186
|
}
|
|
36006
37187
|
|
|
36007
37188
|
// src/tui/app.tsx
|
|
36008
|
-
var
|
|
37189
|
+
var import_jsx_runtime14 = __toESM(require_jsx_runtime(), 1);
|
|
36009
37190
|
var SCREEN_TITLES = {
|
|
36010
37191
|
dashboard: "\u5B9E\u4F8B\u770B\u677F",
|
|
36011
37192
|
detail: "\u5B9E\u4F8B\u8BE6\u60C5",
|
|
36012
37193
|
stock: "GPU \u5E93\u5B58",
|
|
36013
37194
|
create: "\u65B0\u5EFA\u5B9E\u4F8B",
|
|
36014
|
-
help: "\u5FEB\u6377\u952E"
|
|
37195
|
+
help: "\u5FEB\u6377\u952E",
|
|
37196
|
+
files: "\u6587\u4EF6\u7BA1\u7406",
|
|
37197
|
+
transfers: "\u4F20\u8F93\u961F\u5217"
|
|
36015
37198
|
};
|
|
36016
|
-
var DASHBOARD_KEYS = "\u2191\u2193 \u79FB\u52A8 \xB7 Enter \u8BE6\u60C5 \xB7 s \u5F00\u673A \xB7 x \u5173\u673A \xB7
|
|
37199
|
+
var DASHBOARD_KEYS = "\u2191\u2193 \u79FB\u52A8 \xB7 Enter \u8BE6\u60C5 \xB7 s \u5F00\u673A \xB7 x \u5173\u673A \xB7 ctrl+d \u91CA\u653E \xB7 g \u5E93\u5B58 \xB7 r \u5237\u65B0 \xB7 ctrl+l \u9000\u51FA\u767B\u5F55 \xB7 ? \u5E2E\u52A9 \xB7 q \u9000\u51FA";
|
|
36017
37200
|
var isCtrl = (input, key, letter) => key.ctrl && input.toLowerCase() === letter;
|
|
36018
37201
|
var HELP_COLUMNS = ((items) => {
|
|
36019
37202
|
const half = Math.ceil(items.length / 2);
|
|
@@ -36023,25 +37206,35 @@ function App2({
|
|
|
36023
37206
|
client,
|
|
36024
37207
|
token,
|
|
36025
37208
|
tokenSource,
|
|
36026
|
-
onLogout
|
|
37209
|
+
onLogout,
|
|
37210
|
+
baseUrl
|
|
36027
37211
|
}) {
|
|
36028
|
-
const { exit } = use_app_default();
|
|
36029
|
-
const [view, setView] = (0,
|
|
36030
|
-
const [selected, setSelected] = (0,
|
|
36031
|
-
const [notice, setNotice] = (0,
|
|
36032
|
-
const [pending, setPending] = (0,
|
|
36033
|
-
const [busy, setBusy] = (0,
|
|
36034
|
-
const [reveal, setReveal] = (0,
|
|
36035
|
-
const [stock, setStock] = (0,
|
|
36036
|
-
const [stockLoading, setStockLoading] = (0,
|
|
36037
|
-
const [stockIndex, setStockIndex] = (0,
|
|
36038
|
-
const [balance, setBalance] = (0,
|
|
36039
|
-
const [balanceError, setBalanceError] = (0,
|
|
36040
|
-
const [expired, setExpired] = (0,
|
|
36041
|
-
const [
|
|
37212
|
+
const { exit, suspendTerminal } = use_app_default();
|
|
37213
|
+
const [view, setView] = (0, import_react40.useState)("dashboard");
|
|
37214
|
+
const [selected, setSelected] = (0, import_react40.useState)(0);
|
|
37215
|
+
const [notice, setNotice] = (0, import_react40.useState)(null);
|
|
37216
|
+
const [pending, setPending] = (0, import_react40.useState)(null);
|
|
37217
|
+
const [busy, setBusy] = (0, import_react40.useState)(false);
|
|
37218
|
+
const [reveal, setReveal] = (0, import_react40.useState)(false);
|
|
37219
|
+
const [stock, setStock] = (0, import_react40.useState)([]);
|
|
37220
|
+
const [stockLoading, setStockLoading] = (0, import_react40.useState)(false);
|
|
37221
|
+
const [stockIndex, setStockIndex] = (0, import_react40.useState)(0);
|
|
37222
|
+
const [balance, setBalance] = (0, import_react40.useState)(null);
|
|
37223
|
+
const [balanceError, setBalanceError] = (0, import_react40.useState)(null);
|
|
37224
|
+
const [expired, setExpired] = (0, import_react40.useState)(null);
|
|
37225
|
+
const [terminalActive, setTerminalActive] = (0, import_react40.useState)(false);
|
|
37226
|
+
const [workspace, setWorkspace] = (0, import_react40.useState)(null);
|
|
37227
|
+
const [fileUuid, setFileUuid] = (0, import_react40.useState)("");
|
|
37228
|
+
const [fileGate, setFileGate] = (0, import_react40.useState)(void 0);
|
|
37229
|
+
const queueRef = (0, import_react40.useRef)(null);
|
|
37230
|
+
const accessController = (0, import_react40.useRef)(null);
|
|
37231
|
+
const fileUuidRef = (0, import_react40.useRef)("");
|
|
37232
|
+
const queueUnsubscribe = (0, import_react40.useRef)(null);
|
|
37233
|
+
const [queueNotice, setQueueNotice] = (0, import_react40.useState)(null);
|
|
37234
|
+
const [watched, setWatched] = (0, import_react40.useState)(void 0);
|
|
36042
37235
|
const { columns: columns2, rows: terminalRows } = useTerminalSize();
|
|
36043
|
-
const identity = (0,
|
|
36044
|
-
const paused = view === "create" || pending !== null || expired !== null;
|
|
37236
|
+
const identity = (0, import_react40.useMemo)(() => identityFromToken(token), [token]);
|
|
37237
|
+
const paused = view === "create" || pending !== null || expired !== null || terminalActive;
|
|
36045
37238
|
const {
|
|
36046
37239
|
rows,
|
|
36047
37240
|
loading,
|
|
@@ -36053,24 +37246,24 @@ function App2({
|
|
|
36053
37246
|
historyFor,
|
|
36054
37247
|
loadSnapshot
|
|
36055
37248
|
} = useInstances(client, { paused, watch: watched });
|
|
36056
|
-
const noteAuthFailure = (0,
|
|
37249
|
+
const noteAuthFailure = (0, import_react40.useCallback)((err) => {
|
|
36057
37250
|
if (isAuthError(err)) setExpired((current) => current ?? err.message);
|
|
36058
37251
|
}, []);
|
|
36059
|
-
(0,
|
|
37252
|
+
(0, import_react40.useEffect)(() => {
|
|
36060
37253
|
if (authError) setExpired((current) => current ?? authError);
|
|
36061
37254
|
}, [authError]);
|
|
36062
37255
|
const selectedIndex = Math.min(selected, Math.max(0, rows.length - 1));
|
|
36063
37256
|
const row = rows[selectedIndex];
|
|
36064
|
-
(0,
|
|
37257
|
+
(0, import_react40.useEffect)(() => {
|
|
36065
37258
|
if (view === "detail" && !row) setView("dashboard");
|
|
36066
37259
|
}, [view, row]);
|
|
36067
37260
|
const selectedUuid = row?.instance.uuid;
|
|
36068
37261
|
const selectedRunning = row?.instance.status === "running";
|
|
36069
|
-
(0,
|
|
37262
|
+
(0, import_react40.useEffect)(() => {
|
|
36070
37263
|
setWatched(selectedRunning ? selectedUuid : void 0);
|
|
36071
37264
|
if (selectedUuid && selectedRunning) loadSnapshot(selectedUuid);
|
|
36072
37265
|
}, [selectedUuid, selectedRunning, loadSnapshot]);
|
|
36073
|
-
(0,
|
|
37266
|
+
(0, import_react40.useEffect)(() => {
|
|
36074
37267
|
if (expired) return;
|
|
36075
37268
|
let cancelled = false;
|
|
36076
37269
|
const load = () => {
|
|
@@ -36092,19 +37285,87 @@ function App2({
|
|
|
36092
37285
|
clearInterval(timer);
|
|
36093
37286
|
};
|
|
36094
37287
|
}, [client, expired, noteAuthFailure]);
|
|
36095
|
-
const noticeTimer = (0,
|
|
36096
|
-
const flash = (0,
|
|
37288
|
+
const noticeTimer = (0, import_react40.useRef)(null);
|
|
37289
|
+
const flash = (0, import_react40.useCallback)((message) => {
|
|
36097
37290
|
setNotice(message);
|
|
36098
37291
|
if (noticeTimer.current) clearTimeout(noticeTimer.current);
|
|
36099
37292
|
noticeTimer.current = setTimeout(() => setNotice(null), 6e3);
|
|
36100
37293
|
}, []);
|
|
36101
|
-
(0,
|
|
37294
|
+
(0, import_react40.useEffect)(
|
|
36102
37295
|
() => () => {
|
|
36103
37296
|
if (noticeTimer.current) clearTimeout(noticeTimer.current);
|
|
36104
37297
|
},
|
|
36105
37298
|
[]
|
|
36106
37299
|
);
|
|
36107
|
-
const
|
|
37300
|
+
const getQueue = (0, import_react40.useCallback)(() => {
|
|
37301
|
+
if (!queueRef.current) {
|
|
37302
|
+
const account = [identity.tenant, identity.uid ?? identity.uuid ?? token];
|
|
37303
|
+
const namespace = createHash("sha256").update(
|
|
37304
|
+
JSON.stringify([
|
|
37305
|
+
(baseUrl ?? resolveBaseUrl() ?? DEFAULT_BASE_URL).replace(/\/+$/, ""),
|
|
37306
|
+
account
|
|
37307
|
+
])
|
|
37308
|
+
).digest("hex");
|
|
37309
|
+
queueRef.current = new TransferQueue(client, namespace);
|
|
37310
|
+
const queue = queueRef.current;
|
|
37311
|
+
const updateNotice = () => {
|
|
37312
|
+
const jobs = queue.snapshot();
|
|
37313
|
+
const unfinished = jobs.filter(
|
|
37314
|
+
(job) => job.state !== "completed" && job.state !== "cancelled"
|
|
37315
|
+
);
|
|
37316
|
+
setQueueNotice(
|
|
37317
|
+
unfinished.length ? `\u4F20\u8F93 ${unfinished.length} \u9879\u672A\u5B8C\u6210${jobs.some((job) => job.state === "conflict") ? " \xB7 \u7B49\u5F85\u51B2\u7A81\u5904\u7406" : ""} \xB7 t \u67E5\u770B\u961F\u5217` : null
|
|
37318
|
+
);
|
|
37319
|
+
};
|
|
37320
|
+
queueUnsubscribe.current = queue.subscribe(updateNotice);
|
|
37321
|
+
updateNotice();
|
|
37322
|
+
}
|
|
37323
|
+
return queueRef.current;
|
|
37324
|
+
}, [client, baseUrl, identity, token]);
|
|
37325
|
+
(0, import_react40.useEffect)(
|
|
37326
|
+
() => () => {
|
|
37327
|
+
accessController.current?.abort();
|
|
37328
|
+
queueUnsubscribe.current?.();
|
|
37329
|
+
void queueRef.current?.dispose().catch((err) => {
|
|
37330
|
+
process.stderr.write(`\u4F20\u8F93\u961F\u5217\u5173\u95ED\u5931\u8D25\uFF1A${err.message}
|
|
37331
|
+
`);
|
|
37332
|
+
});
|
|
37333
|
+
},
|
|
37334
|
+
[]
|
|
37335
|
+
);
|
|
37336
|
+
(0, import_react40.useEffect)(() => {
|
|
37337
|
+
if (expired) {
|
|
37338
|
+
void queueRef.current?.pauseAll().catch((err) => flash(err.message));
|
|
37339
|
+
}
|
|
37340
|
+
}, [expired, flash]);
|
|
37341
|
+
const requestExit = (0, import_react40.useCallback)(() => {
|
|
37342
|
+
accessController.current?.abort();
|
|
37343
|
+
if (queueRef.current?.hasPending()) setPending({ kind: "exit" });
|
|
37344
|
+
else exit();
|
|
37345
|
+
}, [exit]);
|
|
37346
|
+
const finishLogout = async (reason) => {
|
|
37347
|
+
if (busy) return;
|
|
37348
|
+
setBusy(true);
|
|
37349
|
+
try {
|
|
37350
|
+
if (queueRef.current) await queueRef.current.pauseAll();
|
|
37351
|
+
onLogout(reason);
|
|
37352
|
+
} catch (err) {
|
|
37353
|
+
flash(err.message);
|
|
37354
|
+
setBusy(false);
|
|
37355
|
+
}
|
|
37356
|
+
};
|
|
37357
|
+
const finishExit = async () => {
|
|
37358
|
+
if (busy) return;
|
|
37359
|
+
setBusy(true);
|
|
37360
|
+
try {
|
|
37361
|
+
if (queueRef.current) await queueRef.current.pauseAll();
|
|
37362
|
+
exit();
|
|
37363
|
+
} catch (err) {
|
|
37364
|
+
flash(err.message);
|
|
37365
|
+
setBusy(false);
|
|
37366
|
+
}
|
|
37367
|
+
};
|
|
37368
|
+
const act = (0, import_react40.useCallback)(
|
|
36108
37369
|
async (label, fn) => {
|
|
36109
37370
|
setBusy(true);
|
|
36110
37371
|
setNotice(`${label}\u2026`);
|
|
@@ -36120,7 +37381,7 @@ function App2({
|
|
|
36120
37381
|
},
|
|
36121
37382
|
[flash, refresh, noteAuthFailure]
|
|
36122
37383
|
);
|
|
36123
|
-
const loadStock = (0,
|
|
37384
|
+
const loadStock = (0, import_react40.useCallback)(async () => {
|
|
36124
37385
|
setStockLoading(true);
|
|
36125
37386
|
try {
|
|
36126
37387
|
const { snapshots } = await getStockByRegion(client);
|
|
@@ -36132,7 +37393,106 @@ function App2({
|
|
|
36132
37393
|
setStockLoading(false);
|
|
36133
37394
|
}
|
|
36134
37395
|
}, [client, flash, noteAuthFailure]);
|
|
36135
|
-
const
|
|
37396
|
+
const copySSH = (0, import_react40.useCallback)(
|
|
37397
|
+
(uuid) => {
|
|
37398
|
+
const snapshot = snapshotFor(uuid);
|
|
37399
|
+
if (!snapshot?.ssh.host || !snapshot.ssh.port) {
|
|
37400
|
+
flash("\u5B9E\u4F8B\u672A\u8FD0\u884C\u6216 SSH \u4FE1\u606F\u5C1A\u672A\u5C31\u7EEA");
|
|
37401
|
+
return;
|
|
37402
|
+
}
|
|
37403
|
+
const command = snapshot.ssh.command ?? `ssh -p ${snapshot.ssh.port} root@${snapshot.ssh.host}`;
|
|
37404
|
+
void copyToClipboard(command).then((result) => {
|
|
37405
|
+
flash(
|
|
37406
|
+
result.method === "native" ? `\u2714 \u5DF2\u590D\u5236\uFF1A${command}\u3000\u5BC6\u7801 ${snapshot.ssh.password}` : `${command}\u3000\u5BC6\u7801 ${snapshot.ssh.password}\u3000\uFF08${result.note}\uFF09`
|
|
37407
|
+
);
|
|
37408
|
+
});
|
|
37409
|
+
},
|
|
37410
|
+
[flash, snapshotFor]
|
|
37411
|
+
);
|
|
37412
|
+
const performAccess = (0, import_react40.useCallback)(
|
|
37413
|
+
async (action, signal) => {
|
|
37414
|
+
if (signal?.aborted) return;
|
|
37415
|
+
if (action.kind === "files") {
|
|
37416
|
+
setWorkspace(
|
|
37417
|
+
(prev) => prev && fileUuidRef.current === action.uuid ? prev : new FileWorkspace(client, action.uuid)
|
|
37418
|
+
);
|
|
37419
|
+
fileUuidRef.current = action.uuid;
|
|
37420
|
+
setFileUuid(action.uuid);
|
|
37421
|
+
getQueue();
|
|
37422
|
+
setView("files");
|
|
37423
|
+
if (signal) return;
|
|
37424
|
+
const gate = (async () => {
|
|
37425
|
+
const status = await getInstanceStatus(client, action.uuid);
|
|
37426
|
+
if (status !== "running") {
|
|
37427
|
+
setPending({ kind: "power", action });
|
|
37428
|
+
throw new Error(`\u5B9E\u4F8B ${action.uuid} \u5F53\u524D\u672A\u8FD0\u884C\uFF0C\u8FDC\u7A0B\u76EE\u5F55\u9700\u5F00\u673A\u540E\u67E5\u770B`);
|
|
37429
|
+
}
|
|
37430
|
+
})();
|
|
37431
|
+
gate.catch((err) => {
|
|
37432
|
+
flash(err.message);
|
|
37433
|
+
noteAuthFailure(err);
|
|
37434
|
+
});
|
|
37435
|
+
setFileGate(gate.then(() => void 0));
|
|
37436
|
+
return;
|
|
37437
|
+
}
|
|
37438
|
+
if (action.kind === "resume") {
|
|
37439
|
+
getQueue().resume(action.jobId);
|
|
37440
|
+
return;
|
|
37441
|
+
}
|
|
37442
|
+
setTerminalActive(true);
|
|
37443
|
+
try {
|
|
37444
|
+
let code = 0;
|
|
37445
|
+
await suspendTerminal(async () => {
|
|
37446
|
+
process.stdout.write(LEAVE_ALT_SCREEN);
|
|
37447
|
+
try {
|
|
37448
|
+
code = await connectTerminal(client, action.uuid, signal ? { signal } : {});
|
|
37449
|
+
} finally {
|
|
37450
|
+
process.stdout.write(signal?.aborted ? LEAVE_ALT_SCREEN : ENTER_ALT_SCREEN + CLEAR);
|
|
37451
|
+
}
|
|
37452
|
+
});
|
|
37453
|
+
flash(`SSH \u4F1A\u8BDD\u5DF2\u7ED3\u675F\uFF08\u9000\u51FA\u7801 ${code}\uFF09`);
|
|
37454
|
+
} finally {
|
|
37455
|
+
setTerminalActive(false);
|
|
37456
|
+
}
|
|
37457
|
+
},
|
|
37458
|
+
[client, flash, getQueue, noteAuthFailure, suspendTerminal]
|
|
37459
|
+
);
|
|
37460
|
+
const requestAccess = (0, import_react40.useCallback)(
|
|
37461
|
+
async (action) => {
|
|
37462
|
+
if (action.kind === "files") {
|
|
37463
|
+
if (busy) return;
|
|
37464
|
+
await performAccess(action);
|
|
37465
|
+
return;
|
|
37466
|
+
}
|
|
37467
|
+
if (busy) return;
|
|
37468
|
+
setBusy(true);
|
|
37469
|
+
const controller = new AbortController();
|
|
37470
|
+
accessController.current = controller;
|
|
37471
|
+
try {
|
|
37472
|
+
const status = await getInstanceStatus(client, action.uuid);
|
|
37473
|
+
if (controller.signal.aborted) return;
|
|
37474
|
+
if (status !== "running") {
|
|
37475
|
+
setPending({ kind: "power", action });
|
|
37476
|
+
return;
|
|
37477
|
+
}
|
|
37478
|
+
await performAccess(action, controller.signal);
|
|
37479
|
+
} catch (err) {
|
|
37480
|
+
flash(err.message);
|
|
37481
|
+
noteAuthFailure(err);
|
|
37482
|
+
} finally {
|
|
37483
|
+
setBusy(false);
|
|
37484
|
+
}
|
|
37485
|
+
},
|
|
37486
|
+
[busy, client, flash, noteAuthFailure, performAccess]
|
|
37487
|
+
);
|
|
37488
|
+
const resumeTransfer = (0, import_react40.useCallback)(
|
|
37489
|
+
(jobId) => {
|
|
37490
|
+
const job = queueRef.current?.snapshot().find((entry) => entry.request.id === jobId);
|
|
37491
|
+
if (job) void requestAccess({ kind: "resume", uuid: job.request.uuid, jobId });
|
|
37492
|
+
},
|
|
37493
|
+
[requestAccess]
|
|
37494
|
+
);
|
|
37495
|
+
const submitCreate = (0, import_react40.useCallback)(
|
|
36136
37496
|
async (draft) => {
|
|
36137
37497
|
setBusy(true);
|
|
36138
37498
|
try {
|
|
@@ -36162,6 +37522,8 @@ function App2({
|
|
|
36162
37522
|
);
|
|
36163
37523
|
use_input_default(
|
|
36164
37524
|
(input, key) => {
|
|
37525
|
+
if (isCtrl(input, key, "c")) return requestExit();
|
|
37526
|
+
if (view === "files" || view === "transfers" || view === "create" || expired) return;
|
|
36165
37527
|
if (view === "help") {
|
|
36166
37528
|
setView("dashboard");
|
|
36167
37529
|
return;
|
|
@@ -36179,15 +37541,30 @@ function App2({
|
|
|
36179
37541
|
}
|
|
36180
37542
|
if (view === "detail") {
|
|
36181
37543
|
if (input === "p") return setReveal((v) => !v);
|
|
37544
|
+
if (input === "r") return refresh();
|
|
37545
|
+
if (!row) return;
|
|
37546
|
+
if (input === "h") return void requestAccess({ kind: "ssh", uuid: row.instance.uuid });
|
|
37547
|
+
if (input === "f") return void requestAccess({ kind: "files", uuid: row.instance.uuid });
|
|
37548
|
+
if (input === "c") return copySSH(row.instance.uuid);
|
|
37549
|
+
if (input === "t") {
|
|
37550
|
+
try {
|
|
37551
|
+
getQueue();
|
|
37552
|
+
setView("transfers");
|
|
37553
|
+
} catch (err) {
|
|
37554
|
+
flash(err.message);
|
|
37555
|
+
}
|
|
37556
|
+
return;
|
|
37557
|
+
}
|
|
37558
|
+
if (input === "n") return setView("create");
|
|
36182
37559
|
return;
|
|
36183
37560
|
}
|
|
36184
|
-
if (input === "q"
|
|
37561
|
+
if (input === "q") return requestExit();
|
|
37562
|
+
if (isCtrl(input, key, "c")) return;
|
|
36185
37563
|
if (input === "?") return setView("help");
|
|
36186
37564
|
if (key.upArrow || input === "k") return setSelected((v) => Math.max(0, v - 1));
|
|
36187
37565
|
if (key.downArrow || input === "j")
|
|
36188
37566
|
return setSelected((v) => Math.max(0, Math.min(rows.length - 1, v + 1)));
|
|
36189
37567
|
if (input === "r") return refresh();
|
|
36190
|
-
if (input === "n") return setView("create");
|
|
36191
37568
|
if (isCtrl(input, key, "l")) return setPending({ kind: "logout" });
|
|
36192
37569
|
if (input === "g") {
|
|
36193
37570
|
setView("stock");
|
|
@@ -36213,37 +37590,31 @@ function App2({
|
|
|
36213
37590
|
return stopped ? `\u2714 ${row.instance.uuid} \u5DF2\u5173\u673A\uFF0C\u8BA1\u8D39\u5DF2\u505C\u6B62` : `\u26A0 \u5173\u673A\u672A\u751F\u6548\uFF0C\u72B6\u6001\u4ECD\u4E3A ${status}\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5`;
|
|
36214
37591
|
});
|
|
36215
37592
|
}
|
|
36216
|
-
if (input === "c") {
|
|
36217
|
-
const snapshot = snapshotFor(row.instance.uuid);
|
|
36218
|
-
if (!snapshot?.ssh.host || !snapshot.ssh.port) {
|
|
36219
|
-
return flash("\u5B9E\u4F8B\u672A\u8FD0\u884C\u6216 SSH \u4FE1\u606F\u5C1A\u672A\u5C31\u7EEA");
|
|
36220
|
-
}
|
|
36221
|
-
const command = snapshot.ssh.command ?? `ssh -p ${snapshot.ssh.port} root@${snapshot.ssh.host}`;
|
|
36222
|
-
void copyToClipboard(command).then((result) => {
|
|
36223
|
-
flash(
|
|
36224
|
-
result.method === "native" ? `\u2714 \u5DF2\u590D\u5236\uFF1A${command}\u3000\u5BC6\u7801 ${snapshot.ssh.password}` : `${command}\u3000\u5BC6\u7801 ${snapshot.ssh.password}\u3000\uFF08${result.note}\uFF09`
|
|
36225
|
-
);
|
|
36226
|
-
});
|
|
36227
|
-
return;
|
|
36228
|
-
}
|
|
36229
37593
|
if (isCtrl(input, key, "d")) {
|
|
36230
37594
|
if (busy) return;
|
|
36231
37595
|
return setPending({ kind: "release", row });
|
|
36232
37596
|
}
|
|
36233
37597
|
},
|
|
36234
|
-
{
|
|
37598
|
+
{
|
|
37599
|
+
isActive: pending === null && !terminalActive
|
|
37600
|
+
}
|
|
36235
37601
|
);
|
|
36236
|
-
const hints = expired ? "Enter \u91CD\u65B0\u767B\u5165 \xB7 q \u9000\u51FA" : pending ? CONFIRM_KEYS : view === "create" ? (
|
|
37602
|
+
const hints = expired && !pending ? "Enter \u91CD\u65B0\u767B\u5165 \xB7 q \u9000\u51FA" : pending ? CONFIRM_KEYS : view === "files" || view === "transfers" ? "Esc \u8FD4\u56DE \xB7 ctrl+c \u9000\u51FA\uFF08\u672A\u5B8C\u6210\u4EFB\u52A1\u5148\u786E\u8BA4\uFF09" : view === "create" ? (
|
|
36237
37603
|
// Step-agnostic on purpose: the wizard's own line says what Enter does at this
|
|
36238
37604
|
// step, and only Esc is true at every one of them.
|
|
36239
37605
|
"Esc \u53D6\u6D88"
|
|
36240
|
-
) : view === "help" ? "\u6309\u4EFB\u610F\u952E\u8FD4\u56DE" : view === "detail" ? "p \u663E\u793A/\u9690\u85CF\u5BC6\u7801 \xB7 Esc \u8FD4\u56DE" : view === "stock" ? "\u2191\u2193 \u79FB\u52A8 \xB7 r \u5237\u65B0 \xB7 Esc \u8FD4\u56DE" : DASHBOARD_KEYS;
|
|
37606
|
+
) : view === "help" ? "\u6309\u4EFB\u610F\u952E\u8FD4\u56DE" : view === "detail" ? "h SSH\u767B\u5F55 \xB7 f \u6587\u4EF6 \xB7 t \u4F20\u8F93 \xB7 c \u590D\u5236SSH \xB7 n \u65B0\u5EFA \xB7 p \u663E\u793A/\u9690\u85CF\u5BC6\u7801 \xB7 Esc \u8FD4\u56DE" : view === "stock" ? "\u2191\u2193 \u79FB\u52A8 \xB7 r \u5237\u65B0 \xB7 Esc \u8FD4\u56DE" : DASHBOARD_KEYS;
|
|
36241
37607
|
const showsDashboard = !expired && !pending && view === "dashboard";
|
|
37608
|
+
const showsFiles = !expired && !pending && (view === "files" || view === "transfers");
|
|
36242
37609
|
return (
|
|
36243
37610
|
// Claim the entire terminal so the dashboard is a fixed full-screen surface rather
|
|
36244
37611
|
// than a block that grows and shrinks with its content.
|
|
36245
|
-
/* @__PURE__ */ (0,
|
|
36246
|
-
/* @__PURE__ */ (0,
|
|
37612
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(Box_default, { flexDirection: "column", height: terminalRows, width: columns2, children: [
|
|
37613
|
+
showsFiles ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Box_default, { height: 1, flexShrink: 0, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(Text, { bold: true, wrap: "truncate", children: [
|
|
37614
|
+
"AutoDL \xB7 ",
|
|
37615
|
+
SCREEN_TITLES[view],
|
|
37616
|
+
view === "files" ? ` \xB7 ${fileUuid}` : ""
|
|
37617
|
+
] }) }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
36247
37618
|
Header,
|
|
36248
37619
|
{
|
|
36249
37620
|
subtitle: SCREEN_TITLES[view],
|
|
@@ -36253,27 +37624,56 @@ function App2({
|
|
|
36253
37624
|
columns: columns2
|
|
36254
37625
|
}
|
|
36255
37626
|
),
|
|
36256
|
-
expired ? /* @__PURE__ */ (0,
|
|
37627
|
+
expired && !pending ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
36257
37628
|
SessionExpired,
|
|
36258
37629
|
{
|
|
36259
37630
|
message: expired,
|
|
36260
|
-
onRelogin: () =>
|
|
36261
|
-
onQuit:
|
|
37631
|
+
onRelogin: () => void finishLogout("\u4E0A\u4E00\u6B21\u4F1A\u8BDD\u7684 Token \u5DF2\u5931\u6548\uFF0C\u8BF7\u91CD\u65B0\u767B\u5165\u3002"),
|
|
37632
|
+
onQuit: requestExit
|
|
36262
37633
|
}
|
|
36263
|
-
) : pending?.kind === "logout" ? /* @__PURE__ */ (0,
|
|
37634
|
+
) : pending?.kind === "logout" ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
36264
37635
|
Confirm,
|
|
36265
37636
|
{
|
|
36266
37637
|
title: "\u9000\u51FA\u767B\u5F55\uFF1F",
|
|
36267
|
-
detail: `\u4F1A\u6E05\u9664\u4FDD\u5B58\u5728 ${configPath()} \u7684 Token\uFF0C\u5E76\u8FD4\u56DE\u767B\u5165\u754C\u9762\u3002\u5B9E\u4F8B\
|
|
37638
|
+
detail: `\u4F1A\u5148\u6682\u505C\u672A\u5B8C\u6210\u4F20\u8F93\uFF0C\u6E05\u9664\u4FDD\u5B58\u5728 ${configPath()} \u7684 Token\uFF0C\u5E76\u8FD4\u56DE\u767B\u5165\u754C\u9762\u3002\u5B9E\u4F8B\u7EE7\u7EED\u8BA1\u8D39\uFF1B\u4F20\u8F93\u8BB0\u5F55\u4FDD\u7559\uFF0C\u91CD\u65B0\u767B\u5F55\u540E\u53EF\u624B\u52A8\u6062\u590D\u3002`,
|
|
36268
37639
|
danger: tokenOverrideNote(tokenSource) ?? void 0,
|
|
36269
37640
|
confirmLabel: "\u9000\u51FA\u767B\u5F55",
|
|
37641
|
+
onConfirm: () => void finishLogout(),
|
|
37642
|
+
onCancel: () => setPending(null)
|
|
37643
|
+
}
|
|
37644
|
+
) : pending?.kind === "exit" ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
37645
|
+
Confirm,
|
|
37646
|
+
{
|
|
37647
|
+
title: "\u6682\u505C\u4F20\u8F93\u5E76\u9000\u51FA\uFF1F",
|
|
37648
|
+
detail: "\u5F53\u524D\u548C\u6392\u961F\u4EFB\u52A1\u5C06\u6682\u505C\uFF0C\u4FDD\u7559\u7EED\u4F20\u6570\u636E\u3002\u4E0B\u6B21\u6253\u5F00\u4F20\u8F93\u961F\u5217\u540E\u53EF\u624B\u52A8\u6062\u590D\uFF1B\u9000\u51FA\u540E\u4E0D\u4F1A\u540E\u53F0\u4F20\u8F93\u3002",
|
|
37649
|
+
confirmLabel: "\u6682\u505C\u5E76\u9000\u51FA",
|
|
37650
|
+
onConfirm: () => void finishExit(),
|
|
37651
|
+
onCancel: () => setPending(null)
|
|
37652
|
+
}
|
|
37653
|
+
) : pending?.kind === "power" ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
37654
|
+
Confirm,
|
|
37655
|
+
{
|
|
37656
|
+
title: `\u542F\u52A8\u5B9E\u4F8B ${pending.action.uuid}\uFF1F`,
|
|
37657
|
+
detail: "\u5B9E\u4F8B\u5C1A\u672A\u8FD0\u884C\u3002\u786E\u8BA4\u540E\u7B49\u5F85\u5F00\u673A\u548C SSH \u5C31\u7EEA\uFF0C\u518D\u7EE7\u7EED\u521A\u624D\u7684\u64CD\u4F5C\u3002",
|
|
37658
|
+
danger: "\u5F00\u673A\u4F1A\u4EA7\u751F\u5B9E\u4F8B\u8D39\u7528\u3002\u81EA\u52A8\u91CD\u8FDE\u4E0D\u4F1A\u81EA\u52A8\u5F00\u673A\u3002",
|
|
37659
|
+
confirmLabel: "\u5F00\u673A\u5E76\u7EE7\u7EED",
|
|
36270
37660
|
onConfirm: () => {
|
|
37661
|
+
const action = pending.action;
|
|
36271
37662
|
setPending(null);
|
|
36272
|
-
|
|
37663
|
+
void act("\u5F00\u673A\u5E76\u8FDE\u63A5", async () => {
|
|
37664
|
+
const controller = new AbortController();
|
|
37665
|
+
accessController.current = controller;
|
|
37666
|
+
await getCredentials(client, action.uuid, {
|
|
37667
|
+
autoStart: true,
|
|
37668
|
+
signal: controller.signal
|
|
37669
|
+
});
|
|
37670
|
+
await performAccess(action, controller.signal);
|
|
37671
|
+
return "\u64CD\u4F5C\u5DF2\u7EE7\u7EED";
|
|
37672
|
+
});
|
|
36273
37673
|
},
|
|
36274
37674
|
onCancel: () => setPending(null)
|
|
36275
37675
|
}
|
|
36276
|
-
) : pending ? /* @__PURE__ */ (0,
|
|
37676
|
+
) : pending?.kind === "release" ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
36277
37677
|
Confirm,
|
|
36278
37678
|
{
|
|
36279
37679
|
title: `\u91CA\u653E\u5B9E\u4F8B ${pending.row.instance.name || pending.row.instance.uuid}\uFF1F`,
|
|
@@ -36290,18 +37690,39 @@ function App2({
|
|
|
36290
37690
|
},
|
|
36291
37691
|
onCancel: () => setPending(null)
|
|
36292
37692
|
}
|
|
36293
|
-
) : view === "
|
|
37693
|
+
) : view === "files" && workspace && queueRef.current ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
37694
|
+
FilesScreen,
|
|
37695
|
+
{
|
|
37696
|
+
workspace,
|
|
37697
|
+
queue: queueRef.current,
|
|
37698
|
+
uuid: fileUuid,
|
|
37699
|
+
width: columns2,
|
|
37700
|
+
height: Math.max(6, terminalRows - 2),
|
|
37701
|
+
onBack: () => setView("dashboard"),
|
|
37702
|
+
onResume: resumeTransfer,
|
|
37703
|
+
...fileGate ? { whenRunning: fileGate } : {}
|
|
37704
|
+
}
|
|
37705
|
+
) : view === "transfers" && queueRef.current ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
37706
|
+
TransferJobs,
|
|
37707
|
+
{
|
|
37708
|
+
queue: queueRef.current,
|
|
37709
|
+
width: columns2,
|
|
37710
|
+
height: Math.max(6, terminalRows - 2),
|
|
37711
|
+
onBack: () => setView("dashboard"),
|
|
37712
|
+
onResume: resumeTransfer
|
|
37713
|
+
}
|
|
37714
|
+
) : view === "create" ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(CreateWizard, { busy, onSubmit: submitCreate, onCancel: () => setView("dashboard") }) : view === "detail" && row ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Detail, { row, snapshot: snapshotFor(row.instance.uuid), revealSecrets: reveal }) : view === "stock" ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
36294
37715
|
StockScreen,
|
|
36295
37716
|
{
|
|
36296
37717
|
rows: toStockRows(stock, false),
|
|
36297
37718
|
selectedIndex: stockIndex,
|
|
36298
37719
|
loading: stockLoading
|
|
36299
37720
|
}
|
|
36300
|
-
) : view === "help" ? /* @__PURE__ */ (0,
|
|
36301
|
-
/* @__PURE__ */ (0,
|
|
36302
|
-
/* @__PURE__ */ (0,
|
|
36303
|
-
/* @__PURE__ */ (0,
|
|
36304
|
-
] }) : /* @__PURE__ */ (0,
|
|
37721
|
+
) : view === "help" ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(Box_default, { flexDirection: "column", borderStyle: "round", paddingX: 1, children: [
|
|
37722
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Text, { bold: true, children: "\u5FEB\u6377\u952E" }),
|
|
37723
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Box_default, { children: HELP_COLUMNS.map((column) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Box_default, { flexDirection: "column", width: 22, children: column.map((item) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Text, { children: item }, item)) }, column[0])) }),
|
|
37724
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Text, { dimColor: true, children: "\u6309\u4EFB\u610F\u952E\u8FD4\u56DE" })
|
|
37725
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
36305
37726
|
Dashboard,
|
|
36306
37727
|
{
|
|
36307
37728
|
rows,
|
|
@@ -36314,13 +37735,13 @@ function App2({
|
|
|
36314
37735
|
height: terminalRows
|
|
36315
37736
|
}
|
|
36316
37737
|
),
|
|
36317
|
-
showsDashboard ? null : /* @__PURE__ */ (0,
|
|
36318
|
-
/* @__PURE__ */ (0,
|
|
37738
|
+
showsDashboard || showsFiles ? null : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Box_default, { flexGrow: 1 }),
|
|
37739
|
+
showsFiles ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Box_default, { height: 1, flexShrink: 0, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Text, { color: "cyan", wrap: "truncate", children: notice ?? "ctrl+c \u9000\u51FA\uFF08\u672A\u5B8C\u6210\u4F20\u8F93\u5148\u786E\u8BA4\uFF09" }) }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
36319
37740
|
StatusBar,
|
|
36320
37741
|
{
|
|
36321
37742
|
rows,
|
|
36322
37743
|
error: expired ? null : error,
|
|
36323
|
-
notice,
|
|
37744
|
+
notice: notice ?? queueNotice,
|
|
36324
37745
|
lastUpdated,
|
|
36325
37746
|
hints
|
|
36326
37747
|
}
|
|
@@ -36330,20 +37751,21 @@ function App2({
|
|
|
36330
37751
|
}
|
|
36331
37752
|
function Root({ globals }) {
|
|
36332
37753
|
const { exit } = use_app_default();
|
|
36333
|
-
const [session, setSession] = (0,
|
|
37754
|
+
const [session, setSession] = (0, import_react40.useState)(() => {
|
|
36334
37755
|
const resolved = tryResolveToken(globals.token);
|
|
36335
37756
|
if (!resolved) return null;
|
|
36336
37757
|
const baseUrl = resolveBaseUrl(globals.baseUrl);
|
|
36337
37758
|
return {
|
|
36338
37759
|
client: new AutoDLClient({ token: resolved.token, ...baseUrl ? { baseUrl } : {} }),
|
|
36339
37760
|
token: resolved.token,
|
|
36340
|
-
source: resolved.source
|
|
37761
|
+
source: resolved.source,
|
|
37762
|
+
baseUrl: baseUrl ?? DEFAULT_BASE_URL
|
|
36341
37763
|
};
|
|
36342
37764
|
});
|
|
36343
|
-
const [error, setError] = (0,
|
|
36344
|
-
const [notice, setNotice] = (0,
|
|
36345
|
-
const [verifying, setVerifying] = (0,
|
|
36346
|
-
const submit = (0,
|
|
37765
|
+
const [error, setError] = (0, import_react40.useState)(null);
|
|
37766
|
+
const [notice, setNotice] = (0, import_react40.useState)(null);
|
|
37767
|
+
const [verifying, setVerifying] = (0, import_react40.useState)(false);
|
|
37768
|
+
const submit = (0, import_react40.useCallback)(
|
|
36347
37769
|
async (token) => {
|
|
36348
37770
|
setVerifying(true);
|
|
36349
37771
|
setError(null);
|
|
@@ -36359,7 +37781,12 @@ function Root({ globals }) {
|
|
|
36359
37781
|
});
|
|
36360
37782
|
if (client !== candidate) await getBalance(client);
|
|
36361
37783
|
setNotice(null);
|
|
36362
|
-
setSession({
|
|
37784
|
+
setSession({
|
|
37785
|
+
client,
|
|
37786
|
+
token: resolved.token,
|
|
37787
|
+
source: resolved.source,
|
|
37788
|
+
baseUrl: baseUrl ?? DEFAULT_BASE_URL
|
|
37789
|
+
});
|
|
36363
37790
|
} catch (err) {
|
|
36364
37791
|
setError(err.message);
|
|
36365
37792
|
} finally {
|
|
@@ -36368,7 +37795,7 @@ function Root({ globals }) {
|
|
|
36368
37795
|
},
|
|
36369
37796
|
[globals.baseUrl, globals.token]
|
|
36370
37797
|
);
|
|
36371
|
-
const logout = (0,
|
|
37798
|
+
const logout = (0, import_react40.useCallback)(
|
|
36372
37799
|
(reason) => {
|
|
36373
37800
|
clearToken();
|
|
36374
37801
|
const override = session ? tokenOverrideNote(session.source) : null;
|
|
@@ -36379,18 +37806,19 @@ function Root({ globals }) {
|
|
|
36379
37806
|
[session]
|
|
36380
37807
|
);
|
|
36381
37808
|
if (!session) {
|
|
36382
|
-
return /* @__PURE__ */ (0,
|
|
37809
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Login, { onSubmit: submit, onQuit: exit, error, verifying, notice });
|
|
36383
37810
|
}
|
|
36384
37811
|
return (
|
|
36385
37812
|
// Keyed on the token so a re-login remounts: the previous session's instances,
|
|
36386
37813
|
// balance and error state must not bleed into the new account's dashboard.
|
|
36387
|
-
/* @__PURE__ */ (0,
|
|
37814
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
36388
37815
|
App2,
|
|
36389
37816
|
{
|
|
36390
37817
|
client: session.client,
|
|
36391
37818
|
token: session.token,
|
|
36392
37819
|
tokenSource: session.source,
|
|
36393
|
-
onLogout: logout
|
|
37820
|
+
onLogout: logout,
|
|
37821
|
+
baseUrl: session.baseUrl
|
|
36394
37822
|
},
|
|
36395
37823
|
session.token
|
|
36396
37824
|
)
|
|
@@ -36403,24 +37831,29 @@ async function runTui(globals = {}) {
|
|
|
36403
37831
|
const previous = { json: isJson(), verbose: isVerbose() };
|
|
36404
37832
|
configureOutput({ quiet: true });
|
|
36405
37833
|
let restored = false;
|
|
37834
|
+
let app;
|
|
36406
37835
|
const restore = () => {
|
|
36407
37836
|
if (restored) return;
|
|
36408
37837
|
restored = true;
|
|
36409
37838
|
process.stdout.write(LEAVE_ALT_SCREEN);
|
|
36410
37839
|
configureOutput({ quiet: false, json: previous.json, verbose: previous.verbose });
|
|
36411
37840
|
};
|
|
37841
|
+
const stop = () => {
|
|
37842
|
+
app?.unmount();
|
|
37843
|
+
restore();
|
|
37844
|
+
};
|
|
36412
37845
|
process.once("exit", restore);
|
|
36413
|
-
process.once("SIGINT",
|
|
36414
|
-
process.once("SIGTERM",
|
|
37846
|
+
process.once("SIGINT", stop);
|
|
37847
|
+
process.once("SIGTERM", stop);
|
|
36415
37848
|
process.stdout.write(ENTER_ALT_SCREEN + CLEAR);
|
|
36416
37849
|
try {
|
|
36417
|
-
|
|
37850
|
+
app = render_default(/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Root, { globals }), { exitOnCtrlC: false });
|
|
36418
37851
|
await app.waitUntilExit();
|
|
36419
37852
|
} finally {
|
|
36420
37853
|
restore();
|
|
36421
37854
|
process.off("exit", restore);
|
|
36422
|
-
process.off("SIGINT",
|
|
36423
|
-
process.off("SIGTERM",
|
|
37855
|
+
process.off("SIGINT", stop);
|
|
37856
|
+
process.off("SIGTERM", stop);
|
|
36424
37857
|
}
|
|
36425
37858
|
}
|
|
36426
37859
|
export {
|
|
@@ -36540,4 +37973,4 @@ react/cjs/react-jsx-runtime.development.js:
|
|
|
36540
37973
|
* LICENSE file in the root directory of this source tree.
|
|
36541
37974
|
*)
|
|
36542
37975
|
*/
|
|
36543
|
-
//# sourceMappingURL=app-
|
|
37976
|
+
//# sourceMappingURL=app-V5GCG3MC.js.map
|