新增quickcommand.showLoadingBar,支持显示加载条

This commit is contained in:
fofolee
2025-02-17 22:38:19 +08:00
parent d7508c36a7
commit 3eca3b448e
14 changed files with 339 additions and 84 deletions

View File

@@ -361,12 +361,19 @@ document.addEventListener("DOMContentLoaded", () => {
case "process":
document.getElementById("process").style.display = "block";
document.body.classList.add("dialog-process");
// 创建进度条
const processBarInner = document.getElementById("process-bar-inner");
if (config.isLoading) {
// 如果是加载条模式,使用动画效果
processBarInner.className = "process-bar-loading";
} else {
// 如果是进度条模式,设置初始进度
processBarInner.className = "process-bar-inner";
processBarInner.style.width = `${config.value}%`;
}
// 设置初始文本和进度
// 设置初始文本
document.getElementById("process-text").textContent = config.text;
document.getElementById(
"process-bar-inner"
).style.width = `${config.value}%`;
// 如果需要显示暂停按钮
if (config.showPause) {
@@ -393,8 +400,13 @@ document.addEventListener("DOMContentLoaded", () => {
// 监听进度条更新事件
ipcRenderer.on("update-process", (event, data) => {
const { value, text } = data;
if (typeof value === "number") {
document.getElementById("process-bar-inner").style.width = `${value}%`;
const processBarInner = document.getElementById("process-bar-inner");
if (
processBarInner &&
processBarInner.className === "process-bar-inner" &&
typeof value === "number"
) {
processBarInner.style.width = `${value}%`;
}
if (text) {
document.getElementById("process-text").textContent = text;

View File

@@ -1,6 +1,25 @@
const { ipcRenderer } = require("electron");
const os = require("os");
const { createBrowserWindow } = utools;
const dialogPath = "lib/dialog/view.html";
const preloadPath = "lib/dialog/controller.js";
const commonBrowserWindowOptions = {
resizable: false,
minimizable: false,
maximizable: false,
fullscreenable: false,
skipTaskbar: true,
alwaysOnTop: true,
frame: false,
movable: true,
webPreferences: {
preload: preloadPath,
devTools: utools.isDev(),
},
};
/**
* 创建对话框窗口
* @param {object} config - 对话框配置
@@ -9,9 +28,6 @@ const { createBrowserWindow } = utools;
*/
const createDialog = (config, customDialogOptions = {}) => {
return new Promise((resolve) => {
const dialogPath = "lib/dialog/view.html";
const preloadPath = "lib/dialog/controller.js";
// linux 和 win32 都使用 win32 的样式
const platform = os.platform() === "darwin" ? "darwin" : "win32";
@@ -26,18 +42,8 @@ const createDialog = (config, customDialogOptions = {}) => {
title: config.title || "对话框",
width: dialogWidth,
height: 80,
resizable: false,
minimizable: false,
maximizable: false,
fullscreenable: false,
skipTaskbar: true,
alwaysOnTop: true,
frame: false,
opacity: 0,
webPreferences: {
preload: preloadPath,
devTools: utools.isDev(),
},
...commonBrowserWindowOptions,
...customDialogOptions, // 合并自定义选项
};
@@ -309,7 +315,6 @@ let lastProcessBar = null;
*/
const showProcessBar = async (options = {}) => {
const {
title = "进度",
text = "处理中...",
value = 0,
position = "bottom-right",
@@ -335,26 +340,15 @@ const showProcessBar = async (options = {}) => {
return new Promise((resolve) => {
const UBrowser = createBrowserWindow(
"lib/dialog/view.html",
dialogPath,
{
title,
width: windowWidth,
height: windowHeight,
x,
y,
resizable: false,
minimizable: false,
maximizable: false,
fullscreenable: false,
skipTaskbar: true,
alwaysOnTop: true,
frame: false,
opacity: 0,
movable: true,
webPreferences: {
preload: "lib/dialog/controller.js",
devTools: utools.isDev(),
},
focusable: false,
...commonBrowserWindowOptions,
},
() => {
const windowId = UBrowser.webContents.id;
@@ -362,7 +356,6 @@ const showProcessBar = async (options = {}) => {
// 发送配置到子窗口
ipcRenderer.sendTo(windowId, "dialog-config", {
type: "process",
title,
text,
value,
isDark: utools.isDarkColors(),
@@ -443,10 +436,103 @@ const updateProcessBar = (options = {}, processBar = null) => {
ipcRenderer.sendTo(processBar.id, "update-process", { value, text });
if (complete) {
processBar.close();
setTimeout(() => {
processBar.close();
}, 600);
}
};
let lastLoadingBar = null;
/**
* 显示一个加载条对话框
* @param {object} options - 配置选项
* @param {string} [options.text="加载中..."] - 加载条上方的文本
* @param {string} [options.position="bottom-right"] - 加载条位置可选值top-left, top-right, bottom-left, bottom-right
* @param {Function} [options.onClose] - 关闭按钮点击时的回调函数
* @returns {Promise<{id: number, close: Function}>} 返回加载条窗口ID和关闭函数
*/
const showLoadingBar = async (options = {}) => {
const { text = "加载中...", position = "bottom-right", onClose } = options;
const windowWidth = 250;
const windowHeight = 60;
// 计算窗口位置
const { x, y } = calculateWindowPosition({
position,
width: windowWidth,
height: windowHeight,
});
return new Promise((resolve) => {
const UBrowser = createBrowserWindow(
dialogPath,
{
width: windowWidth,
height: windowHeight,
x,
y,
opacity: 0,
focusable: false,
...commonBrowserWindowOptions,
},
() => {
const windowId = UBrowser.webContents.id;
// 发送配置到子窗口
ipcRenderer.sendTo(windowId, "dialog-config", {
type: "process",
text,
value: 0,
isDark: utools.isDarkColors(),
platform: process.platform,
isLoading: true, // 标记为加载条模式
});
// 监听窗口准备就绪
ipcRenderer.once("dialog-ready", () => {
UBrowser.setOpacity(1);
});
// 监听对话框结果
ipcRenderer.once("dialog-result", (event, result) => {
if (result === "close" && typeof onClose === "function") {
onClose();
}
UBrowser.destroy();
});
const loadingBar = {
id: windowId,
close: () => {
if (typeof onClose === "function") {
onClose();
}
lastLoadingBar = null;
UBrowser.destroy();
},
};
lastLoadingBar = loadingBar;
// 返回窗口ID和关闭函数
resolve(loadingBar);
}
);
});
};
const closeLoadingBar = (loadingBar) => {
if (!loadingBar) {
if (!lastLoadingBar) {
throw new Error("没有找到已创建的加载条");
}
loadingBar = lastLoadingBar;
}
loadingBar.close();
};
module.exports = {
showSystemMessageBox,
showSystemInputBox,
@@ -457,4 +543,6 @@ module.exports = {
showSystemWaitButton,
showProcessBar,
updateProcessBar,
showLoadingBar,
closeLoadingBar,
};

View File

@@ -614,6 +614,7 @@ textarea:focus {
background: rgba(255, 255, 255, 0.3);
border-radius: 2px;
overflow: hidden;
position: relative;
}
.process-bar-inner {
@@ -624,6 +625,25 @@ textarea:focus {
transition: width 0.3s ease;
}
@keyframes loading-bar-animation {
0% {
left: -80px;
}
100% {
left: calc(100% + 80px);
}
}
.process-bar-loading {
position: absolute;
width: 80px;
height: 100%;
background: white;
border-radius: 2px;
animation: loading-bar-animation 3s infinite linear;
}
/* 进度条按钮容器 */
.process-buttons {
position: absolute;

View File

@@ -60,7 +60,7 @@
</div>
<div class="process-text" id="process-text"></div>
<div class="process-bar">
<div class="process-bar-inner" id="process-bar-inner"></div>
<div id="process-bar-inner"></div>
</div>
</div>
</div>