@cloud411716/fancy-webnovel 1.0.39 → 1.0.41
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/commands/bootstrap/index.js +11 -16
- package/commands/scan/index.js +17 -28
- package/index.js +2 -2
- package/infra.js +9 -6
- package/package.json +1 -1
|
@@ -103,22 +103,17 @@ export function apply(ctx) {
|
|
|
103
103
|
}
|
|
104
104
|
|
|
105
105
|
// ---------- confirm ----------
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
signal,
|
|
118
|
-
});
|
|
119
|
-
} catch {
|
|
120
|
-
return notify(session, 'error', bootstrap.notify({ type: 'cancelled' }));
|
|
121
|
-
}
|
|
106
|
+
const confirm = await ctx.userQuestions.ask({
|
|
107
|
+
questions: [{
|
|
108
|
+
id: 'confirm',
|
|
109
|
+
question: bootstrap.notify({ type: 'confirm', projectRoot }),
|
|
110
|
+
detail: projectRoot,
|
|
111
|
+
hideCustomInput: true,
|
|
112
|
+
options: bootstrap.confirmOptions(),
|
|
113
|
+
}],
|
|
114
|
+
agent: invocation.agent,
|
|
115
|
+
signal,
|
|
116
|
+
});
|
|
122
117
|
const ans = confirm.answers[0];
|
|
123
118
|
const chosen = ans?.selected?.[0] ?? ans?.custom;
|
|
124
119
|
if (chosen !== '确认创建') {
|
package/commands/scan/index.js
CHANGED
|
@@ -52,7 +52,6 @@ const scan = {
|
|
|
52
52
|
return {
|
|
53
53
|
id: 'rank',
|
|
54
54
|
question: `${pLabel} 有多个榜单,支持多选。请选择要采集的榜单:`,
|
|
55
|
-
detail: opts.map(o => o.label).join('、'),
|
|
56
55
|
hideCustomInput: true,
|
|
57
56
|
multiSelect: true,
|
|
58
57
|
options: opts,
|
|
@@ -134,20 +133,15 @@ export function apply(ctx) {
|
|
|
134
133
|
}
|
|
135
134
|
|
|
136
135
|
// ---------- platform selection ----------
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
signal,
|
|
147
|
-
});
|
|
148
|
-
} catch {
|
|
149
|
-
return notify(session, 'error', scan.notify({ type: 'cancelled' }));
|
|
150
|
-
}
|
|
136
|
+
const platformResult = await ctx.userQuestions.ask({
|
|
137
|
+
questions: [{
|
|
138
|
+
id: 'platform',
|
|
139
|
+
...scan.askPlatform(),
|
|
140
|
+
question: `${scan.platformList()}\n\n请选择要扫的平台(输入编号 1-4):`,
|
|
141
|
+
}],
|
|
142
|
+
agent: invocation.agent,
|
|
143
|
+
signal,
|
|
144
|
+
});
|
|
151
145
|
const answer = platformResult.answers[0]?.custom?.trim();
|
|
152
146
|
if (!answer) {
|
|
153
147
|
return notify(session, 'error', scan.notify({ type: 'cancelled' }));
|
|
@@ -160,16 +154,11 @@ export function apply(ctx) {
|
|
|
160
154
|
const platform = row[1];
|
|
161
155
|
|
|
162
156
|
// ---------- rank selection (multi-select) ----------
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
signal,
|
|
169
|
-
});
|
|
170
|
-
} catch {
|
|
171
|
-
return notify(session, 'error', scan.notify({ type: 'cancelled' }));
|
|
172
|
-
}
|
|
157
|
+
const rankResult = await ctx.userQuestions.ask({
|
|
158
|
+
questions: [scan.askRankList(platform)],
|
|
159
|
+
agent: invocation.agent,
|
|
160
|
+
signal,
|
|
161
|
+
});
|
|
173
162
|
const selected = rankResult.answers[0]?.selected ?? [];
|
|
174
163
|
const custom = rankResult.answers[0]?.custom?.trim();
|
|
175
164
|
|
|
@@ -213,12 +202,12 @@ export function apply(ctx) {
|
|
|
213
202
|
const statusLine = new StatusLine(session);
|
|
214
203
|
let currentRankLabel = '';
|
|
215
204
|
|
|
216
|
-
disposers.push(ctx.events.on('fancy/scan:start', (_ctx,
|
|
205
|
+
disposers.push(ctx.events.on('fancy/scan:start', (_ctx, platform, _channel, _type, label) => {
|
|
217
206
|
currentRankLabel = label;
|
|
218
|
-
statusLine.update(`[${SPINNER[_spinnerIdx++ % 4]}] 正在采集:${platformLabel(
|
|
207
|
+
statusLine.update(`[${SPINNER[_spinnerIdx++ % 4]}] 正在采集:${platformLabel(platform)} ${label} …`);
|
|
219
208
|
}));
|
|
220
209
|
|
|
221
|
-
disposers.push(ctx.events.on('fancy/scan:rank-done', (_ctx,
|
|
210
|
+
disposers.push(ctx.events.on('fancy/scan:rank-done', (_ctx, _platform, _channel, _type, ok, written) => {
|
|
222
211
|
statusLine.update(`[${SPINNER[_spinnerIdx++ % 4]}] ${currentRankLabel} ${ok ? `✓ 写入 ${written} 条` : '✗ 失败'}`);
|
|
223
212
|
}));
|
|
224
213
|
|
package/index.js
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* - File operations use Node.js fs (project roots may be outside workspace).
|
|
13
13
|
* - ctx.timer (via ctx.timeout()) handles all delays/timeouts.
|
|
14
14
|
*
|
|
15
|
-
* Required Cordis services: commands, userQuestions, timer
|
|
15
|
+
* Required Cordis services: commands, userQuestions, timer
|
|
16
16
|
* (all are part of dsh-base, so this plugin works on dsh-tui, dsh-web, dsh-desktop).
|
|
17
17
|
*
|
|
18
18
|
* IMPORTANT: This plugin needs `danger-full-access` sandbox mode because it
|
|
@@ -27,7 +27,7 @@ import { apply as applyScan } from './commands/scan/index.js';
|
|
|
27
27
|
* Services this plugin requires from the Cordis context.
|
|
28
28
|
* All are provided by dsh-base, so this works on every DSH UI.
|
|
29
29
|
*/
|
|
30
|
-
export const inject = ['commands', 'userQuestions', 'timer'
|
|
30
|
+
export const inject = ['commands', 'userQuestions', 'timer'];
|
|
31
31
|
|
|
32
32
|
/**
|
|
33
33
|
* Called once when the plugin is loaded into a Cordis context (fiber).
|
package/infra.js
CHANGED
|
@@ -12,8 +12,9 @@
|
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
// --------------------------------------------------------------------------
|
|
15
|
-
// notify — return error
|
|
15
|
+
// notify — return error result propagated through dsh-commands settleThrown()
|
|
16
16
|
// --------------------------------------------------------------------------
|
|
17
|
+
//
|
|
17
18
|
|
|
18
19
|
/** Strip ANSI escape sequences from a string (defensive, prevents TTY leak). */
|
|
19
20
|
function stripAnsi(str) {
|
|
@@ -25,7 +26,7 @@ function stripAnsi(str) {
|
|
|
25
26
|
* @param {'error'|'success'} kind
|
|
26
27
|
* @param {string} text
|
|
27
28
|
* @returns {{ kind: 'error'|'success', text: string }} Result propagated through
|
|
28
|
-
* dsh-commands
|
|
29
|
+
* dsh-commands settleThrown() → command/done → channel.notify() (TUI toast)
|
|
29
30
|
* and command/done (Web left-panel with real commandId prefix)
|
|
30
31
|
*/
|
|
31
32
|
export function notify(session, kind, text) {
|
|
@@ -121,18 +122,18 @@ export function scanProgress(ctx, phase, data) {
|
|
|
121
122
|
switch (phase) {
|
|
122
123
|
case 'start':
|
|
123
124
|
ctx.events.emit('fancy/scan:start', data.platform, data.channel, data.type, data.label);
|
|
124
|
-
break
|
|
125
|
+
break
|
|
125
126
|
case 'book':
|
|
126
127
|
ctx.events.emit('fancy/scan:book', data.platform, data.channel, data.type,
|
|
127
128
|
data.index, data.total, data.title, data.rank);
|
|
128
|
-
break
|
|
129
|
+
break
|
|
129
130
|
case 'rank-done':
|
|
130
131
|
ctx.events.emit('fancy/scan:rank-done', data.platform, data.channel, data.type,
|
|
131
132
|
data.ok, data.written, data.failed, data.errorMsg);
|
|
132
|
-
break
|
|
133
|
+
break
|
|
133
134
|
case 'done':
|
|
134
135
|
ctx.events.emit('fancy/scan:done', data.platform, data.totalBooks, data.totalFiles, data.ok);
|
|
135
|
-
break
|
|
136
|
+
break
|
|
136
137
|
}
|
|
137
138
|
}
|
|
138
139
|
|
|
@@ -155,3 +156,5 @@ export async function writeFile(filepath, content, encoding = 'utf-8') {
|
|
|
155
156
|
mkdirSync(dirname(filepath), { recursive: true });
|
|
156
157
|
writeFileSync(filepath, content, encoding);
|
|
157
158
|
}
|
|
159
|
+
|
|
160
|
+
|