添加pin的雏形

This commit is contained in:
fofolee
2025-04-25 07:45:55 +08:00
parent 0d4f49fcf4
commit 6f1c98fb4a
7 changed files with 263 additions and 0 deletions

View File

@@ -0,0 +1,30 @@
const { ipcRenderer } = require("electron");
// 等待 DOM 加载完成
document.addEventListener("DOMContentLoaded", () => {
let parentId = null;
let windowId = null;
let commandCode = null;
// 监听父窗口发来的配置
ipcRenderer.on("window-config", (event, config) => {
parentId = event.senderId;
windowId = config.windowId;
commandCode = config.commandCode;
// 设置主题
document.documentElement.setAttribute(
"data-theme",
config.isDark ? "dark" : "light"
);
// 设置图标
document.getElementById("command-icon").src = config.icon;
});
// 点击图标执行命令
document.querySelector(".pin-container").addEventListener("click", () => {
console.log("click", parentId, `pin-execute-${windowId}`);
ipcRenderer.sendTo(parentId, `pin-execute-${windowId}`, commandCode);
});
});

108
plugin/lib/pin/service.js Normal file
View File

@@ -0,0 +1,108 @@
const { ipcRenderer } = require("electron");
const { createBrowserWindow } = utools;
const pinPath = "lib/pin/view.html";
const preloadPath = "lib/pin/controller.js";
// 存储所有pin窗口的信息
const pinWindows = new Map();
/**
* 创建pin窗口
* @param {object} commandInfo - 命令信息
* @param {object} position - 窗口位置 {x, y}
* @returns {Promise} 返回窗口对象
*/
const createPinWindow = (commandInfo, position = null) => {
return new Promise((resolve) => {
const windowOptions = {
width: 52,
height: 52,
transparent: true,
frame: false,
resizable: false,
skipTaskbar: true,
alwaysOnTop: true,
focusable: false,
movable: true,
webPreferences: {
preload: preloadPath,
devTools: utools.isDev(),
},
};
// 如果指定了位置,添加到选项中
if (position) {
windowOptions.x = position.x;
windowOptions.y = position.y;
}
// 创建窗口
const UBrowser = createBrowserWindow(pinPath, windowOptions, () => {
const windowId = UBrowser.webContents.id;
UBrowser.webContents.openDevTools({
mode: "undocked",
});
// 监听命令执行请求
ipcRenderer.once(`pin-execute-${windowId}`, (event, code) => {
// 执行命令
console.log("execute command", event, code, commandInfo);
});
// 保存窗口信息
pinWindows.set(commandInfo.features.code, {
window: UBrowser,
windowId,
position: UBrowser.getPosition(),
});
// 发送配置到子窗口
ipcRenderer.sendTo(windowId, "window-config", {
isDark: utools.isDarkColors(),
icon: commandInfo.features.icon,
commandCode: commandInfo.features.code,
windowId,
});
resolve(UBrowser);
});
});
};
/**
* 移除pin窗口
* @param {string} commandCode - 命令代码
*/
const removePinWindow = (commandCode) => {
const pinInfo = pinWindows.get(commandCode);
if (pinInfo) {
pinInfo.window.destroy();
pinWindows.delete(commandCode);
}
};
/**
* 获取所有pin窗口信息
* @returns {Map} pin窗口信息Map
*/
const getPinWindows = () => {
return pinWindows;
};
/**
* 恢复所有pin窗口
* @param {Array} pinnedCommands - pin命令列表
*/
const restorePinWindows = async (pinnedCommands) => {
for (const command of pinnedCommands) {
await createPinWindow(command.info, command.position);
}
};
module.exports = {
createPinWindow,
removePinWindow,
getPinWindows,
restorePinWindows,
};

40
plugin/lib/pin/style.css Normal file
View File

@@ -0,0 +1,40 @@
body {
margin: 0;
padding: 0;
background: transparent;
overflow: hidden;
user-select: none;
}
.pin-container {
width: 52px;
height: 52px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
transition: transform 0.3s ease;
}
.pin-container:hover {
transform: scale(1.1);
}
.pin-icon {
width: 45px;
height: 45px;
overflow: hidden;
}
.pin-icon img {
width: 100%;
height: 100%;
object-fit: contain;
}
body[data-theme="dark"] .pin-icon {
background: rgba(57, 57, 57, 0.09);
border: 1px solid rgb(59 58 58 / 5%);
box-shadow: 0 1px 5px rgb(0 0 0 / 20%), 0 2px 2px rgb(0 0 0 / 14%),
0 3px 1px -2px rgb(69 67 67 / 12%);
}

15
plugin/lib/pin/view.html Normal file
View File

@@ -0,0 +1,15 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Pin</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div class="pin-container">
<div class="pin-icon">
<img id="command-icon" src="" alt="command icon" />
</div>
</div>
</body>
</html>