更新功能实现

This commit is contained in:
yinsx
2025-12-22 09:43:46 +08:00
parent 29a7a1e626
commit dd99e932b4
8 changed files with 78 additions and 68 deletions

View File

@ -23,10 +23,15 @@ export async function gridSelect(options) {
cols = 3,
colWidth = 24,
title = "",
renderHeader = null
renderHeader = null,
updateInfo = null,
headerGap = 2, // header后的空行数
menuGap = 2, // 菜单和提示文字的间隔
rowGap = 1 // 每行菜单后的空行数
} = options;
let current = 0;
let onUpdate = updateInfo ? true : false; // 如果有更新,默认选中更新按钮
let resolved = false;
const rows = Math.ceil(items.length / cols);
const termWidth = process.stdout.columns || 80;
@ -37,19 +42,18 @@ export async function gridSelect(options) {
clearScreen();
if (renderHeader) {
console.log(renderHeader());
console.log(renderHeader(onUpdate));
}
console.log("");
for (let i = 0; i < headerGap; i++) console.log("");
if (title) {
const titlePad = " ".repeat(Math.max(0, Math.floor((termWidth - title.length - 4) / 2)));
console.log(titlePad + color.bgMagenta(color.white(` ${title} `)));
}
console.log("");
console.log(pad + color.dim("↑ ↓ ← → 选择 | Enter 确认 | Esc 退出"));
console.log("\n");
for (let i = 0; i < menuGap; i++) console.log("");
for (let row = 0; row < rows; row++) {
let line = "";
@ -59,7 +63,7 @@ export async function gridSelect(options) {
const idx = row * cols + col;
if (idx < items.length) {
const item = items[idx];
if (idx === current) {
if (!onUpdate && idx === current) {
line += color.cyan("[" + item.name + "]");
} else {
line += " " + item.name + " ";
@ -71,7 +75,7 @@ export async function gridSelect(options) {
console.log(pad + line);
console.log(pad + color.dim(descLine));
console.log("\n");
for (let i = 0; i < rowGap; i++) console.log("");
}
}
@ -87,21 +91,35 @@ export async function gridSelect(options) {
switch (key.name) {
case "up":
if (row > 0) { current -= cols; render(); }
if (onUpdate) {
// 已在更新按钮,不能再上
} else if (row === 0 && updateInfo) {
onUpdate = true; render();
} else if (row > 0) {
current -= cols; render();
}
break;
case "down":
if (row < rows - 1 && current + cols < items.length) { current += cols; render(); }
if (onUpdate) {
onUpdate = false; render();
} else if (row < rows - 1 && current + cols < items.length) {
current += cols; render();
}
break;
case "left":
if (col > 0) { current--; render(); }
if (!onUpdate && col > 0) { current--; render(); }
break;
case "right":
if (col < cols - 1 && current < items.length - 1) { current++; render(); }
if (!onUpdate && col < cols - 1 && current < items.length - 1) { current++; render(); }
break;
case "return":
resolved = true;
stopKeypress();
setImmediate(() => resolve(items[current]));
if (onUpdate) {
setImmediate(() => resolve({ isUpdate: true }));
} else {
setImmediate(() => resolve(items[current]));
}
break;
case "escape":
resolved = true;