@becrafter/prompt-manager 0.0.19 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +145 -234
- package/app/desktop/assets/app.1.png +0 -0
- package/app/desktop/assets/app.png +0 -0
- package/app/desktop/assets/icons/icon.icns +0 -0
- package/app/desktop/assets/icons/icon.ico +0 -0
- package/app/desktop/assets/icons/icon.png +0 -0
- package/app/desktop/assets/icons/tray.png +0 -0
- package/app/desktop/assets/tray.1.png +0 -0
- package/app/desktop/assets/tray.png +0 -0
- package/app/desktop/main.js +27 -0
- package/app/desktop/package-lock.json +216 -48
- package/app/desktop/package.json +23 -29
- package/app/desktop/src/services/module-loader.js +43 -22
- package/app/desktop/src/services/runtime-manager.js +172 -23
- package/app/desktop/src/ui/admin-window-manager.js +757 -0
- package/app/desktop/src/ui/splash-manager.js +253 -0
- package/app/desktop/src/ui/tray-manager.js +8 -24
- package/app/desktop/src/utils/icon-manager.js +39 -47
- package/app/desktop/src/utils/resource-paths.js +0 -23
- package/app/desktop/src/utils/resource-sync.js +260 -0
- package/app/desktop/src/utils/runtime-sync.js +241 -0
- package/examples/prompts/recommend/human_3-0_growth_diagnostic_coach_prompt.yaml +105 -0
- package/package.json +16 -13
- package/packages/admin-ui/.babelrc +3 -0
- package/packages/admin-ui/admin.html +237 -4784
- package/packages/admin-ui/css/main.css +2592 -0
- package/packages/admin-ui/css/recommended-prompts.css +610 -0
- package/packages/admin-ui/package-lock.json +6981 -0
- package/packages/admin-ui/package.json +36 -0
- package/packages/admin-ui/src/codemirror.js +53 -0
- package/packages/admin-ui/src/index.js +3188 -0
- package/packages/admin-ui/webpack.config.js +76 -0
- package/packages/resources/tools/chrome-devtools/README.md +310 -0
- package/packages/resources/tools/chrome-devtools/chrome-devtools.tool.js +1703 -0
- package/packages/resources/tools/file-reader/README.md +289 -0
- package/packages/resources/tools/file-reader/file-reader.tool.js +1545 -0
- package/packages/resources/tools/filesystem/README.md +359 -0
- package/packages/resources/tools/filesystem/filesystem.tool.js +514 -160
- package/packages/resources/tools/ollama-remote/README.md +192 -0
- package/packages/resources/tools/ollama-remote/ollama-remote.tool.js +421 -0
- package/packages/resources/tools/pdf-reader/README.md +236 -0
- package/packages/resources/tools/pdf-reader/pdf-reader.tool.js +565 -0
- package/packages/resources/tools/playwright/README.md +306 -0
- package/packages/resources/tools/playwright/playwright.tool.js +1186 -0
- package/packages/resources/tools/todolist/README.md +394 -0
- package/packages/resources/tools/todolist/todolist.tool.js +1312 -0
- package/packages/server/README.md +142 -0
- package/packages/server/api/admin.routes.js +42 -11
- package/packages/server/api/surge.routes.js +43 -0
- package/packages/server/app.js +119 -14
- package/packages/server/index.js +39 -0
- package/packages/server/mcp/mcp.server.js +324 -105
- package/packages/server/mcp/sequential-thinking.handler.js +318 -0
- package/packages/server/mcp/think-plan.handler.js +274 -0
- package/packages/server/middlewares/auth.middleware.js +6 -0
- package/packages/server/package.json +51 -0
- package/packages/server/server.js +37 -1
- package/packages/server/toolm/index.js +9 -0
- package/packages/server/toolm/package-installer.service.js +267 -0
- package/packages/server/toolm/test-tools.js +264 -0
- package/packages/server/toolm/tool-context.service.js +334 -0
- package/packages/server/toolm/tool-dependency.service.js +168 -0
- package/packages/server/toolm/tool-description-generator-optimized.service.js +375 -0
- package/packages/server/toolm/tool-description-generator.service.js +312 -0
- package/packages/server/toolm/tool-environment.service.js +200 -0
- package/packages/server/toolm/tool-execution.service.js +277 -0
- package/packages/server/toolm/tool-loader.service.js +219 -0
- package/packages/server/toolm/tool-logger.service.js +223 -0
- package/packages/server/toolm/tool-manager.handler.js +65 -0
- package/packages/server/toolm/tool-manual-generator.service.js +389 -0
- package/packages/server/toolm/tool-mode-handlers.service.js +224 -0
- package/packages/server/toolm/tool-storage.service.js +111 -0
- package/packages/server/toolm/tool-sync.service.js +138 -0
- package/packages/server/toolm/tool-utils.js +20 -0
- package/packages/server/toolm/tool-yaml-parser.service.js +81 -0
- package/packages/server/toolm/validate-system.js +421 -0
- package/packages/server/utils/config.js +49 -5
- package/packages/server/utils/util.js +65 -10
- package/scripts/build-icons.js +99 -69
- package/scripts/build.sh +57 -0
- package/scripts/surge/CNAME +1 -0
- package/scripts/surge/README.md +47 -0
- package/scripts/surge/package-lock.json +34 -0
- package/scripts/surge/package.json +20 -0
- package/scripts/surge/sync-to-surge.js +151 -0
- package/app/desktop/assets/icons/icon_1024x1024.png +0 -0
- package/app/desktop/assets/icons/icon_128x128.png +0 -0
- package/app/desktop/assets/icons/icon_16x16.png +0 -0
- package/app/desktop/assets/icons/icon_24x24.png +0 -0
- package/app/desktop/assets/icons/icon_256x256.png +0 -0
- package/app/desktop/assets/icons/icon_32x32.png +0 -0
- package/app/desktop/assets/icons/icon_48x48.png +0 -0
- package/app/desktop/assets/icons/icon_512x512.png +0 -0
- package/app/desktop/assets/icons/icon_64x64.png +0 -0
- package/app/desktop/assets/icons/icon_96x96.png +0 -0
- package/packages/admin-ui/js/closebrackets.min.js +0 -8
- package/packages/admin-ui/js/codemirror.min.js +0 -8
- package/packages/admin-ui/js/js-yaml.min.js +0 -2
- package/packages/admin-ui/js/markdown.min.js +0 -8
- package/packages/resources/tools/index.js +0 -16
- package/packages/server/mcp/toolx.handler.js +0 -131
- package/scripts/icns-builder/package.json +0 -12
- /package/packages/server/mcp/{mcp.handler.js → prompt.handler.js} +0 -0
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
const { BrowserWindow, nativeImage } = require('electron');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
class SplashManager {
|
|
5
|
+
constructor(logger, iconManager) {
|
|
6
|
+
this.logger = logger;
|
|
7
|
+
this.iconManager = iconManager;
|
|
8
|
+
this.splashWindow = null;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* 创建并显示启动画面
|
|
13
|
+
*/
|
|
14
|
+
async showSplash() {
|
|
15
|
+
this.logger.info('Showing splash screen');
|
|
16
|
+
|
|
17
|
+
// 如果启动画面已存在,直接返回
|
|
18
|
+
if (this.splashWindow) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
try {
|
|
23
|
+
// 创建启动窗口
|
|
24
|
+
this.splashWindow = this.createSplashWindow();
|
|
25
|
+
|
|
26
|
+
// 加载启动画面内容
|
|
27
|
+
const htmlContent = this.generateSplashHTML();
|
|
28
|
+
this.splashWindow.loadURL(`data:text/html;charset=utf-8,${encodeURIComponent(htmlContent)}`);
|
|
29
|
+
|
|
30
|
+
// 设置窗口事件
|
|
31
|
+
this.setupWindowEvents();
|
|
32
|
+
|
|
33
|
+
this.logger.info('Splash screen shown successfully');
|
|
34
|
+
|
|
35
|
+
} catch (error) {
|
|
36
|
+
this.logger.error('Failed to show splash screen', error);
|
|
37
|
+
// 如果启动画面失败,不阻塞主流程
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* 创建启动窗口
|
|
43
|
+
*/
|
|
44
|
+
createSplashWindow() {
|
|
45
|
+
return new BrowserWindow({
|
|
46
|
+
width: 400,
|
|
47
|
+
height: 100,
|
|
48
|
+
transparent: true,
|
|
49
|
+
frame: false,
|
|
50
|
+
resizable: false,
|
|
51
|
+
movable: false,
|
|
52
|
+
fullscreenable: false,
|
|
53
|
+
hasShadow: false,
|
|
54
|
+
alwaysOnTop: true,
|
|
55
|
+
show: false,
|
|
56
|
+
webPreferences: {
|
|
57
|
+
contextIsolation: true,
|
|
58
|
+
nodeIntegration: false,
|
|
59
|
+
sandbox: false
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* 生成启动画面HTML内容
|
|
66
|
+
*/
|
|
67
|
+
generateSplashHTML() {
|
|
68
|
+
return `<!DOCTYPE html>
|
|
69
|
+
<html>
|
|
70
|
+
<head>
|
|
71
|
+
<meta charset="UTF-8">
|
|
72
|
+
<title>Prompt Manager - Loading</title>
|
|
73
|
+
<style>
|
|
74
|
+
body {
|
|
75
|
+
margin: 0;
|
|
76
|
+
padding: 0;
|
|
77
|
+
background: transparent;
|
|
78
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
|
79
|
+
display: flex;
|
|
80
|
+
align-items: center;
|
|
81
|
+
justify-content: center;
|
|
82
|
+
height: 100vh;
|
|
83
|
+
overflow: hidden;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.container {
|
|
87
|
+
width: 360px;
|
|
88
|
+
padding: 20px;
|
|
89
|
+
background: white;
|
|
90
|
+
border: 2px solid #1a1a1a;
|
|
91
|
+
border-radius: 8px;
|
|
92
|
+
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
|
|
93
|
+
text-align: center;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.title {
|
|
97
|
+
font-size: 20px;
|
|
98
|
+
font-weight: 580;
|
|
99
|
+
color: #666;
|
|
100
|
+
margin: 0 0 16px 0;
|
|
101
|
+
letter-spacing: -0.02em;
|
|
102
|
+
font-family: "SF Pro Display", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "PingFang SC", "Microsoft YaHei", sans-serif;
|
|
103
|
+
position: relative;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
.title::after {
|
|
107
|
+
content: '';
|
|
108
|
+
position: absolute;
|
|
109
|
+
bottom: -8px;
|
|
110
|
+
left: 50%;
|
|
111
|
+
transform: translateX(-50%);
|
|
112
|
+
width: 40px;
|
|
113
|
+
height: 1px;
|
|
114
|
+
background: linear-gradient(to right, transparent, #ccc, transparent);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.loading-container {
|
|
118
|
+
display: flex;
|
|
119
|
+
align-items: center;
|
|
120
|
+
justify-content: center;
|
|
121
|
+
gap: 12px;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
.loading-text {
|
|
125
|
+
font-size: 14px;
|
|
126
|
+
color: #999;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
.dots {
|
|
130
|
+
display: flex;
|
|
131
|
+
gap: 4px;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
.dot {
|
|
135
|
+
width: 6px;
|
|
136
|
+
height: 6px;
|
|
137
|
+
background: #aaa;
|
|
138
|
+
border-radius: 50%;
|
|
139
|
+
animation: pulse 1.5s infinite ease-in-out;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
.dot:nth-child(1) { animation-delay: -0.32s; }
|
|
143
|
+
.dot:nth-child(2) { animation-delay: -0.16s; }
|
|
144
|
+
|
|
145
|
+
@keyframes pulse {
|
|
146
|
+
0%, 80%, 100% {
|
|
147
|
+
transform: scale(0);
|
|
148
|
+
opacity: 0.5;
|
|
149
|
+
}
|
|
150
|
+
40% {
|
|
151
|
+
transform: scale(1);
|
|
152
|
+
opacity: 1;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
</style>
|
|
156
|
+
</head>
|
|
157
|
+
<body>
|
|
158
|
+
<div class="container">
|
|
159
|
+
<div class="title">Prompt Manager</div>
|
|
160
|
+
<div class="loading-container">
|
|
161
|
+
<div class="loading-text">正在启动</div>
|
|
162
|
+
<div class="dots">
|
|
163
|
+
<div class="dot"></div>
|
|
164
|
+
<div class="dot"></div>
|
|
165
|
+
<div class="dot"></div>
|
|
166
|
+
</div>
|
|
167
|
+
</div>
|
|
168
|
+
</div>
|
|
169
|
+
|
|
170
|
+
<script>
|
|
171
|
+
// 简单的动画效果增强
|
|
172
|
+
let dotIndex = 0;
|
|
173
|
+
const dots = document.querySelectorAll('.dot');
|
|
174
|
+
|
|
175
|
+
setInterval(() => {
|
|
176
|
+
// 重置所有点
|
|
177
|
+
dots.forEach(dot => {
|
|
178
|
+
dot.style.animation = 'none';
|
|
179
|
+
setTimeout(() => {
|
|
180
|
+
dot.style.animation = 'pulse 1.5s infinite ease-in-out';
|
|
181
|
+
}, 10);
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
// 依次激活点
|
|
185
|
+
dotIndex = (dotIndex + 1) % dots.length;
|
|
186
|
+
}, 1500);
|
|
187
|
+
</script>
|
|
188
|
+
</body>
|
|
189
|
+
</html>`;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* 更新启动状态
|
|
194
|
+
* @param {string} message - 状态消息
|
|
195
|
+
* @param {number} progress - 进度百分比 (0-100)
|
|
196
|
+
*/
|
|
197
|
+
updateStatus(message, progress) {
|
|
198
|
+
if (!this.splashWindow || this.splashWindow.isDestroyed()) {
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
try {
|
|
203
|
+
this.splashWindow.webContents.executeJavaScript(`
|
|
204
|
+
(function() {
|
|
205
|
+
const statusElement = document.getElementById('status');
|
|
206
|
+
const progressElement = document.getElementById('progress');
|
|
207
|
+
if (statusElement) statusElement.textContent = "${message}";
|
|
208
|
+
if (progressElement && ${progress} >= 0) {
|
|
209
|
+
progressElement.style.width = "${progress}%";
|
|
210
|
+
}
|
|
211
|
+
})();
|
|
212
|
+
`);
|
|
213
|
+
} catch (error) {
|
|
214
|
+
this.logger.warn('Failed to update splash status', error);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* 设置窗口事件
|
|
220
|
+
*/
|
|
221
|
+
setupWindowEvents() {
|
|
222
|
+
if (!this.splashWindow) return;
|
|
223
|
+
|
|
224
|
+
this.splashWindow.once('ready-to-show', () => {
|
|
225
|
+
if (this.splashWindow) {
|
|
226
|
+
this.splashWindow.show();
|
|
227
|
+
}
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
this.splashWindow.on('closed', () => {
|
|
231
|
+
this.splashWindow = null;
|
|
232
|
+
this.logger.info('Splash screen closed');
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* 关闭启动画面
|
|
238
|
+
*/
|
|
239
|
+
async closeSplash() {
|
|
240
|
+
this.logger.info('Closing splash screen');
|
|
241
|
+
|
|
242
|
+
if (this.splashWindow) {
|
|
243
|
+
try {
|
|
244
|
+
this.splashWindow.close();
|
|
245
|
+
this.splashWindow = null;
|
|
246
|
+
} catch (error) {
|
|
247
|
+
this.logger.warn('Failed to close splash window', error);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
module.exports = SplashManager;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
const { Tray, Menu, clipboard, nativeImage, dialog, shell
|
|
1
|
+
const { Tray, Menu, clipboard, nativeImage, dialog, shell } = require('electron');
|
|
2
2
|
const fs = require('fs');
|
|
3
3
|
const path = require('path');
|
|
4
4
|
const EventEmitter = require('../core/event-emitter');
|
|
5
|
+
const AdminWindowManager = require('./admin-window-manager');
|
|
5
6
|
|
|
6
7
|
class TrayManager extends EventEmitter {
|
|
7
8
|
constructor(logger, errorHandler, iconManager) {
|
|
@@ -13,7 +14,7 @@ class TrayManager extends EventEmitter {
|
|
|
13
14
|
this.menuTemplate = [];
|
|
14
15
|
this.iconPaths = [];
|
|
15
16
|
this.currentState = null;
|
|
16
|
-
this.
|
|
17
|
+
this.adminWindowManager = new AdminWindowManager(logger, iconManager);
|
|
17
18
|
}
|
|
18
19
|
|
|
19
20
|
async initialize(stateManager) {
|
|
@@ -142,29 +143,13 @@ class TrayManager extends EventEmitter {
|
|
|
142
143
|
}
|
|
143
144
|
|
|
144
145
|
openAdminWindow(adminUrl) {
|
|
145
|
-
if (this.
|
|
146
|
-
this.
|
|
146
|
+
if (this.adminWindowManager.hasWindow()) {
|
|
147
|
+
this.adminWindowManager.getWindow().focus();
|
|
147
148
|
return;
|
|
148
149
|
}
|
|
149
150
|
|
|
150
151
|
try {
|
|
151
|
-
this.
|
|
152
|
-
width: 1200,
|
|
153
|
-
height: 800,
|
|
154
|
-
title: 'Prompt Server 管理后台',
|
|
155
|
-
webPreferences: {
|
|
156
|
-
contextIsolation: true,
|
|
157
|
-
nodeIntegration: false
|
|
158
|
-
}
|
|
159
|
-
});
|
|
160
|
-
|
|
161
|
-
this.adminWindow.loadURL(adminUrl);
|
|
162
|
-
|
|
163
|
-
this.adminWindow.on('closed', () => {
|
|
164
|
-
this.adminWindow = null;
|
|
165
|
-
});
|
|
166
|
-
|
|
167
|
-
this.logger.info('Admin window opened', { url: adminUrl });
|
|
152
|
+
this.adminWindowManager.openAdminWindow(adminUrl);
|
|
168
153
|
} catch (error) {
|
|
169
154
|
this.logger.error('Failed to open admin window', error);
|
|
170
155
|
}
|
|
@@ -192,9 +177,8 @@ class TrayManager extends EventEmitter {
|
|
|
192
177
|
this.logger.info('Tray destroyed');
|
|
193
178
|
}
|
|
194
179
|
|
|
195
|
-
if (this.
|
|
196
|
-
this.
|
|
197
|
-
this.adminWindow = null;
|
|
180
|
+
if (this.adminWindowManager) {
|
|
181
|
+
this.adminWindowManager.closeAdminWindow();
|
|
198
182
|
}
|
|
199
183
|
}
|
|
200
184
|
}
|
|
@@ -20,69 +20,62 @@ class IconManager {
|
|
|
20
20
|
const basePath = path.join(__dirname, '..', '..', 'assets', 'icons');
|
|
21
21
|
|
|
22
22
|
return {
|
|
23
|
-
'
|
|
24
|
-
'
|
|
25
|
-
'
|
|
26
|
-
'
|
|
27
|
-
'64': path.join(basePath, 'icon_64x64.png'),
|
|
28
|
-
'96': path.join(basePath, 'icon_96x96.png'),
|
|
29
|
-
'128': path.join(basePath, 'icon_128x128.png'),
|
|
30
|
-
'256': path.join(basePath, 'icon_256x256.png'),
|
|
31
|
-
'512': path.join(basePath, 'icon_512x512.png'),
|
|
32
|
-
'1024': path.join(basePath, 'icon_1024x1024.png'),
|
|
33
|
-
'default': path.join(basePath, 'icon.png'),
|
|
34
|
-
'ico': path.join(basePath, 'icon.ico'),
|
|
35
|
-
'icns': path.join(basePath, 'icon.icns')
|
|
23
|
+
'icns': path.join(basePath, 'icon.icns'),
|
|
24
|
+
'ico': path.join(basePath, 'icon.ico'),
|
|
25
|
+
'png': path.join(basePath, 'icon.png'),
|
|
26
|
+
'tray': path.join(basePath, 'tray.png'),
|
|
36
27
|
};
|
|
37
28
|
}
|
|
38
29
|
|
|
39
30
|
/**
|
|
40
|
-
*
|
|
31
|
+
* 获取应用程序图标
|
|
32
|
+
* @returns {nativeImage|null} - 图标对象
|
|
33
|
+
*/
|
|
34
|
+
getAppIcon() {
|
|
35
|
+
const platform = process.platform;
|
|
36
|
+
if (platform === 'darwin') {
|
|
37
|
+
const iconPath = this.iconPaths['icns'];
|
|
38
|
+
return fs.existsSync(iconPath) ? nativeImage.createFromPath(iconPath) : null;
|
|
39
|
+
} else if (platform === 'win32') {
|
|
40
|
+
const iconPath = this.iconPaths['ico'];
|
|
41
|
+
return fs.existsSync(iconPath) ? nativeImage.createFromPath(iconPath) : null;
|
|
42
|
+
}
|
|
43
|
+
const iconPath = this.iconPaths['png'];
|
|
44
|
+
return fs.existsSync(iconPath) ? nativeImage.createFromPath(iconPath) : null;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* 获取指定尺寸的托盘图标
|
|
41
49
|
* @param {string|number} size - 图标尺寸
|
|
42
50
|
* @returns {nativeImage|null} - 图标对象
|
|
43
51
|
*/
|
|
44
|
-
|
|
52
|
+
getTrayIconBySize(size) {
|
|
45
53
|
const sizeKey = String(size);
|
|
46
54
|
|
|
47
|
-
if (this.iconCache.has(sizeKey)) {
|
|
48
|
-
return this.iconCache.get(sizeKey);
|
|
55
|
+
if (this.iconCache.has(`tray-${sizeKey}`)) {
|
|
56
|
+
return this.iconCache.get(`tray-${sizeKey}`);
|
|
49
57
|
}
|
|
50
58
|
|
|
51
|
-
const iconPath = this.iconPaths[
|
|
59
|
+
const iconPath = this.iconPaths['tray'];
|
|
52
60
|
if (!iconPath || !fs.existsSync(iconPath)) {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
console.warn(`Default icon not found at ${iconPath}`);
|
|
56
|
-
return null;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
console.warn(`Icon not found for size ${sizeKey}, trying default`);
|
|
60
|
-
return this.getIcon('default');
|
|
61
|
+
console.warn(`Tray icon not found for size ${sizeKey}`);
|
|
62
|
+
return null;
|
|
61
63
|
}
|
|
62
64
|
|
|
63
65
|
try {
|
|
64
66
|
const icon = nativeImage.createFromPath(iconPath);
|
|
67
|
+
icon.resize({ width: size, height: size });
|
|
65
68
|
|
|
66
69
|
if (icon.isEmpty()) {
|
|
67
|
-
console.warn(`Failed to load icon from ${iconPath}`);
|
|
68
|
-
|
|
69
|
-
if (sizeKey === 'default') {
|
|
70
|
-
return null;
|
|
71
|
-
}
|
|
72
|
-
// 否则尝试加载默认图标
|
|
73
|
-
return this.getIcon('default');
|
|
70
|
+
console.warn(`Failed to load tray icon from ${iconPath}`);
|
|
71
|
+
return null;
|
|
74
72
|
}
|
|
75
73
|
|
|
76
|
-
this.iconCache.set(sizeKey
|
|
74
|
+
this.iconCache.set(`tray-${sizeKey}`, icon);
|
|
77
75
|
return icon;
|
|
78
76
|
} catch (error) {
|
|
79
|
-
console.error(`Error loading icon ${iconPath}:`, error);
|
|
80
|
-
|
|
81
|
-
if (sizeKey === 'default') {
|
|
82
|
-
return null;
|
|
83
|
-
}
|
|
84
|
-
// 否则尝试加载默认图标
|
|
85
|
-
return this.getIcon('default');
|
|
77
|
+
console.error(`Error loading tray icon ${iconPath}:`, error);
|
|
78
|
+
return null;
|
|
86
79
|
}
|
|
87
80
|
}
|
|
88
81
|
|
|
@@ -104,11 +97,7 @@ class IconManager {
|
|
|
104
97
|
iconSize = '24'; // Linux 推荐 24x24
|
|
105
98
|
}
|
|
106
99
|
|
|
107
|
-
let icon = this.
|
|
108
|
-
|
|
109
|
-
if (!icon) {
|
|
110
|
-
icon = this.getIcon('default');
|
|
111
|
-
}
|
|
100
|
+
let icon = this.getTrayIconBySize(iconSize);
|
|
112
101
|
|
|
113
102
|
// macOS 特殊处理
|
|
114
103
|
if (platform === 'darwin' && icon) {
|
|
@@ -127,7 +116,10 @@ class IconManager {
|
|
|
127
116
|
* 获取关于对话框图标
|
|
128
117
|
*/
|
|
129
118
|
getAboutDialogIcon() {
|
|
130
|
-
|
|
119
|
+
// 优先使用应用图标,如果没有则使用较大的托盘图标
|
|
120
|
+
const iconPath = this.iconPaths['png'];
|
|
121
|
+
let icon = nativeImage.createFromPath(iconPath)
|
|
122
|
+
return icon.resize({ width: 64, height: 64 });
|
|
131
123
|
}
|
|
132
124
|
|
|
133
125
|
/**
|
|
@@ -11,29 +11,6 @@ class ResourcePaths {
|
|
|
11
11
|
this.assetsPath = path.join(this.basePath, 'assets');
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
/**
|
|
15
|
-
* 图标路径
|
|
16
|
-
*/
|
|
17
|
-
static get icons() {
|
|
18
|
-
const iconsPath = path.join(__dirname, '..', '..', 'assets', 'icons');
|
|
19
|
-
return {
|
|
20
|
-
base: iconsPath,
|
|
21
|
-
'16': path.join(iconsPath, 'icon_16x16.png'),
|
|
22
|
-
'24': path.join(iconsPath, 'icon_24x24.png'),
|
|
23
|
-
'32': path.join(iconsPath, 'icon_32x32.png'),
|
|
24
|
-
'48': path.join(iconsPath, 'icon_48x48.png'),
|
|
25
|
-
'64': path.join(iconsPath, 'icon_64x64.png'),
|
|
26
|
-
'96': path.join(iconsPath, 'icon_96x96.png'),
|
|
27
|
-
'128': path.join(iconsPath, 'icon_128x128.png'),
|
|
28
|
-
'256': path.join(iconsPath, 'icon_256x256.png'),
|
|
29
|
-
'512': path.join(iconsPath, 'icon_512x512.png'),
|
|
30
|
-
'1024': path.join(iconsPath, 'icon_1024x1024.png'),
|
|
31
|
-
'default': path.join(iconsPath, 'icon.png'),
|
|
32
|
-
'ico': path.join(iconsPath, 'icon.ico'),
|
|
33
|
-
'icns': path.join(iconsPath, 'icon.icns')
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
|
|
37
14
|
/**
|
|
38
15
|
* 模板路径
|
|
39
16
|
*/
|