mani-calc 1.1.1 → 1.2.0
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/OVERLAY_MODE.md +3 -0
- package/package.json +2 -2
- package/src/core/clipboard-manager.js +14 -0
- package/src/ui/floating-search.js +27 -0
- package/src/ui/overlay.html +53 -22
package/OVERLAY_MODE.md
CHANGED
|
@@ -47,6 +47,9 @@ Control your computer with simple commands:
|
|
|
47
47
|
|
|
48
48
|
| Command | Action |
|
|
49
49
|
|---------|--------|
|
|
50
|
+
| `help` | Show available commands |
|
|
51
|
+
| `theme` | Toggle Light/Dark mode |
|
|
52
|
+
| `quit` | Quit application |
|
|
50
53
|
| `sleep` | Put computer to sleep |
|
|
51
54
|
| `shutdown` | Shutdown computer |
|
|
52
55
|
| `restart` | Restart computer |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mani-calc",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "Spotlight-style instant calculator for Windows Search | Math, natural language & unit conversions | Offline-first productivity tool",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"mathjs": "^12.2.1",
|
|
37
37
|
"node-windows": "^1.0.0-beta.8",
|
|
38
|
-
"clipboardy": "^3.0
|
|
38
|
+
"clipboardy": "^2.3.0",
|
|
39
39
|
"chalk": "^4.1.2",
|
|
40
40
|
"electron": "^28.1.0"
|
|
41
41
|
},
|
|
@@ -11,6 +11,14 @@ class ClipboardManager {
|
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
try {
|
|
14
|
+
// Check if running in Electron
|
|
15
|
+
if (process.versions.electron) {
|
|
16
|
+
const { clipboard } = require('electron');
|
|
17
|
+
clipboard.writeText(String(text));
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Fallback to clipboardy for CLI
|
|
14
22
|
await clipboardy.write(String(text));
|
|
15
23
|
return true;
|
|
16
24
|
} catch (error) {
|
|
@@ -21,6 +29,12 @@ class ClipboardManager {
|
|
|
21
29
|
|
|
22
30
|
async read() {
|
|
23
31
|
try {
|
|
32
|
+
// Check if running in Electron
|
|
33
|
+
if (process.versions.electron) {
|
|
34
|
+
const { clipboard } = require('electron');
|
|
35
|
+
return clipboard.readText();
|
|
36
|
+
}
|
|
37
|
+
|
|
24
38
|
return await clipboardy.read();
|
|
25
39
|
} catch (error) {
|
|
26
40
|
console.error('Failed to read from clipboard:', error);
|
|
@@ -100,6 +100,33 @@ class FloatingSearchBox {
|
|
|
100
100
|
const execAsync = promisify(exec);
|
|
101
101
|
|
|
102
102
|
const commands = {
|
|
103
|
+
'help': {
|
|
104
|
+
action: async () => {
|
|
105
|
+
return 'Commands: sleep, lock, shutdown, restart, logout, mute, volume up/down, theme, quit';
|
|
106
|
+
},
|
|
107
|
+
description: 'Show available commands'
|
|
108
|
+
},
|
|
109
|
+
'quit': {
|
|
110
|
+
action: async () => {
|
|
111
|
+
setTimeout(() => app.quit(), 500);
|
|
112
|
+
return 'Quitting Mani-Calc...';
|
|
113
|
+
},
|
|
114
|
+
description: 'Quit application'
|
|
115
|
+
},
|
|
116
|
+
'exit': {
|
|
117
|
+
action: async () => {
|
|
118
|
+
setTimeout(() => app.quit(), 500);
|
|
119
|
+
return 'Quitting Mani-Calc...';
|
|
120
|
+
},
|
|
121
|
+
description: 'Quit application'
|
|
122
|
+
},
|
|
123
|
+
'theme': {
|
|
124
|
+
action: async () => {
|
|
125
|
+
this.window.webContents.send('toggle-theme');
|
|
126
|
+
return 'Toggled theme';
|
|
127
|
+
},
|
|
128
|
+
description: 'Toggle Light/Dark mode'
|
|
129
|
+
},
|
|
103
130
|
'sleep': {
|
|
104
131
|
action: async () => {
|
|
105
132
|
await execAsync('rundll32.exe powrprof.dll,SetSuspendState 0,1,0');
|
package/src/ui/overlay.html
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<!DOCTYPE html>
|
|
2
2
|
<html lang="en">
|
|
3
|
+
|
|
3
4
|
<head>
|
|
4
5
|
<meta charset="UTF-8">
|
|
5
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
@@ -18,31 +19,58 @@
|
|
|
18
19
|
overflow: hidden;
|
|
19
20
|
}
|
|
20
21
|
|
|
22
|
+
:root {
|
|
23
|
+
--bg-color: rgba(255, 255, 255, 0.95);
|
|
24
|
+
--text-color: #333;
|
|
25
|
+
--icon-color: #00D9FF;
|
|
26
|
+
--hint-color: #999;
|
|
27
|
+
--shortcut-bg: rgba(0, 0, 0, 0.02);
|
|
28
|
+
--key-bg: rgba(0, 0, 0, 0.1);
|
|
29
|
+
--border-color: rgba(0, 0, 0, 0.1);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
body.dark {
|
|
33
|
+
--bg-color: rgba(30, 30, 30, 0.95);
|
|
34
|
+
--text-color: #eee;
|
|
35
|
+
--icon-color: #00D9FF;
|
|
36
|
+
--hint-color: #666;
|
|
37
|
+
--shortcut-bg: rgba(255, 255, 255, 0.05);
|
|
38
|
+
--key-bg: rgba(255, 255, 255, 0.1);
|
|
39
|
+
--border-color: rgba(255, 255, 255, 0.1);
|
|
40
|
+
}
|
|
41
|
+
|
|
21
42
|
.container {
|
|
22
43
|
width: 600px;
|
|
23
44
|
padding: 10px;
|
|
24
45
|
}
|
|
25
46
|
|
|
26
47
|
.search-box {
|
|
27
|
-
background:
|
|
48
|
+
background: var(--bg-color);
|
|
28
49
|
backdrop-filter: blur(20px);
|
|
29
50
|
border-radius: 12px;
|
|
30
51
|
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
|
|
31
52
|
overflow: hidden;
|
|
32
53
|
-webkit-app-region: no-drag;
|
|
54
|
+
transition: background 0.3s ease;
|
|
33
55
|
}
|
|
34
56
|
|
|
35
57
|
.input-container {
|
|
36
58
|
display: flex;
|
|
37
59
|
align-items: center;
|
|
38
60
|
padding: 16px 20px;
|
|
39
|
-
border-bottom: 1px solid
|
|
61
|
+
border-bottom: 1px solid var(--border-color);
|
|
40
62
|
}
|
|
41
63
|
|
|
42
64
|
.icon {
|
|
43
65
|
font-size: 24px;
|
|
44
66
|
margin-right: 12px;
|
|
45
|
-
color:
|
|
67
|
+
color: var(--icon-color);
|
|
68
|
+
-webkit-app-region: drag;
|
|
69
|
+
cursor: grab;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.icon:active {
|
|
73
|
+
cursor: grabbing;
|
|
46
74
|
}
|
|
47
75
|
|
|
48
76
|
#search-input {
|
|
@@ -51,11 +79,11 @@
|
|
|
51
79
|
outline: none;
|
|
52
80
|
font-size: 18px;
|
|
53
81
|
background: transparent;
|
|
54
|
-
color:
|
|
82
|
+
color: var(--text-color);
|
|
55
83
|
}
|
|
56
84
|
|
|
57
85
|
#search-input::placeholder {
|
|
58
|
-
color:
|
|
86
|
+
color: var(--hint-color);
|
|
59
87
|
}
|
|
60
88
|
|
|
61
89
|
.result-container {
|
|
@@ -74,6 +102,7 @@
|
|
|
74
102
|
opacity: 0;
|
|
75
103
|
transform: translateY(-10px);
|
|
76
104
|
}
|
|
105
|
+
|
|
77
106
|
to {
|
|
78
107
|
opacity: 1;
|
|
79
108
|
transform: translateY(0);
|
|
@@ -82,7 +111,7 @@
|
|
|
82
111
|
|
|
83
112
|
.result-text {
|
|
84
113
|
font-size: 16px;
|
|
85
|
-
color:
|
|
114
|
+
color: var(--icon-color);
|
|
86
115
|
font-weight: 600;
|
|
87
116
|
}
|
|
88
117
|
|
|
@@ -91,7 +120,7 @@
|
|
|
91
120
|
}
|
|
92
121
|
|
|
93
122
|
.result-text.success {
|
|
94
|
-
color:
|
|
123
|
+
color: var(--icon-color);
|
|
95
124
|
}
|
|
96
125
|
|
|
97
126
|
.result-text.system {
|
|
@@ -100,16 +129,16 @@
|
|
|
100
129
|
|
|
101
130
|
.hint {
|
|
102
131
|
font-size: 12px;
|
|
103
|
-
color:
|
|
132
|
+
color: var(--hint-color);
|
|
104
133
|
margin-top: 4px;
|
|
105
134
|
}
|
|
106
135
|
|
|
107
136
|
.shortcuts {
|
|
108
137
|
padding: 8px 20px;
|
|
109
|
-
background:
|
|
138
|
+
background: var(--shortcut-bg);
|
|
110
139
|
display: none;
|
|
111
140
|
font-size: 11px;
|
|
112
|
-
color:
|
|
141
|
+
color: var(--hint-color);
|
|
113
142
|
}
|
|
114
143
|
|
|
115
144
|
.shortcuts.show {
|
|
@@ -122,27 +151,23 @@
|
|
|
122
151
|
}
|
|
123
152
|
|
|
124
153
|
.key {
|
|
125
|
-
background:
|
|
154
|
+
background: var(--key-bg);
|
|
126
155
|
padding: 2px 6px;
|
|
127
156
|
border-radius: 3px;
|
|
128
157
|
font-family: monospace;
|
|
129
158
|
}
|
|
130
159
|
</style>
|
|
131
160
|
</head>
|
|
161
|
+
|
|
132
162
|
<body>
|
|
133
163
|
<div class="container">
|
|
134
164
|
<div class="search-box">
|
|
135
165
|
<div class="input-container">
|
|
136
166
|
<div class="icon">⚡</div>
|
|
137
|
-
<input
|
|
138
|
-
|
|
139
|
-
id="search-input"
|
|
140
|
-
placeholder="Type calculation or command..."
|
|
141
|
-
autocomplete="off"
|
|
142
|
-
spellcheck="false"
|
|
143
|
-
>
|
|
167
|
+
<input type="text" id="search-input" placeholder="Type calculation or command..." autocomplete="off"
|
|
168
|
+
spellcheck="false">
|
|
144
169
|
</div>
|
|
145
|
-
|
|
170
|
+
|
|
146
171
|
<div class="result-container" id="result-container">
|
|
147
172
|
<div class="result-text" id="result-text"></div>
|
|
148
173
|
<div class="hint" id="result-hint"></div>
|
|
@@ -158,7 +183,7 @@
|
|
|
158
183
|
|
|
159
184
|
<script>
|
|
160
185
|
const { ipcRenderer } = require('electron');
|
|
161
|
-
|
|
186
|
+
|
|
162
187
|
const input = document.getElementById('search-input');
|
|
163
188
|
const resultContainer = document.getElementById('result-container');
|
|
164
189
|
const resultText = document.getElementById('result-text');
|
|
@@ -184,7 +209,7 @@
|
|
|
184
209
|
// Handle input
|
|
185
210
|
input.addEventListener('input', (e) => {
|
|
186
211
|
const query = e.target.value.trim();
|
|
187
|
-
|
|
212
|
+
|
|
188
213
|
if (!query) {
|
|
189
214
|
resultContainer.classList.remove('show');
|
|
190
215
|
return;
|
|
@@ -226,6 +251,11 @@
|
|
|
226
251
|
}
|
|
227
252
|
}
|
|
228
253
|
|
|
254
|
+
// Handle theme toggle
|
|
255
|
+
ipcRenderer.on('toggle-theme', () => {
|
|
256
|
+
document.body.classList.toggle('dark');
|
|
257
|
+
});
|
|
258
|
+
|
|
229
259
|
// Handle result from main process
|
|
230
260
|
ipcRenderer.on('query-result', (event, result) => {
|
|
231
261
|
if (result.error) {
|
|
@@ -251,4 +281,5 @@
|
|
|
251
281
|
}, 100);
|
|
252
282
|
</script>
|
|
253
283
|
</body>
|
|
254
|
-
|
|
284
|
+
|
|
285
|
+
</html>
|