mirror of
https://github.com/fofolee/uTools-quickcommand.git
synced 2025-06-08 22:51:25 +08:00
改用browserwindows实现systemdialog,和现有弹窗UI统一参数格式
This commit is contained in:
parent
272cf488a3
commit
1b1c79deb5
192
plugin/lib/dialog/controller.js
Normal file
192
plugin/lib/dialog/controller.js
Normal file
@ -0,0 +1,192 @@
|
|||||||
|
const { ipcRenderer } = require("electron");
|
||||||
|
|
||||||
|
// 等待 DOM 加载完成
|
||||||
|
document.addEventListener("DOMContentLoaded", () => {
|
||||||
|
let parentId = null;
|
||||||
|
let dialogType = null;
|
||||||
|
|
||||||
|
// 监听父窗口发来的对话框配置
|
||||||
|
ipcRenderer.on("dialog-config", (event, config) => {
|
||||||
|
parentId = event.senderId;
|
||||||
|
dialogType = config.type;
|
||||||
|
|
||||||
|
// 设置主题
|
||||||
|
document.documentElement.setAttribute(
|
||||||
|
"data-theme",
|
||||||
|
config.isDark ? "dark" : "light"
|
||||||
|
);
|
||||||
|
|
||||||
|
// 设置对话框标题
|
||||||
|
document.getElementById("title-text").textContent = config.title || "提示";
|
||||||
|
|
||||||
|
// 设置对话框内容
|
||||||
|
if (config.content) {
|
||||||
|
document.getElementById("content").textContent = config.content;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据类型设置不同的对话框内容
|
||||||
|
switch (config.type) {
|
||||||
|
case "message":
|
||||||
|
document.body.classList.add("dialog-message"); // 添加消息对话框的类
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "input":
|
||||||
|
document.getElementById("input").style.display = "block";
|
||||||
|
document.body.classList.add("dialog-input");
|
||||||
|
// 创建输入框
|
||||||
|
const inputContainer = document.getElementById("input-container");
|
||||||
|
inputContainer.innerHTML = ""; // 清空现有内容
|
||||||
|
config.inputOptions.forEach((inputOption, index) => {
|
||||||
|
console.log(inputOption);
|
||||||
|
const div = document.createElement("div");
|
||||||
|
div.className = "input-group";
|
||||||
|
|
||||||
|
const label = document.createElement("label");
|
||||||
|
label.textContent =
|
||||||
|
typeof inputOption === "string" ? inputOption : inputOption.label;
|
||||||
|
|
||||||
|
const input = document.createElement("input");
|
||||||
|
input.type = "text";
|
||||||
|
input.id = `input-${index}`;
|
||||||
|
if (typeof inputOption !== "string") {
|
||||||
|
input.value = inputOption.value || "";
|
||||||
|
input.placeholder = inputOption.hint || "";
|
||||||
|
}
|
||||||
|
|
||||||
|
div.appendChild(label);
|
||||||
|
div.appendChild(input);
|
||||||
|
inputContainer.appendChild(div);
|
||||||
|
});
|
||||||
|
document.getElementById("input-0").focus();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "confirm":
|
||||||
|
document.getElementById("confirm").style.display = "block";
|
||||||
|
document.body.classList.add("dialog-confirm");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "buttons":
|
||||||
|
document.getElementById("buttons").style.display = "block";
|
||||||
|
document.body.classList.add("dialog-buttons");
|
||||||
|
// 创建按钮
|
||||||
|
const buttonContainer = document.getElementById("button-container");
|
||||||
|
buttonContainer.innerHTML = "";
|
||||||
|
config.buttons.forEach((btn, index) => {
|
||||||
|
const button = document.createElement("button");
|
||||||
|
button.textContent = btn;
|
||||||
|
button.onclick = () => {
|
||||||
|
ipcRenderer.sendTo(parentId, "dialog-result", {
|
||||||
|
id: index,
|
||||||
|
text: btn,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
buttonContainer.appendChild(button);
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "textarea":
|
||||||
|
document.getElementById("textarea").style.display = "block";
|
||||||
|
document.body.classList.add("dialog-textarea");
|
||||||
|
const textarea = document.getElementById("text-content");
|
||||||
|
if (config.placeholder) {
|
||||||
|
textarea.placeholder = config.placeholder;
|
||||||
|
}
|
||||||
|
if (config.defaultText) {
|
||||||
|
textarea.value = config.defaultText;
|
||||||
|
}
|
||||||
|
textarea.focus();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ipcRenderer.sendTo(parentId, "dialog-ready", calculateHeight());
|
||||||
|
});
|
||||||
|
|
||||||
|
const calculateHeight = () => {
|
||||||
|
const titleBar = document.querySelector(".title-bar");
|
||||||
|
const buttonBar = document.querySelector(".button-bar");
|
||||||
|
const contentWrapper = document.querySelector(".content-wrapper");
|
||||||
|
|
||||||
|
// 计算总高度
|
||||||
|
const totalHeight =
|
||||||
|
titleBar.offsetHeight +
|
||||||
|
contentWrapper.scrollHeight +
|
||||||
|
(buttonBar.style.display !== "none" ? buttonBar.offsetHeight : 0);
|
||||||
|
|
||||||
|
// 确保高度在最小值和最大值之间
|
||||||
|
return Math.min(Math.max(totalHeight, 100), 520);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 确定按钮点击事件
|
||||||
|
document.getElementById("ok-btn").onclick = () => {
|
||||||
|
let result;
|
||||||
|
|
||||||
|
switch (dialogType) {
|
||||||
|
case "message":
|
||||||
|
result = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "input":
|
||||||
|
const inputs = document.querySelectorAll("#input-container input");
|
||||||
|
result = Array.from(inputs).map((input) => input.value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "confirm":
|
||||||
|
result = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "textarea":
|
||||||
|
result = document.getElementById("text-content").value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ipcRenderer.sendTo(parentId, "dialog-result", result);
|
||||||
|
};
|
||||||
|
|
||||||
|
const cancelDialog = () => {
|
||||||
|
let result;
|
||||||
|
switch (dialogType) {
|
||||||
|
case "input":
|
||||||
|
result = [];
|
||||||
|
break;
|
||||||
|
case "textarea":
|
||||||
|
result = "";
|
||||||
|
break;
|
||||||
|
case "confirm":
|
||||||
|
result = false;
|
||||||
|
break;
|
||||||
|
case "buttons":
|
||||||
|
result = {};
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
result = null;
|
||||||
|
}
|
||||||
|
ipcRenderer.sendTo(parentId, "dialog-result", result);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 取消按钮点击事件
|
||||||
|
document.getElementById("cancel-btn").onclick = () => {
|
||||||
|
cancelDialog();
|
||||||
|
};
|
||||||
|
|
||||||
|
// ESC键关闭窗口
|
||||||
|
document.addEventListener("keydown", (e) => {
|
||||||
|
if (e.key === "Escape") {
|
||||||
|
cancelDialog();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 回车键确认
|
||||||
|
document.addEventListener("keydown", (e) => {
|
||||||
|
// 如果是文本区域且按下回车,不触发确认
|
||||||
|
if (e.key === "Enter") {
|
||||||
|
if (dialogType === "textarea" && !e.ctrlKey) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
document.getElementById("ok-btn").click();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 关闭按钮点击事件
|
||||||
|
document.querySelector(".close-btn").onclick = () => {
|
||||||
|
cancelDialog();
|
||||||
|
};
|
||||||
|
});
|
163
plugin/lib/dialog/service.js
Normal file
163
plugin/lib/dialog/service.js
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
const { ipcRenderer } = require("electron");
|
||||||
|
const { createBrowserWindow } = utools;
|
||||||
|
/**
|
||||||
|
* 创建对话框窗口
|
||||||
|
* @param {object} config - 对话框配置
|
||||||
|
* @returns {Promise} 返回对话框结果
|
||||||
|
*/
|
||||||
|
const createDialog = (config) => {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
const dialogPath = "lib/dialog/view.html";
|
||||||
|
const preloadPath = "lib/dialog/controller.js";
|
||||||
|
|
||||||
|
const dialogOptions = {
|
||||||
|
title: config.title || "对话框",
|
||||||
|
width: 470,
|
||||||
|
height: 80,
|
||||||
|
resizable: false,
|
||||||
|
minimizable: false,
|
||||||
|
maximizable: false,
|
||||||
|
fullscreenable: false,
|
||||||
|
skipTaskbar: true,
|
||||||
|
alwaysOnTop: true,
|
||||||
|
frame: false,
|
||||||
|
webPreferences: {
|
||||||
|
preload: preloadPath,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// 创建窗口
|
||||||
|
const UBrowser = createBrowserWindow(dialogPath, dialogOptions, () => {
|
||||||
|
const dialogResultHandler = (event, result) => {
|
||||||
|
resolve(result);
|
||||||
|
// 移除监听器
|
||||||
|
ipcRenderer.removeListener("dialog-result", dialogResultHandler);
|
||||||
|
UBrowser.destroy();
|
||||||
|
};
|
||||||
|
|
||||||
|
const dialogReadyHandler = (event, height) => {
|
||||||
|
// 获取当前窗口位置
|
||||||
|
const bounds = UBrowser.getBounds();
|
||||||
|
// 调整y坐标,保持窗口中心点不变
|
||||||
|
const y = Math.round(bounds.y - (height - bounds.height) / 2);
|
||||||
|
// 确保坐标和尺寸都是有效的整数
|
||||||
|
const newBounds = {
|
||||||
|
x: Math.round(bounds.x),
|
||||||
|
y: Math.max(0, y), // 确保不会超出屏幕顶部
|
||||||
|
width: 470,
|
||||||
|
height: Math.round(height),
|
||||||
|
};
|
||||||
|
// 设置新的位置和大小
|
||||||
|
UBrowser.setBounds(newBounds);
|
||||||
|
ipcRenderer.removeListener("dialog-ready", dialogReadyHandler);
|
||||||
|
};
|
||||||
|
ipcRenderer.on("dialog-ready", dialogReadyHandler);
|
||||||
|
|
||||||
|
// 添加监听器
|
||||||
|
ipcRenderer.on("dialog-result", dialogResultHandler);
|
||||||
|
|
||||||
|
// 发送配置到子窗口
|
||||||
|
ipcRenderer.sendTo(UBrowser.webContents.id, "dialog-config", {
|
||||||
|
...config,
|
||||||
|
isDark: utools.isDarkColors(),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 显示一个系统级消息框
|
||||||
|
* @param {string} content - 消息内容
|
||||||
|
* @param {string} [title] - 标题,默认为空
|
||||||
|
* @returns {Promise<void>} Promise
|
||||||
|
*/
|
||||||
|
const showSystemMessageBox = async (content, title = "") => {
|
||||||
|
await createDialog({
|
||||||
|
type: "message",
|
||||||
|
title,
|
||||||
|
content,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 显示一个系统级输入框组对话框
|
||||||
|
* @param {string[]|{label:string,value:string,hint:string}[]} options - 输入框配置,可以是标签数组或者带属性的对象数组
|
||||||
|
* @param {string} [title] - 标题,默认为空
|
||||||
|
* @returns {Promise<string[]|null>} 输入的内容数组
|
||||||
|
*/
|
||||||
|
const showSystemInputBox = async (options, title = "") => {
|
||||||
|
// 确保 options 是数组
|
||||||
|
const optionsArray = Array.isArray(options) ? options : [options];
|
||||||
|
|
||||||
|
// 转换每个选项为正确的格式
|
||||||
|
const inputOptions = optionsArray.map((opt) => {
|
||||||
|
if (typeof opt === "string") {
|
||||||
|
return opt;
|
||||||
|
}
|
||||||
|
if (typeof opt === "object" && opt.label) {
|
||||||
|
return {
|
||||||
|
label: opt.label,
|
||||||
|
value: opt.value || "",
|
||||||
|
hint: opt.hint || "",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
throw new Error("输入框配置格式错误");
|
||||||
|
});
|
||||||
|
|
||||||
|
return await createDialog({
|
||||||
|
type: "input",
|
||||||
|
title,
|
||||||
|
inputOptions,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 显示一个系统级确认框,返回是否点击了确认
|
||||||
|
* @param {string} content - 确认内容
|
||||||
|
* @param {string} [title] - 标题,默认为空
|
||||||
|
* @returns {Promise<boolean>} 是否确认
|
||||||
|
*/
|
||||||
|
const showSystemConfirmBox = async (content, title = "") => {
|
||||||
|
const result = await createDialog({
|
||||||
|
type: "confirm",
|
||||||
|
title,
|
||||||
|
content,
|
||||||
|
});
|
||||||
|
return !!result;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 显示一个系统级按钮组对话框,返回点击的按钮的索引和文本
|
||||||
|
* @param {string[]} buttons - 按钮文本数组
|
||||||
|
* @param {string} [title] - 标题,默认为空
|
||||||
|
* @returns {Promise<{id: number, text: string}|null>} 选择的按钮信息
|
||||||
|
*/
|
||||||
|
const showSystemButtonBox = async (buttons, title = "") => {
|
||||||
|
return await createDialog({
|
||||||
|
type: "buttons",
|
||||||
|
title,
|
||||||
|
buttons: Array.isArray(buttons) ? buttons : [buttons],
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 显示一个系统级多行文本输入框
|
||||||
|
* @param {string} [placeholder] - 输入框的提示文本
|
||||||
|
* @param {string} [defaultText] - 输入框的默认文本,默认为空
|
||||||
|
* @returns {Promise<string|null>} 编辑后的文本
|
||||||
|
*/
|
||||||
|
const showSystemTextArea = async (placeholder = "请输入", defaultText = "") => {
|
||||||
|
return await createDialog({
|
||||||
|
type: "textarea",
|
||||||
|
placeholder,
|
||||||
|
defaultText,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
showSystemMessageBox,
|
||||||
|
showSystemInputBox,
|
||||||
|
showSystemConfirmBox,
|
||||||
|
showSystemButtonBox,
|
||||||
|
showSystemTextArea,
|
||||||
|
};
|
344
plugin/lib/dialog/view.html
Normal file
344
plugin/lib/dialog/view.html
Normal file
@ -0,0 +1,344 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<title>对话框</title>
|
||||||
|
<style>
|
||||||
|
:root {
|
||||||
|
--bg-color: #fff;
|
||||||
|
--text-color: #333;
|
||||||
|
--border-color: #ddd;
|
||||||
|
--title-bg: #f5f5f5;
|
||||||
|
--input-bg: #fff;
|
||||||
|
--input-border: #ddd;
|
||||||
|
--input-focus: #0d6efd;
|
||||||
|
--button-bg: #0d6efd;
|
||||||
|
--button-hover: #0b5ed7;
|
||||||
|
--button-text: #fff;
|
||||||
|
--cancel-bg: #6c757d;
|
||||||
|
--cancel-border: #6c757d;
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="dark"] {
|
||||||
|
--bg-color: #282727;
|
||||||
|
--text-color: #e0e0e0;
|
||||||
|
--border-color: #404040;
|
||||||
|
--title-bg: #2d2d2d;
|
||||||
|
--input-bg: #2d2d2d;
|
||||||
|
--input-border: #404040;
|
||||||
|
--input-focus: #0d6efd;
|
||||||
|
--button-bg: #0d6efd;
|
||||||
|
--button-hover: #0b5ed7;
|
||||||
|
--button-text: #fff;
|
||||||
|
--cancel-bg: #4a4a4a;
|
||||||
|
--cancel-border: #4a4a4a;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
|
||||||
|
"Helvetica Neue", Arial, sans-serif;
|
||||||
|
background: var(--bg-color);
|
||||||
|
color: var(--text-color);
|
||||||
|
user-select: none;
|
||||||
|
height: 100vh;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 标题栏样式 */
|
||||||
|
.title-bar {
|
||||||
|
background: var(--title-bg);
|
||||||
|
border-bottom: 1px solid var(--border-color);
|
||||||
|
padding: 4px 12px;
|
||||||
|
-webkit-app-region: drag;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title-left {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
margin-right: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title-text {
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 500;
|
||||||
|
color: var(--text-color);
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.close-btn {
|
||||||
|
-webkit-app-region: no-drag;
|
||||||
|
background-color: rgba(0, 0, 0, 0.05);
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
min-width: 16px;
|
||||||
|
min-height: 16px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
border-radius: 50%;
|
||||||
|
cursor: pointer;
|
||||||
|
opacity: 0.8;
|
||||||
|
transition: all 0.2s;
|
||||||
|
margin-left: 8px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-theme="dark"] .close-btn {
|
||||||
|
background-color: rgba(255, 255, 255, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.close-btn:hover {
|
||||||
|
opacity: 1;
|
||||||
|
background-color: #ff4d4d;
|
||||||
|
}
|
||||||
|
|
||||||
|
.close-btn::before,
|
||||||
|
.close-btn::after {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
width: 8px;
|
||||||
|
height: 1px;
|
||||||
|
background-color: var(--text-color);
|
||||||
|
transform-origin: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.close-btn::before {
|
||||||
|
transform: rotate(45deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.close-btn::after {
|
||||||
|
transform: rotate(-45deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.close-btn:hover::before,
|
||||||
|
.close-btn:hover::after {
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-wrapper {
|
||||||
|
padding: 16px;
|
||||||
|
min-height: 60px;
|
||||||
|
max-height: 449px;
|
||||||
|
overflow-y: auto;
|
||||||
|
overflow-x: hidden;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#content {
|
||||||
|
line-height: 1.4;
|
||||||
|
font-size: 13px;
|
||||||
|
user-select: text;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-bar {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 0 16px 16px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
background: var(--bg-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
padding: 4px 12px;
|
||||||
|
border-radius: 4px;
|
||||||
|
border: 1px solid var(--button-bg);
|
||||||
|
background: linear-gradient(
|
||||||
|
180deg,
|
||||||
|
rgba(255, 255, 255, 0.08) 0%,
|
||||||
|
rgba(0, 0, 0, 0.05) 100%
|
||||||
|
),
|
||||||
|
var(--button-bg);
|
||||||
|
color: var(--button-text);
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 13px;
|
||||||
|
min-width: 70px;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
button:hover {
|
||||||
|
background: linear-gradient(
|
||||||
|
180deg,
|
||||||
|
rgba(255, 255, 255, 0.1) 0%,
|
||||||
|
rgba(0, 0, 0, 0.05) 100%
|
||||||
|
),
|
||||||
|
var(--button-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
button:active {
|
||||||
|
background: linear-gradient(
|
||||||
|
180deg,
|
||||||
|
rgba(0, 0, 0, 0.05) 0%,
|
||||||
|
rgba(255, 255, 255, 0.08) 100%
|
||||||
|
),
|
||||||
|
var(--button-bg);
|
||||||
|
box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ok-btn {
|
||||||
|
padding: 0 12px;
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cancel-btn {
|
||||||
|
padding: 0 12px;
|
||||||
|
background: linear-gradient(
|
||||||
|
180deg,
|
||||||
|
rgba(255, 255, 255, 0.08) 0%,
|
||||||
|
rgba(0, 0, 0, 0.05) 100%
|
||||||
|
),
|
||||||
|
var(--cancel-bg);
|
||||||
|
border: 1px solid var(--cancel-border);
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cancel-btn:hover {
|
||||||
|
background: linear-gradient(
|
||||||
|
180deg,
|
||||||
|
rgba(255, 255, 255, 0.1) 0%,
|
||||||
|
rgba(0, 0, 0, 0.05) 100%
|
||||||
|
),
|
||||||
|
var(--cancel-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
#input-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-group label {
|
||||||
|
display: block;
|
||||||
|
padding: 0 0 4px 2px;
|
||||||
|
color: var(--text-color);
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-group input {
|
||||||
|
width: 100%;
|
||||||
|
padding: 6px 8px;
|
||||||
|
border: 1px solid var(--input-border);
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 13px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
background: var(--input-bg);
|
||||||
|
color: var(--text-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-group input:focus {
|
||||||
|
border-color: var(--input-focus);
|
||||||
|
outline: none;
|
||||||
|
box-shadow: 0 0 0 2px rgba(13, 110, 253, 0.25);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 文本区域样式 */
|
||||||
|
textarea {
|
||||||
|
width: 100%;
|
||||||
|
height: 400px;
|
||||||
|
padding: 6px 8px;
|
||||||
|
border: 1px solid var(--input-border);
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 13px;
|
||||||
|
resize: none;
|
||||||
|
box-sizing: border-box;
|
||||||
|
background: var(--input-bg);
|
||||||
|
color: var(--text-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea:focus {
|
||||||
|
border-color: var(--input-focus);
|
||||||
|
outline: none;
|
||||||
|
box-shadow: 0 0 0 2px rgba(13, 110, 253, 0.25);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 按钮组样式 */
|
||||||
|
#button-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 10px;
|
||||||
|
padding-top: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#button-container button {
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
padding: 6px 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 根据对话框类型显示/隐藏取消按钮 */
|
||||||
|
.dialog-message #cancel-btn {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog-buttons .button-bar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 隐藏所有对话框内容 */
|
||||||
|
#input,
|
||||||
|
#confirm,
|
||||||
|
#buttons,
|
||||||
|
#textarea {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<!-- 标题栏 -->
|
||||||
|
<div class="title-bar">
|
||||||
|
<div class="title-left">
|
||||||
|
<img src="../../logo.png" alt="logo" class="logo" />
|
||||||
|
<h1 class="title-text" id="title-text">对话框</h1>
|
||||||
|
</div>
|
||||||
|
<div class="close-btn"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="content-wrapper">
|
||||||
|
<div id="content"></div>
|
||||||
|
|
||||||
|
<!-- 输入对话框 -->
|
||||||
|
<div id="input">
|
||||||
|
<div id="input-container"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 确认对话框 -->
|
||||||
|
<div id="confirm"></div>
|
||||||
|
|
||||||
|
<!-- 按钮选择对话框 -->
|
||||||
|
<div id="buttons">
|
||||||
|
<div id="button-container"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 文本区域对话框 -->
|
||||||
|
<div id="textarea">
|
||||||
|
<textarea id="text-content"></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="button-bar">
|
||||||
|
<button id="cancel-btn">取消</button>
|
||||||
|
<button id="ok-btn">确定</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -6,7 +6,7 @@ const iconv = require("iconv-lite");
|
|||||||
const path = require("path");
|
const path = require("path");
|
||||||
const axios = require("axios");
|
const axios = require("axios");
|
||||||
|
|
||||||
const systemDialog = require("./systemDialog");
|
const systemDialog = require("./dialog/service");
|
||||||
|
|
||||||
const { getQuickcommandTempFile } = require("./getQuickcommandFile");
|
const { getQuickcommandTempFile } = require("./getQuickcommandFile");
|
||||||
|
|
||||||
@ -178,60 +178,7 @@ const quickcommand = {
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
|
...systemDialog,
|
||||||
// 运行C#脚本
|
|
||||||
runCsharp: function (script, args = []) {
|
|
||||||
return new Promise((reslove, reject) => {
|
|
||||||
let cscPath = path.join(
|
|
||||||
process.env.WINDIR,
|
|
||||||
"Microsoft.NET",
|
|
||||||
"Framework",
|
|
||||||
"v4.0.30319",
|
|
||||||
"csc.exe"
|
|
||||||
);
|
|
||||||
if (!fs.existsSync(cscPath)) {
|
|
||||||
cscPath = path.join(
|
|
||||||
process.env.WINDIR,
|
|
||||||
"Microsoft.NET",
|
|
||||||
"Framework",
|
|
||||||
"v3.5",
|
|
||||||
"csc.exe"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (!fs.existsSync(cscPath)) {
|
|
||||||
return reject("未安装.NET Framework");
|
|
||||||
}
|
|
||||||
let tempCsharpFile = getQuickcommandTempFile("cs");
|
|
||||||
let tempBuildFile = getQuickcommandTempFile("exe");
|
|
||||||
|
|
||||||
fs.writeFile(tempCsharpFile, iconv.encode(script, "gbk"), (err) => {
|
|
||||||
if (err) return reject(err.toString());
|
|
||||||
// 添加命令行参数
|
|
||||||
const argsStr =
|
|
||||||
args.length > 0
|
|
||||||
? " " +
|
|
||||||
args
|
|
||||||
.map((arg) =>
|
|
||||||
arg.startsWith("-") ? arg : `"${arg}"`
|
|
||||||
)
|
|
||||||
.join(" ")
|
|
||||||
: "";
|
|
||||||
child_process.exec(
|
|
||||||
`${cscPath} /nologo /out:${tempBuildFile} ${tempCsharpFile} && ${tempBuildFile}${argsStr}`,
|
|
||||||
{
|
|
||||||
encoding: "buffer",
|
|
||||||
windowsHide: true,
|
|
||||||
},
|
|
||||||
(err, stdout) => {
|
|
||||||
if (err) reject(iconv.decode(stdout, "gbk"));
|
|
||||||
else reslove(iconv.decode(stdout, "gbk"));
|
|
||||||
fs.unlink(tempCsharpFile, () => {});
|
|
||||||
fs.unlink(tempBuildFile, () => {});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (process.platform === "win32") {
|
if (process.platform === "win32") {
|
||||||
@ -272,8 +219,6 @@ if (process.platform === "win32") {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
quickcommand.showSystemTextArea = systemDialog.showSystemTextArea;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (process.platform === "darwin") {
|
if (process.platform === "darwin") {
|
||||||
@ -316,11 +261,6 @@ if (process.platform !== "linux") {
|
|||||||
let command = createTerminalCommand(cmdline, options);
|
let command = createTerminalCommand(cmdline, options);
|
||||||
child_process.exec(command);
|
child_process.exec(command);
|
||||||
};
|
};
|
||||||
// 系统级弹窗
|
|
||||||
quickcommand.showSystemMessageBox = systemDialog.showSystemMessageBox;
|
|
||||||
quickcommand.showSystemInputBox = systemDialog.showSystemInputBox;
|
|
||||||
quickcommand.showSystemConfirmBox = systemDialog.showSystemConfirmBox;
|
|
||||||
quickcommand.showSystemButtonBox = systemDialog.showSystemButtonBox;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = quickcommand;
|
module.exports = quickcommand;
|
||||||
|
@ -1,303 +0,0 @@
|
|||||||
const fs = require("fs");
|
|
||||||
const path = require("path");
|
|
||||||
const { exec } = require("child_process");
|
|
||||||
const { getQuickcommandFolderFile } = require("./getQuickcommandFile");
|
|
||||||
const { runCsharpFeature } = require("./csharp");
|
|
||||||
|
|
||||||
// 辅助函数
|
|
||||||
const execCommand = (cmd) => {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
exec(cmd, (error, stdout, stderr) => {
|
|
||||||
if (error) {
|
|
||||||
reject(stderr);
|
|
||||||
} else {
|
|
||||||
resolve(stdout);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const checkZenity = async () => {
|
|
||||||
try {
|
|
||||||
await execCommand("which zenity");
|
|
||||||
return true;
|
|
||||||
} catch (error) {
|
|
||||||
window.utools.showNotification(
|
|
||||||
"请先安装 zenity:\nsudo apt install zenity 或\nsudo yum install zenity 或\nsudo pacman -S zenity"
|
|
||||||
);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const getQuickcommandIconPath = () => {
|
|
||||||
try {
|
|
||||||
const iconPath = getQuickcommandFolderFile("logo", "png");
|
|
||||||
if (!fs.existsSync(iconPath)) {
|
|
||||||
const sourcePath = path.join(__dirname, "..", "logo.png");
|
|
||||||
if (!fs.existsSync(sourcePath)) {
|
|
||||||
console.error("Source icon not found:", sourcePath);
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
fs.copyFileSync(sourcePath, iconPath);
|
|
||||||
}
|
|
||||||
return iconPath;
|
|
||||||
} catch (error) {
|
|
||||||
console.error("Error getting icon path:", error);
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 修改对话框函数,使用新的 dialog.cs
|
|
||||||
const showSystemMessageBox = async function (content, title = "提示") {
|
|
||||||
try {
|
|
||||||
const iconPath = getQuickcommandIconPath();
|
|
||||||
if (window.utools.isWindows()) {
|
|
||||||
const args = [
|
|
||||||
"-type",
|
|
||||||
"message",
|
|
||||||
"-title",
|
|
||||||
title,
|
|
||||||
"-content",
|
|
||||||
content.replace(/\r\n|\n/g, ""),
|
|
||||||
];
|
|
||||||
|
|
||||||
if (iconPath) {
|
|
||||||
args.push("-iconpath", iconPath.replace(/\\/g, "\\\\"));
|
|
||||||
}
|
|
||||||
|
|
||||||
const result = await runCsharpFeature("dialog", args);
|
|
||||||
if (result && result.startsWith("Error:")) {
|
|
||||||
throw new Error(result.substring(7));
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (window.utools.isMacOs()) {
|
|
||||||
let iconParam = "note";
|
|
||||||
if (iconPath) {
|
|
||||||
const posixPath = iconPath.replace(/\\/g, "/");
|
|
||||||
iconParam = `alias POSIX file "${posixPath}"`;
|
|
||||||
}
|
|
||||||
const script = `display dialog "${content}" with title "${title}" buttons {"确定"} default button "确定" with icon ${iconParam}`;
|
|
||||||
await this.runAppleScript(script);
|
|
||||||
return true;
|
|
||||||
} else if (window.utools.isLinux()) {
|
|
||||||
if (!(await checkZenity())) return false;
|
|
||||||
try {
|
|
||||||
const script = `zenity --info --title="${title}" --text="${content}" --width=400`;
|
|
||||||
await execCommand(script);
|
|
||||||
return true;
|
|
||||||
} catch (error) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error("Dialog error:", error);
|
|
||||||
window.utools.showNotification(`对话框错误: ${error.message}`);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const showSystemInputBox = async function (placeholders, title = "请输入") {
|
|
||||||
if (!Array.isArray(placeholders)) {
|
|
||||||
placeholders = [placeholders];
|
|
||||||
}
|
|
||||||
|
|
||||||
const iconPath = getQuickcommandIconPath();
|
|
||||||
if (window.utools.isMacOs()) {
|
|
||||||
let iconParam = "note";
|
|
||||||
if (iconPath) {
|
|
||||||
const posixPath = iconPath.replace(/\\/g, "/");
|
|
||||||
iconParam = `alias POSIX file "${posixPath}"`;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
const results = [];
|
|
||||||
for (let i = 0; i < placeholders.length; i++) {
|
|
||||||
const isLast = i === placeholders.length - 1;
|
|
||||||
const buttons = isLast ? '{"取消", "确定"}' : '{"取消", "继续"}';
|
|
||||||
const defaultButton = isLast ? '"确定"' : '"继续"';
|
|
||||||
const script = `display dialog "${placeholders[i]}" with title "${title}" default answer "" buttons ${buttons} default button ${defaultButton} with icon ${iconParam}`;
|
|
||||||
const result = await this.runAppleScript(script);
|
|
||||||
const buttonClicked = isLast ? "确定" : "继续";
|
|
||||||
if (!result.includes(`button returned:${buttonClicked}`)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
const text = result.match(/text returned:(.+)/)[1];
|
|
||||||
results.push(text);
|
|
||||||
}
|
|
||||||
return results;
|
|
||||||
} catch (err) {
|
|
||||||
console.error(err);
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
} else if (window.utools.isWindows()) {
|
|
||||||
const args = [
|
|
||||||
"-type",
|
|
||||||
"input",
|
|
||||||
"-title",
|
|
||||||
title,
|
|
||||||
"-content",
|
|
||||||
placeholders.join("|||||"),
|
|
||||||
];
|
|
||||||
|
|
||||||
if (iconPath) {
|
|
||||||
args.push("-iconpath", iconPath.replace(/\\/g, "\\\\"));
|
|
||||||
}
|
|
||||||
|
|
||||||
const result = await runCsharpFeature("dialog", args);
|
|
||||||
return result ? JSON.parse(result) : [];
|
|
||||||
} else if (window.utools.isLinux()) {
|
|
||||||
if (!(await checkZenity())) return null;
|
|
||||||
const results = [];
|
|
||||||
for (let i = 0; i < placeholders.length; i++) {
|
|
||||||
try {
|
|
||||||
const script = `zenity --entry --title="${title}" --text="${placeholders[i]}" --width=400`;
|
|
||||||
const result = await execCommand(script);
|
|
||||||
if (!result) return [];
|
|
||||||
results.push(result.trim());
|
|
||||||
} catch (error) {
|
|
||||||
console.error("执行 zenity 命令失败:", error);
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const showSystemConfirmBox = async function (content, title = "请确认") {
|
|
||||||
const iconPath = getQuickcommandIconPath();
|
|
||||||
if (window.utools.isMacOs()) {
|
|
||||||
let iconParam = "note";
|
|
||||||
if (iconPath) {
|
|
||||||
const posixPath = iconPath.replace(/\\/g, "/");
|
|
||||||
iconParam = `alias POSIX file "${posixPath}"`;
|
|
||||||
}
|
|
||||||
const script = `display dialog "${content}" with title "${title}" buttons {"取消", "确定"} default button "确定" with icon ${iconParam}`;
|
|
||||||
try {
|
|
||||||
const result = await this.runAppleScript(script);
|
|
||||||
return result.includes("button returned:确定");
|
|
||||||
} catch (err) {
|
|
||||||
console.error(err);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else if (window.utools.isWindows()) {
|
|
||||||
const args = [
|
|
||||||
"-type",
|
|
||||||
"confirm",
|
|
||||||
"-title",
|
|
||||||
title,
|
|
||||||
"-content",
|
|
||||||
content.replace(/\r\n|\n/g, "\\n"),
|
|
||||||
];
|
|
||||||
|
|
||||||
if (iconPath) {
|
|
||||||
args.push("-iconpath", iconPath.replace(/\\/g, "\\\\"));
|
|
||||||
}
|
|
||||||
|
|
||||||
const result = await runCsharpFeature("dialog", args);
|
|
||||||
return result === "true";
|
|
||||||
} else if (window.utools.isLinux()) {
|
|
||||||
if (!(await checkZenity())) return false;
|
|
||||||
try {
|
|
||||||
const script = `zenity --question --title="${title}" --text="${content}" --width=400`;
|
|
||||||
await execCommand(script);
|
|
||||||
return true;
|
|
||||||
} catch (error) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const showSystemButtonBox = async function (buttons, title = "请选择") {
|
|
||||||
const iconPath = getQuickcommandIconPath();
|
|
||||||
if (window.utools.isMacOs()) {
|
|
||||||
const itemList = buttons.map((item) => `"${item}"`).join(", ");
|
|
||||||
const script = `choose from list {${itemList}} with title "${title}" default items {"${buttons[0]}"}`;
|
|
||||||
try {
|
|
||||||
const result = await this.runAppleScript(script);
|
|
||||||
if (result.includes("false")) return {};
|
|
||||||
const text = result.trim();
|
|
||||||
const id = buttons.findIndex((item) => item === text);
|
|
||||||
return { id, text };
|
|
||||||
} catch (err) {
|
|
||||||
console.error(err);
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
} else if (window.utools.isWindows()) {
|
|
||||||
const args = [
|
|
||||||
"-type",
|
|
||||||
"buttons",
|
|
||||||
"-title",
|
|
||||||
title,
|
|
||||||
"-content",
|
|
||||||
buttons.join("|||||"),
|
|
||||||
];
|
|
||||||
|
|
||||||
if (iconPath) {
|
|
||||||
args.push("-iconpath", iconPath.replace(/\\/g, "\\\\"));
|
|
||||||
}
|
|
||||||
|
|
||||||
const result = await runCsharpFeature("dialog", args);
|
|
||||||
if (result) {
|
|
||||||
return JSON.parse(result);
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
} else if (window.utools.isLinux()) {
|
|
||||||
if (!(await checkZenity())) return null;
|
|
||||||
try {
|
|
||||||
const script1 = `zenity --info --title="${title}" --width=400`;
|
|
||||||
await execCommand(script1);
|
|
||||||
|
|
||||||
const itemsList = buttons
|
|
||||||
.map((btn, index) => `"${index}" "${btn}"`)
|
|
||||||
.join(" ");
|
|
||||||
const script2 = `zenity --list --title="${title}" --column="序号" --column="选项" ${itemsList} --width=400 --height=300`;
|
|
||||||
const result = await execCommand(script2);
|
|
||||||
if (!result) return {};
|
|
||||||
const text = result.trim();
|
|
||||||
const id = buttons.findIndex((btn) => btn === text);
|
|
||||||
return { id, text };
|
|
||||||
} catch (error) {
|
|
||||||
console.error("执行 zenity 命令失败:", error);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const showSystemTextArea = async function (defaultText = "", title = "请输入") {
|
|
||||||
const iconPath = getQuickcommandIconPath();
|
|
||||||
if (window.utools.isWindows()) {
|
|
||||||
const args = [
|
|
||||||
"-type",
|
|
||||||
"textarea",
|
|
||||||
"-title",
|
|
||||||
title,
|
|
||||||
"-content",
|
|
||||||
defaultText,
|
|
||||||
];
|
|
||||||
|
|
||||||
if (iconPath) {
|
|
||||||
args.push("-iconpath", iconPath.replace(/\\/g, "\\\\"));
|
|
||||||
}
|
|
||||||
|
|
||||||
const result = await runCsharpFeature("dialog", args);
|
|
||||||
return result || null;
|
|
||||||
} else if (window.utools.isLinux()) {
|
|
||||||
if (!(await checkZenity())) return null;
|
|
||||||
try {
|
|
||||||
const script = `zenity --text-info --title="${title}" --editable --width=450 --height=350 --filename=<(echo "${defaultText}")`;
|
|
||||||
const result = await execCommand(script);
|
|
||||||
return result ? result.trim() : null;
|
|
||||||
} catch (error) {
|
|
||||||
console.error("执行 zenity 命令失败:", error);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
showSystemMessageBox,
|
|
||||||
showSystemInputBox,
|
|
||||||
showSystemConfirmBox,
|
|
||||||
showSystemButtonBox,
|
|
||||||
showSystemTextArea,
|
|
||||||
};
|
|
@ -258,50 +258,37 @@ export const uiCommands = {
|
|||||||
isAsync: true,
|
isAsync: true,
|
||||||
outputVariable: "[inputValue1]",
|
outputVariable: "[inputValue1]",
|
||||||
saveOutput: true,
|
saveOutput: true,
|
||||||
|
config: [
|
||||||
|
{
|
||||||
|
label: "输入框",
|
||||||
|
component: "ArrayEditor",
|
||||||
|
width: 12,
|
||||||
|
columns: {
|
||||||
|
label: {
|
||||||
|
label: "标签",
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
label: "默认值",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
defaultValue: [
|
||||||
|
{
|
||||||
|
label: newVarInputVal("str", "请输入"),
|
||||||
|
value: newVarInputVal("str"),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
subCommands: [
|
subCommands: [
|
||||||
{
|
{
|
||||||
value: "quickcommand.showInputBox",
|
value: "quickcommand.showInputBox",
|
||||||
icon: "call_to_action",
|
icon: "call_to_action",
|
||||||
label: "插件内弹窗",
|
label: "插件内弹窗",
|
||||||
config: [
|
|
||||||
{
|
|
||||||
label: "输入框",
|
|
||||||
component: "ArrayEditor",
|
|
||||||
width: 12,
|
|
||||||
columns: {
|
|
||||||
label: {
|
|
||||||
label: "标签",
|
|
||||||
},
|
|
||||||
value: {
|
|
||||||
label: "默认值",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
defaultValue: [
|
|
||||||
{
|
|
||||||
label: newVarInputVal("str", "请输入"),
|
|
||||||
value: newVarInputVal("str"),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: "quickcommand.showSystemInputBox",
|
value: "quickcommand.showSystemInputBox",
|
||||||
icon: "report",
|
icon: "report",
|
||||||
label: "系统弹窗",
|
label: "系统弹窗",
|
||||||
config: [
|
|
||||||
{
|
|
||||||
label: "提示信息",
|
|
||||||
component: "ArrayEditor",
|
|
||||||
width: 12,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "标题",
|
|
||||||
component: "VariableInput",
|
|
||||||
defaultValue: newVarInputVal("str", "请输入"),
|
|
||||||
width: 12,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@ -317,44 +304,30 @@ export const uiCommands = {
|
|||||||
isAsync: true,
|
isAsync: true,
|
||||||
outputVariable: "textareaValue",
|
outputVariable: "textareaValue",
|
||||||
saveOutput: true,
|
saveOutput: true,
|
||||||
|
config: [
|
||||||
|
{
|
||||||
|
label: "文本框占位符",
|
||||||
|
component: "VariableInput",
|
||||||
|
defaultValue: newVarInputVal("str", "请输入"),
|
||||||
|
width: 6,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "文本框默认值",
|
||||||
|
component: "VariableInput",
|
||||||
|
defaultValue: newVarInputVal("str"),
|
||||||
|
width: 6,
|
||||||
|
},
|
||||||
|
],
|
||||||
subCommands: [
|
subCommands: [
|
||||||
{
|
{
|
||||||
value: "quickcommand.showTextArea",
|
value: "quickcommand.showTextArea",
|
||||||
icon: "call_to_action",
|
icon: "call_to_action",
|
||||||
label: "插件内弹窗",
|
label: "插件内弹窗",
|
||||||
config: [
|
|
||||||
{
|
|
||||||
label: "文本框占位符",
|
|
||||||
component: "VariableInput",
|
|
||||||
defaultValue: newVarInputVal("str", "请输入"),
|
|
||||||
width: 6,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "文本框默认值",
|
|
||||||
component: "VariableInput",
|
|
||||||
defaultValue: newVarInputVal("str"),
|
|
||||||
width: 6,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: "quickcommand.showSystemTextArea",
|
value: "quickcommand.showSystemTextArea",
|
||||||
icon: "report",
|
icon: "report",
|
||||||
label: "系统弹窗(Mac不支持)",
|
label: "系统弹窗",
|
||||||
config: [
|
|
||||||
{
|
|
||||||
label: "文本框默认值",
|
|
||||||
component: "VariableInput",
|
|
||||||
defaultValue: newVarInputVal("str"),
|
|
||||||
width: 6,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "标题",
|
|
||||||
component: "VariableInput",
|
|
||||||
defaultValue: newVarInputVal("str", "请输入"),
|
|
||||||
width: 6,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
44
src/plugins/monaco/types/quickcommand.api.d.ts
vendored
44
src/plugins/monaco/types/quickcommand.api.d.ts
vendored
@ -131,9 +131,9 @@ interface quickcommandApi {
|
|||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
* @param placeholder 文本框占位符
|
* @param placeholder 文本框占位符
|
||||||
* @param value 默认的文本值
|
* @param defaultText 默认的文本值
|
||||||
*/
|
*/
|
||||||
showTextArea(placeholder?: string, value?: string): Promise<string>;
|
showTextArea(placeholder?: string, defaultText?: string): Promise<string>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 显示一个自动消失的提示框
|
* 显示一个自动消失的提示框
|
||||||
@ -483,7 +483,7 @@ interface quickcommandApi {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 显示一个系统级消息框(不支持Linux)
|
* 显示一个系统级消息框
|
||||||
*
|
*
|
||||||
* ```js
|
* ```js
|
||||||
* quickcommand.showSystemMessageBox("这是一条消息", "标题")
|
* quickcommand.showSystemMessageBox("这是一条消息", "标题")
|
||||||
@ -495,30 +495,33 @@ interface quickcommandApi {
|
|||||||
showSystemMessageBox(content: string, title?: string): Promise<void>;
|
showSystemMessageBox(content: string, title?: string): Promise<void>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 显示一个系统级输入框组,返回所有输入框的值(不支持Linux)
|
* 显示一个系统级输入框组对话框,返回所有输入框的值
|
||||||
*
|
*
|
||||||
* ```js
|
* ```js
|
||||||
* // 单个输入框
|
* // 简单数组形式
|
||||||
* quickcommand.showSystemInputBox("请输入:", "标题").then(results => {
|
* quickcommand.showSystemInputBox(["姓名", "年龄", "地址"], "个人信息").then(values => {
|
||||||
* console.log(results[0]) // 第一个输入框的值
|
* console.log(values) // ["张三", "25", "北京"]
|
||||||
* })
|
* })
|
||||||
*
|
*
|
||||||
* // 多个输入框
|
* // 对象数组形式
|
||||||
* quickcommand.showSystemInputBox(["姓名:", "年龄:", "地址:"], "个人信息").then(results => {
|
* quickcommand.showSystemInputBox([
|
||||||
* console.log(results) // ["张三", "25", "北京"]
|
* { label: "姓名", value: "张三", hint: "请输入姓名" },
|
||||||
|
* { label: "年龄", value: "25", hint: "请输入年龄" }
|
||||||
|
* ], "个人信息").then(values => {
|
||||||
|
* console.log(values) // ["张三", "25"]
|
||||||
* })
|
* })
|
||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
* @param placeholders 输入框的提示文本,可以是单个字符串或字符串数组
|
* @param options 输入框配置,可以是标签数组或者带属性的对象数组
|
||||||
* @param title 标题,默认为空
|
* @param title 标题,默认为空
|
||||||
*/
|
*/
|
||||||
showSystemInputBox(
|
showSystemInputBox(
|
||||||
placeholders: string | string[],
|
options: string[] | { label: string; value?: string; hint?: string }[],
|
||||||
title?: string
|
title?: string
|
||||||
): Promise<string[] | null>;
|
): Promise<string[] | null>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 显示一个系统级确认框,返回是否点击了确认(不支持Linux)
|
* 显示一个系统级确认框,返回是否点击了确认
|
||||||
*
|
*
|
||||||
* ```js
|
* ```js
|
||||||
* quickcommand.showSystemConfirmBox("确定要删除吗?", "确认删除").then(confirmed => {
|
* quickcommand.showSystemConfirmBox("确定要删除吗?", "确认删除").then(confirmed => {
|
||||||
@ -533,9 +536,8 @@ interface quickcommandApi {
|
|||||||
*/
|
*/
|
||||||
showSystemConfirmBox(content: string, title?: string): Promise<boolean>;
|
showSystemConfirmBox(content: string, title?: string): Promise<boolean>;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 显示一个系统级按钮组对话框,返回点击的按钮的索引和文本(不支持Linux)
|
* 显示一个系统级按钮组对话框,返回点击的按钮的索引和文本
|
||||||
*
|
*
|
||||||
* ```js
|
* ```js
|
||||||
* quickcommand.showSystemButtonBox(["保存", "不保存", "取消"], "保存确认").then(result => {
|
* quickcommand.showSystemButtonBox(["保存", "不保存", "取消"], "保存确认").then(result => {
|
||||||
@ -554,22 +556,22 @@ interface quickcommandApi {
|
|||||||
): Promise<{ id: number; text: string } | null>;
|
): Promise<{ id: number; text: string } | null>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 显示一个系统级多行文本输入框(仅Windows支持)
|
* 显示一个系统级多行文本输入框
|
||||||
*
|
*
|
||||||
* ```js
|
* ```js
|
||||||
* quickcommand.showSystemTextArea("默认内容", "文本编辑").then(text => {
|
* quickcommand.showSystemTextArea("请输入内容", "").then(text => {
|
||||||
* if (text) {
|
* if (text) {
|
||||||
* console.log("输入的文本:", text)
|
* console.log("输入的文本:", text)
|
||||||
* }
|
* }
|
||||||
* })
|
* })
|
||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
* @param defaultText 默认文本,默认为空
|
* @param placeholder 输入框的提示文本,默认为空
|
||||||
* @param title 标题,默认为空
|
* @param defaultText 输入框的默认文本,默认为空
|
||||||
*/
|
*/
|
||||||
showSystemTextArea(
|
showSystemTextArea(
|
||||||
defaultText?: string,
|
placeholder?: string,
|
||||||
title?: string
|
defaultText?: string
|
||||||
): Promise<string | null>;
|
): Promise<string | null>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user