mirror of
https://github.com/fofolee/uTools-quickcommand.git
synced 2025-07-05 15:42:43 +08:00
添加pin的雏形
This commit is contained in:
parent
0d4f49fcf4
commit
6f1c98fb4a
30
plugin/lib/pin/controller.js
Normal file
30
plugin/lib/pin/controller.js
Normal 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
108
plugin/lib/pin/service.js
Normal 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
40
plugin/lib/pin/style.css
Normal 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
15
plugin/lib/pin/view.html
Normal 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>
|
@ -20,6 +20,7 @@ const md5 = (input) => {
|
|||||||
|
|
||||||
window.lodashM = require("./lib/lodashMini");
|
window.lodashM = require("./lib/lodashMini");
|
||||||
window.pinyinMatch = require("pinyin-match");
|
window.pinyinMatch = require("pinyin-match");
|
||||||
|
window.pinService = require("./lib/pin/service");
|
||||||
window.DOMPurify = DOMPurify;
|
window.DOMPurify = DOMPurify;
|
||||||
|
|
||||||
const createTerminalCommand = require("./lib/createTerminalCommand");
|
const createTerminalCommand = require("./lib/createTerminalCommand");
|
||||||
|
@ -122,6 +122,10 @@ export default defineComponent({
|
|||||||
window.quickcommandHttpServer().run(this.nativeProfile.serverPort);
|
window.quickcommandHttpServer().run(this.nativeProfile.serverPort);
|
||||||
console.log("Server Start...");
|
console.log("Server Start...");
|
||||||
}
|
}
|
||||||
|
// 恢复固定到桌面的命令
|
||||||
|
if (this.nativeProfile.pinnedCommands) {
|
||||||
|
window.pinService.restorePinWindows(this.nativeProfile.pinnedCommands);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
enterPlugin(enter) {
|
enterPlugin(enter) {
|
||||||
this.updateExp();
|
this.updateExp();
|
||||||
|
@ -4,6 +4,20 @@
|
|||||||
v-ripple
|
v-ripple
|
||||||
:class="{ [`text-${disabledColor}`]: !isActivated, command: 1 }"
|
:class="{ [`text-${disabledColor}`]: !isActivated, command: 1 }"
|
||||||
>
|
>
|
||||||
|
<q-badge floating transparent style="z-index: 1000" v-if="isActivated">
|
||||||
|
<q-btn
|
||||||
|
flat
|
||||||
|
round
|
||||||
|
dense
|
||||||
|
:color="isPinned ? 'amber' : 'grey'"
|
||||||
|
icon="push_pin"
|
||||||
|
@click.stop="togglePin"
|
||||||
|
size="12px"
|
||||||
|
>
|
||||||
|
<q-tooltip>{{ isPinned ? "取消固定到桌面" : "固定到桌面" }}</q-tooltip>
|
||||||
|
</q-btn>
|
||||||
|
</q-badge>
|
||||||
|
|
||||||
<component
|
<component
|
||||||
:is="currentLayout"
|
:is="currentLayout"
|
||||||
:commandInfo="commandInfo"
|
:commandInfo="commandInfo"
|
||||||
@ -56,6 +70,33 @@ export default {
|
|||||||
"--icon-url": `url(${this.commandInfo.features.icon})`,
|
"--icon-url": `url(${this.commandInfo.features.icon})`,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
isPinned() {
|
||||||
|
return (
|
||||||
|
this.$root.nativeProfile.pinnedCommands?.some(
|
||||||
|
(cmd) => cmd.info.features.code === this.commandInfo.features.code
|
||||||
|
) || false
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async togglePin() {
|
||||||
|
if (this.isPinned) {
|
||||||
|
window.pinService.removePinWindow(this.commandInfo.features.code);
|
||||||
|
this.$root.nativeProfile.pinnedCommands =
|
||||||
|
this.$root.nativeProfile.pinnedCommands.filter(
|
||||||
|
(cmd) => cmd.info.features.code !== this.commandInfo.features.code
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
await window.pinService.createPinWindow(this.commandInfo);
|
||||||
|
if (!this.$root.nativeProfile.pinnedCommands) {
|
||||||
|
this.$root.nativeProfile.pinnedCommands = [];
|
||||||
|
}
|
||||||
|
this.$root.nativeProfile.pinnedCommands.push({
|
||||||
|
info: this.commandInfo,
|
||||||
|
position: utools.getCursorScreenPoint(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
@ -80,4 +121,28 @@ export default {
|
|||||||
box-shadow: 0 1px 5px rgb(0 0 0 / 20%), 0 2px 2px rgb(0 0 0 / 14%),
|
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%);
|
0 3px 1px -2px rgb(69 67 67 / 12%);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.pin-icon {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(-5px);
|
||||||
|
visibility: hidden;
|
||||||
|
transition: all 0.35s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
will-change: transform, opacity, visibility;
|
||||||
|
}
|
||||||
|
|
||||||
|
.q-card:hover .pin-icon {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
visibility: visible;
|
||||||
|
backdrop-filter: blur(1px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pin-icon .q-btn {
|
||||||
|
transition: transform 0.35s cubic-bezier(0.68, -0.6, 0.32, 1.6);
|
||||||
|
will-change: transform;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pin-icon .q-btn:hover {
|
||||||
|
transform: scale(1.15);
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user