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 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.1.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.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');
@@ -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: rgba(255, 255, 255, 0.95);
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 rgba(0, 0, 0, 0.1);
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: #00D9FF;
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: #333;
82
+ color: var(--text-color);
55
83
  }
56
84
 
57
85
  #search-input::placeholder {
58
- color: #999;
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: #00D9FF;
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: #00D9FF;
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: #999;
132
+ color: var(--hint-color);
104
133
  margin-top: 4px;
105
134
  }
106
135
 
107
136
  .shortcuts {
108
137
  padding: 8px 20px;
109
- background: rgba(0, 0, 0, 0.02);
138
+ background: var(--shortcut-bg);
110
139
  display: none;
111
140
  font-size: 11px;
112
- color: #666;
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: rgba(0, 0, 0, 0.1);
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
- type="text"
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
- </html>
284
+
285
+ </html>