Skip to content

Commit e9a112e

Browse files
authored
Merge pull request #41 from owennewo-dev/custom-css-themes
feat: additional themes
2 parents eb884e7 + b716294 commit e9a112e

19 files changed

+414
-43
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
node_modules
22
data
33
.DS_Store
4-
.env
4+
.env

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ These features are disabled by default. Set them to `true` to enable.
9292
|----------|---------|-------------|
9393
| `ENABLE_CHAT` | `false` | Enables the decentralized chat system. |
9494
| `ENABLE_MAP` | `false` | Enables map visualization features. |
95+
| `ENABLE_THEMES` | `true` | Controls the theme switcher function ([THEMES.md](THEMES.md))
9596

9697
### Refinement
9798
Tune the network parameters to fit your system resources. The defaults are safe for most users. Don't change unless you know what you're doing.

THEMES.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# Current themes
2+
3+
### Default
4+
5+
![Default theme screenshot](assets/images/default-theme.png)
6+
7+
### Tokyo Night
8+
9+
![Tokyo night theme screenshot](assets/images/tokyo-night-theme.png)
10+
11+
### Nord Dark
12+
13+
![Nord dark theme screenshot](assets/images/nord-dark-theme.png)
14+
15+
### Solarized Light
16+
17+
![Solarized light theme screenshot](assets/images/solarized-light-theme.png)
18+
19+
### Volcano
20+
21+
![Volcano theme screenshot](assets/images/volcano-theme.png)
22+
23+
# Contributing custom themes
24+
25+
1. Fork `main` and clone locally to your device.
26+
2. Create a copy of `default.css` (or any other existing theme file).
27+
Rename the file `new-theme.css` replacing "new-theme" with the actual name of your theme.
28+
Filename may not include capitals or spaces (use dashes `-`).
29+
Only add `dark` or `light` to the filename if the theme you are creating is based on a popular theme (solarized, nord, etc) that has dark and light versions. If a theme does not have two versions, or if a theme is completely made up by you, do not add `dark` or `light`.
30+
3. Edit the `const themes` block in [`app.js`](public/app.js) with the filename of your new theme so that when you press the theme cycle button in the bottom left corner of the UI, your new theme will appear as one of the options.
31+
```js
32+
const themes = [
33+
'default.css',
34+
'tokyo-night.css',
35+
'nord-dark.css',
36+
'solarized-light.css',
37+
'volcano.css',
38+
'new-theme.css' /* always add to the end of the list
39+
];
40+
```
41+
4. Change the colors as you desire. Reference [`index.html`](public/index.html) and [`style.css`](public/style.css) as needed.
42+
5. Test changes by running `npm install` then `npm start` in a terminal.
43+
6. Once you have finished creating your theme, edit [`THEMES.md`](THEMES.md) to include the name of your theme and a fullscreen screenshot in 16:9 aspect ratio at the bottom of the list. Ensure to match existing formatting.
44+
7. Create a pull request titled `theme: add *name of theme*`.
45+
46+
#### Thank you for contributing to Hypermind!

assets/images/default-theme.png

1.43 MB
Loading

assets/images/nord-dark-theme.png

1.38 MB
Loading
1.41 MB
Loading
1.51 MB
Loading

assets/images/volcano-theme.png

1.44 MB
Loading

docker-compose.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ services:
1010
# --- Add-ons ---
1111
# - ENABLE_CHAT=false # Enable decentralized chat
1212
# - ENABLE_MAP=false # Enable peer map visualization
13+
# - ENABLE_THEMES=true # Enable theme switcher button
1314

1415
# --- Refinements ---
1516
# - MAX_PEERS=50000 # Max peers to track in memory

public/app.js

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ const canvas = document.getElementById('network');
44
const ctx = canvas.getContext('2d');
55
let particles = [];
66

7+
function getThemeColor(varName) {
8+
return getComputedStyle(document.documentElement).getPropertyValue(varName).trim();
9+
}
10+
711
function resize() {
812
canvas.width = window.innerWidth;
913
canvas.height = window.innerHeight;
@@ -32,7 +36,7 @@ class Particle {
3236
draw() {
3337
ctx.beginPath();
3438
ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
35-
ctx.fillStyle = '#4ade80';
39+
ctx.fillStyle = getThemeColor('--color-particle');
3640
ctx.fill();
3741
}
3842
}
@@ -55,7 +59,7 @@ const updateParticles = (count) => {
5559
const animate = () => {
5660
ctx.clearRect(0, 0, canvas.width, canvas.height);
5761

58-
ctx.strokeStyle = 'rgba(74, 222, 128, 0.15)';
62+
ctx.strokeStyle = getThemeColor('--color-particle-link');
5963
ctx.lineWidth = 1;
6064
for (let i = 0; i < particles.length; i++) {
6165
for (let j = i + 1; j < particles.length; j++) {
@@ -489,3 +493,40 @@ countEl.classList.add('loaded');
489493
updateParticles(initialCount);
490494
animate();
491495

496+
const themes = [
497+
'default.css',
498+
'tokyo-night.css',
499+
'nord-dark.css',
500+
'solarized-light.css',
501+
'volcano.css'
502+
];
503+
504+
let currentThemeIndex = 0;
505+
506+
function loadSavedTheme() {
507+
const savedTheme = localStorage.getItem('hypermind-theme');
508+
if (savedTheme) {
509+
const themeLink = document.getElementById('theme-css');
510+
themeLink.href = `/themes/${savedTheme}`;
511+
currentThemeIndex = themes.indexOf(savedTheme);
512+
if (currentThemeIndex === -1) currentThemeIndex = 0;
513+
} else {
514+
const themeLink = document.getElementById('theme-css');
515+
const currentTheme = themeLink.href.split('/').pop();
516+
currentThemeIndex = themes.indexOf(currentTheme);
517+
if (currentThemeIndex === -1) currentThemeIndex = 0;
518+
}
519+
}
520+
521+
function cycleTheme() {
522+
currentThemeIndex = (currentThemeIndex + 1) % themes.length;
523+
const newTheme = themes[currentThemeIndex];
524+
const themeLink = document.getElementById('theme-css');
525+
themeLink.href = `/themes/${newTheme}`;
526+
localStorage.setItem('hypermind-theme', newTheme);
527+
}
528+
529+
document.getElementById('theme-switcher').addEventListener('click', cycleTheme);
530+
531+
loadSavedTheme();
532+

0 commit comments

Comments
 (0)