lobsterboard 0.3.1 → 0.3.2
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/CHANGELOG.md +6 -0
- package/README.md +19 -1
- package/dist/lobsterboard.css +1 -1
- package/dist/lobsterboard.esm.js +1 -1
- package/dist/lobsterboard.esm.min.js +1 -1
- package/dist/lobsterboard.umd.js +1 -1
- package/dist/lobsterboard.umd.min.js +1 -1
- package/js/templates.js +2 -2
- package/package.json +1 -1
- package/server.cjs +22 -5
package/CHANGELOG.md
CHANGED
|
@@ -12,6 +12,12 @@
|
|
|
12
12
|
- **Phosphor icon system** — themed widgets use Phosphor icons; Default theme keeps emoji
|
|
13
13
|
- **Theme selector dropdown** in edit mode header
|
|
14
14
|
- Theme persists to localStorage and dashboard config
|
|
15
|
+
- **Themes showcase** on website and README with lightbox gallery
|
|
16
|
+
|
|
17
|
+
## [0.2.6] - 2026-02-23
|
|
18
|
+
|
|
19
|
+
### Fixed
|
|
20
|
+
- **Version suffix comparison** — versions like `2026.2.22-2` (npm post-release patches) now correctly match GitHub tags like `v2026.2.22`, fixing false "Update available" indicators — thanks @JamesTsetsekas!
|
|
15
21
|
|
|
16
22
|
## [0.2.5] - 2026-02-19
|
|
17
23
|
|
package/README.md
CHANGED
|
@@ -37,9 +37,27 @@ Open **http://localhost:8080** → press **Ctrl+E** to enter edit mode → drag
|
|
|
37
37
|
- **Custom pages** — extend your dashboard with full custom pages (notes, kanban boards, anything)
|
|
38
38
|
- **Canvas sizes** — preset resolutions (1920×1080, 2560×1440, etc.) or custom sizes
|
|
39
39
|
- **Live data** — system stats stream via Server-Sent Events, widgets auto-refresh
|
|
40
|
-
- **
|
|
40
|
+
- **5 themes** — Default (dark), Terminal (CRT green), Feminine (pastel pink), Feminine Dark, Paper (sepia)
|
|
41
41
|
- **No cloud** — everything runs locally, your data stays yours
|
|
42
42
|
|
|
43
|
+
## Themes
|
|
44
|
+
|
|
45
|
+
LobsterBoard ships with 5 built-in themes. Switch themes from the dropdown in edit mode — your choice persists across sessions.
|
|
46
|
+
|
|
47
|
+
| Default | Terminal | Paper |
|
|
48
|
+
|---------|----------|-------|
|
|
49
|
+
|  |  |  |
|
|
50
|
+
|
|
51
|
+
| Feminine | Feminine Dark |
|
|
52
|
+
|----------|---------------|
|
|
53
|
+
|  |  |
|
|
54
|
+
|
|
55
|
+
- **Default** — dark theme with emoji icons (the classic look)
|
|
56
|
+
- **Terminal** — green CRT aesthetic with scanlines and Phosphor icons
|
|
57
|
+
- **Paper** — warm cream/sepia tones, serif fonts, vintage feel
|
|
58
|
+
- **Feminine** — soft pink and lavender pastels with subtle glows
|
|
59
|
+
- **Feminine Dark** — pink/purple accents on a dark background
|
|
60
|
+
|
|
43
61
|
## Configuration
|
|
44
62
|
|
|
45
63
|
```bash
|
package/dist/lobsterboard.css
CHANGED
package/dist/lobsterboard.esm.js
CHANGED
package/dist/lobsterboard.umd.js
CHANGED
package/js/templates.js
CHANGED
|
@@ -155,7 +155,7 @@
|
|
|
155
155
|
tplGrid.style.display = '';
|
|
156
156
|
loadTemplates();
|
|
157
157
|
} else {
|
|
158
|
-
alert('❌ ' + (data.error || 'Delete failed'));
|
|
158
|
+
alert('❌ ' + (data.error || data.message || 'Delete failed'));
|
|
159
159
|
}
|
|
160
160
|
} catch (e) {
|
|
161
161
|
alert('❌ Delete failed: ' + e.message);
|
|
@@ -187,7 +187,7 @@
|
|
|
187
187
|
alert(`✅ ${data.message}\n\nReloading dashboard...`);
|
|
188
188
|
location.reload();
|
|
189
189
|
} else {
|
|
190
|
-
alert('❌ ' + (data.error || 'Import failed'));
|
|
190
|
+
alert('❌ ' + (data.error || data.message || 'Import failed'));
|
|
191
191
|
}
|
|
192
192
|
} catch (e) {
|
|
193
193
|
alert('❌ Import failed: ' + e.message);
|
package/package.json
CHANGED
package/server.cjs
CHANGED
|
@@ -1458,12 +1458,25 @@ const server = http.createServer(async (req, res) => {
|
|
|
1458
1458
|
req.on('end', () => {
|
|
1459
1459
|
try {
|
|
1460
1460
|
const { id, mode } = JSON.parse(body);
|
|
1461
|
+
if (!id) { sendJson(res, 400, { error: 'Missing template id' }); return; }
|
|
1462
|
+
if (!mode) { sendJson(res, 400, { error: 'Missing import mode' }); return; }
|
|
1463
|
+
|
|
1461
1464
|
const tplConfigPath = path.join(TEMPLATES_DIR, id, 'config.json');
|
|
1462
|
-
if (!fs.existsSync(tplConfigPath)) { sendJson(res, 404, { error:
|
|
1463
|
-
|
|
1465
|
+
if (!fs.existsSync(tplConfigPath)) { sendJson(res, 404, { error: `Template "${id}" not found` }); return; }
|
|
1466
|
+
|
|
1467
|
+
let tplConfig;
|
|
1468
|
+
try {
|
|
1469
|
+
tplConfig = JSON.parse(fs.readFileSync(tplConfigPath, 'utf8'));
|
|
1470
|
+
} catch (parseErr) {
|
|
1471
|
+
sendJson(res, 500, { error: `Template config is invalid JSON: ${parseErr.message}` }); return;
|
|
1472
|
+
}
|
|
1464
1473
|
|
|
1465
1474
|
if (mode === 'replace') {
|
|
1466
|
-
|
|
1475
|
+
try {
|
|
1476
|
+
fs.writeFileSync(CONFIG_FILE, JSON.stringify(tplConfig, null, 2));
|
|
1477
|
+
} catch (writeErr) {
|
|
1478
|
+
sendJson(res, 500, { error: `Failed to write config: ${writeErr.message}` }); return;
|
|
1479
|
+
}
|
|
1467
1480
|
sendJson(res, 200, { status: 'success', message: 'Template imported (replace)' });
|
|
1468
1481
|
} else if (mode === 'merge') {
|
|
1469
1482
|
let currentConfig = { canvas: { width: 1920, height: 1080 }, widgets: [] };
|
|
@@ -1481,12 +1494,16 @@ const server = http.createServer(async (req, res) => {
|
|
|
1481
1494
|
y: (w.y || 0) + offset
|
|
1482
1495
|
}));
|
|
1483
1496
|
currentConfig.widgets = [...(currentConfig.widgets || []), ...newWidgets];
|
|
1484
|
-
|
|
1497
|
+
try {
|
|
1498
|
+
fs.writeFileSync(CONFIG_FILE, JSON.stringify(currentConfig, null, 2));
|
|
1499
|
+
} catch (writeErr) {
|
|
1500
|
+
sendJson(res, 500, { error: `Failed to write config: ${writeErr.message}` }); return;
|
|
1501
|
+
}
|
|
1485
1502
|
sendJson(res, 200, { status: 'success', message: `Merged ${newWidgets.length} widgets` });
|
|
1486
1503
|
} else {
|
|
1487
1504
|
sendJson(res, 400, { error: 'Invalid mode. Use "replace" or "merge"' });
|
|
1488
1505
|
}
|
|
1489
|
-
} catch (e) {
|
|
1506
|
+
} catch (e) { sendJson(res, 500, { error: `Import error: ${e.message}` }); }
|
|
1490
1507
|
});
|
|
1491
1508
|
return;
|
|
1492
1509
|
}
|