@xynogen/pix-pretty 1.7.2 → 1.7.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/gate-overlay.ts +4 -47
- package/src/progress.ts +14 -19
package/package.json
CHANGED
package/src/gate-overlay.ts
CHANGED
|
@@ -19,7 +19,7 @@ import { frameLines, modalWidth, selectListTheme } from "./modal-frame.js";
|
|
|
19
19
|
|
|
20
20
|
// ── Types ─────────────────────────────────────────────────────────────────────
|
|
21
21
|
|
|
22
|
-
export type OverlayAction = "approved" | "denied" | "timeout";
|
|
22
|
+
export type OverlayAction = "approved" | "denied" | "timeout"; // ponytail: timeout kept for back-compat; never emitted now
|
|
23
23
|
|
|
24
24
|
export interface OverlayResult {
|
|
25
25
|
action: OverlayAction;
|
|
@@ -40,7 +40,7 @@ interface BaseConfig {
|
|
|
40
40
|
title: string;
|
|
41
41
|
/** Optional body lines under the title. */
|
|
42
42
|
body?: string[];
|
|
43
|
-
/**
|
|
43
|
+
/** @deprecated No-op — timeout removed. Dialog waits indefinitely for user input. */
|
|
44
44
|
timeoutMs?: number;
|
|
45
45
|
/**
|
|
46
46
|
* Choices shown in the SelectList.
|
|
@@ -96,10 +96,6 @@ export interface OverlayUI {
|
|
|
96
96
|
|
|
97
97
|
// ── Constants ─────────────────────────────────────────────────────────────────
|
|
98
98
|
|
|
99
|
-
const SECOND_MS = 1_000;
|
|
100
|
-
const COUNTDOWN_WARN_S = 5;
|
|
101
|
-
const DEFAULT_TIMEOUT_MS = 30_000;
|
|
102
|
-
|
|
103
99
|
const DEFAULT_CHOICES: OverlayChoice[] = [
|
|
104
100
|
{ value: "yes", label: "Allow", description: "Proceed" },
|
|
105
101
|
{ value: "no", label: "Deny", description: "Block" },
|
|
@@ -214,17 +210,10 @@ export function showOverlay(
|
|
|
214
210
|
config: OverlayConfig,
|
|
215
211
|
): Promise<OverlayResult> {
|
|
216
212
|
const accent = config.accent ?? "accent";
|
|
217
|
-
const timeoutMs = config.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
218
213
|
const choices = config.choices ?? DEFAULT_CHOICES;
|
|
219
214
|
const approveVal = config.approveValue ?? "yes";
|
|
220
215
|
|
|
221
216
|
return new Promise((resolve) => {
|
|
222
|
-
const controller = new AbortController();
|
|
223
|
-
const timer =
|
|
224
|
-
timeoutMs > 0
|
|
225
|
-
? setTimeout(() => controller.abort(), timeoutMs)
|
|
226
|
-
: undefined;
|
|
227
|
-
|
|
228
217
|
ui.custom<OverlayResult>(
|
|
229
218
|
(tui, theme, _kb, done) => {
|
|
230
219
|
type Stage = "select" | "password";
|
|
@@ -245,35 +234,8 @@ export function showOverlay(
|
|
|
245
234
|
);
|
|
246
235
|
const maskedInput = new MaskedInput();
|
|
247
236
|
|
|
248
|
-
// ── countdown ───────────────────────────────────────────────────
|
|
249
|
-
let ticker: ReturnType<typeof setInterval> | undefined;
|
|
250
|
-
if (timeoutMs > 0) {
|
|
251
|
-
const deadlineMs = Date.now() + timeoutMs;
|
|
252
|
-
const updateCountdown = () => {
|
|
253
|
-
const remaining = Math.max(
|
|
254
|
-
0,
|
|
255
|
-
Math.ceil((deadlineMs - Date.now()) / SECOND_MS),
|
|
256
|
-
);
|
|
257
|
-
countdownLine =
|
|
258
|
-
theme.fg("dim", "Auto-deny in ") +
|
|
259
|
-
theme.fg(
|
|
260
|
-
remaining <= COUNTDOWN_WARN_S ? accent : "muted",
|
|
261
|
-
`${remaining}s`,
|
|
262
|
-
);
|
|
263
|
-
};
|
|
264
|
-
updateCountdown();
|
|
265
|
-
ticker = setInterval(() => {
|
|
266
|
-
updateCountdown();
|
|
267
|
-
tui.requestRender();
|
|
268
|
-
}, SECOND_MS);
|
|
269
|
-
}
|
|
270
|
-
|
|
271
237
|
// ── finish ───────────────────────────────────────────────────────
|
|
272
|
-
const finish = (result: OverlayResult) =>
|
|
273
|
-
if (timer !== undefined) clearTimeout(timer);
|
|
274
|
-
if (ticker !== undefined) clearInterval(ticker);
|
|
275
|
-
done(result);
|
|
276
|
-
};
|
|
238
|
+
const finish = (result: OverlayResult) => done(result);
|
|
277
239
|
|
|
278
240
|
// ── event wiring ─────────────────────────────────────────────────
|
|
279
241
|
selectList.onSelect = (item) => {
|
|
@@ -292,10 +254,6 @@ export function showOverlay(
|
|
|
292
254
|
finish({ action: "approved", password: pw });
|
|
293
255
|
maskedInput.onEscape = () => finish({ action: "denied" });
|
|
294
256
|
|
|
295
|
-
controller.signal.addEventListener("abort", () =>
|
|
296
|
-
finish({ action: "timeout" }),
|
|
297
|
-
);
|
|
298
|
-
|
|
299
257
|
// ── component interface ──────────────────────────────────────────
|
|
300
258
|
return {
|
|
301
259
|
render: (w) => {
|
|
@@ -327,8 +285,7 @@ export function showOverlay(
|
|
|
327
285
|
},
|
|
328
286
|
{ overlay: true },
|
|
329
287
|
).then((result) => {
|
|
330
|
-
|
|
331
|
-
resolve(result ?? { action: "timeout" });
|
|
288
|
+
resolve(result ?? { action: "denied" });
|
|
332
289
|
});
|
|
333
290
|
});
|
|
334
291
|
}
|
package/src/progress.ts
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* p.close(); // releases input, removes overlay
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
|
-
import {
|
|
16
|
+
import { frameLines, modalWidth } from "./modal-frame.js";
|
|
17
17
|
|
|
18
18
|
interface ProgressTheme {
|
|
19
19
|
fg(color: string, text: string): string;
|
|
@@ -66,31 +66,15 @@ export function openProgress(
|
|
|
66
66
|
ui.custom<void>(
|
|
67
67
|
(tui, theme, _kb, done) => {
|
|
68
68
|
let frame = 0;
|
|
69
|
-
const titleText = new Text(theme.fg(accent, theme.bold(title)), 1, 0);
|
|
70
|
-
const statusText = new Text("", 1, 0);
|
|
71
|
-
|
|
72
|
-
const render = () => {
|
|
73
|
-
statusText.setText(
|
|
74
|
-
`${theme.fg(accent, SPINNER[frame])} ${theme.fg("muted", labelValue)}`,
|
|
75
|
-
);
|
|
76
|
-
};
|
|
77
|
-
|
|
78
69
|
let labelValue = "Working…";
|
|
79
|
-
render();
|
|
80
70
|
|
|
81
71
|
const ticker = setInterval(() => {
|
|
82
72
|
frame = (frame + 1) % SPINNER.length;
|
|
83
|
-
render();
|
|
84
73
|
tui.requestRender();
|
|
85
74
|
}, SPINNER_INTERVAL_MS);
|
|
86
75
|
|
|
87
|
-
const container = new Box(2, 1, (s) => theme.bg("customMessageBg", s));
|
|
88
|
-
container.addChild(titleText);
|
|
89
|
-
container.addChild(statusText);
|
|
90
|
-
|
|
91
76
|
setLabelImpl = (label: string) => {
|
|
92
77
|
labelValue = label;
|
|
93
|
-
render();
|
|
94
78
|
tui.requestRender();
|
|
95
79
|
};
|
|
96
80
|
closeImpl = () => {
|
|
@@ -99,8 +83,19 @@ export function openProgress(
|
|
|
99
83
|
};
|
|
100
84
|
|
|
101
85
|
return {
|
|
102
|
-
render: (w: number) =>
|
|
103
|
-
|
|
86
|
+
render: (w: number) => {
|
|
87
|
+
const mw = modalWidth(w);
|
|
88
|
+
return frameLines({
|
|
89
|
+
width: mw,
|
|
90
|
+
lines: [
|
|
91
|
+
theme.fg(accent, theme.bold(title)),
|
|
92
|
+
`${theme.fg(accent, SPINNER[frame])} ${theme.fg("muted", labelValue)}`,
|
|
93
|
+
],
|
|
94
|
+
color: (s) => theme.fg(accent, s),
|
|
95
|
+
bg: (s) => theme.bg("customMessageBg", s),
|
|
96
|
+
});
|
|
97
|
+
},
|
|
98
|
+
invalidate: () => {},
|
|
104
99
|
// Swallow every keystroke: a focused overlay owns input, so nothing
|
|
105
100
|
// reaches the editor while the update runs.
|
|
106
101
|
handleInput: () => {},
|