diff --git a/.gitignore b/.gitignore index 4f498b0..6a4a987 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ node_modules data .DS_Store -.env +.env \ No newline at end of file diff --git a/README.md b/README.md index dbf4ec9..a678ca4 100644 --- a/README.md +++ b/README.md @@ -92,6 +92,7 @@ These features are disabled by default. Set them to `true` to enable. |----------|---------|-------------| | `ENABLE_CHAT` | `false` | Enables the decentralized chat system. | | `ENABLE_MAP` | `false` | Enables map visualization features. | +| `ENABLE_THEMES` | `true` | Controls the theme switcher function ([THEMES.md](THEMES.md)) ### Refinement 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. diff --git a/THEMES.md b/THEMES.md new file mode 100644 index 0000000..ba034d6 --- /dev/null +++ b/THEMES.md @@ -0,0 +1,46 @@ +# Current themes + +### Default + +![Default theme screenshot](assets/images/default-theme.png) + +### Tokyo Night + +![Tokyo night theme screenshot](assets/images/tokyo-night-theme.png) + +### Nord Dark + +![Nord dark theme screenshot](assets/images/nord-dark-theme.png) + +### Solarized Light + +![Solarized light theme screenshot](assets/images/solarized-light-theme.png) + +### Volcano + +![Volcano theme screenshot](assets/images/volcano-theme.png) + +# Contributing custom themes + +1. Fork `main` and clone locally to your device. +2. Create a copy of `default.css` (or any other existing theme file). + Rename the file `new-theme.css` replacing "new-theme" with the actual name of your theme. + Filename may not include capitals or spaces (use dashes `-`). + 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`. +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. + ```js + const themes = [ + 'default.css', + 'tokyo-night.css', + 'nord-dark.css', + 'solarized-light.css', + 'volcano.css', + 'new-theme.css' /* always add to the end of the list + ]; + ``` +4. Change the colors as you desire. Reference [`index.html`](public/index.html) and [`style.css`](public/style.css) as needed. +5. Test changes by running `npm install` then `npm start` in a terminal. +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. +7. Create a pull request titled `theme: add *name of theme*`. + +#### Thank you for contributing to Hypermind! \ No newline at end of file diff --git a/assets/images/default-theme.png b/assets/images/default-theme.png new file mode 100644 index 0000000..e5b7010 Binary files /dev/null and b/assets/images/default-theme.png differ diff --git a/assets/images/nord-dark-theme.png b/assets/images/nord-dark-theme.png new file mode 100644 index 0000000..0e99377 Binary files /dev/null and b/assets/images/nord-dark-theme.png differ diff --git a/assets/images/solarized-light-theme.png b/assets/images/solarized-light-theme.png new file mode 100644 index 0000000..7466bfd Binary files /dev/null and b/assets/images/solarized-light-theme.png differ diff --git a/assets/images/tokyo-night-theme.png b/assets/images/tokyo-night-theme.png new file mode 100644 index 0000000..b9e85ab Binary files /dev/null and b/assets/images/tokyo-night-theme.png differ diff --git a/assets/images/volcano-theme.png b/assets/images/volcano-theme.png new file mode 100644 index 0000000..061fe27 Binary files /dev/null and b/assets/images/volcano-theme.png differ diff --git a/docker-compose.yml b/docker-compose.yml index 4037c84..ac6e4ef 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -10,6 +10,7 @@ services: # --- Add-ons --- # - ENABLE_CHAT=false # Enable decentralized chat # - ENABLE_MAP=false # Enable peer map visualization + # - ENABLE_THEMES=true # Enable theme switcher button # --- Refinements --- # - MAX_PEERS=50000 # Max peers to track in memory diff --git a/public/app.js b/public/app.js index b269c9d..039eeab 100644 --- a/public/app.js +++ b/public/app.js @@ -4,6 +4,10 @@ const canvas = document.getElementById('network'); const ctx = canvas.getContext('2d'); let particles = []; +function getThemeColor(varName) { + return getComputedStyle(document.documentElement).getPropertyValue(varName).trim(); +} + function resize() { canvas.width = window.innerWidth; canvas.height = window.innerHeight; @@ -32,7 +36,7 @@ class Particle { draw() { ctx.beginPath(); ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2); - ctx.fillStyle = '#4ade80'; + ctx.fillStyle = getThemeColor('--color-particle'); ctx.fill(); } } @@ -55,7 +59,7 @@ const updateParticles = (count) => { const animate = () => { ctx.clearRect(0, 0, canvas.width, canvas.height); - ctx.strokeStyle = 'rgba(74, 222, 128, 0.15)'; + ctx.strokeStyle = getThemeColor('--color-particle-link'); ctx.lineWidth = 1; for (let i = 0; i < particles.length; i++) { for (let j = i + 1; j < particles.length; j++) { @@ -489,3 +493,40 @@ countEl.classList.add('loaded'); updateParticles(initialCount); animate(); +const themes = [ + 'default.css', + 'tokyo-night.css', + 'nord-dark.css', + 'solarized-light.css', + 'volcano.css' +]; + +let currentThemeIndex = 0; + +function loadSavedTheme() { + const savedTheme = localStorage.getItem('hypermind-theme'); + if (savedTheme) { + const themeLink = document.getElementById('theme-css'); + themeLink.href = `/themes/${savedTheme}`; + currentThemeIndex = themes.indexOf(savedTheme); + if (currentThemeIndex === -1) currentThemeIndex = 0; + } else { + const themeLink = document.getElementById('theme-css'); + const currentTheme = themeLink.href.split('/').pop(); + currentThemeIndex = themes.indexOf(currentTheme); + if (currentThemeIndex === -1) currentThemeIndex = 0; + } +} + +function cycleTheme() { + currentThemeIndex = (currentThemeIndex + 1) % themes.length; + const newTheme = themes[currentThemeIndex]; + const themeLink = document.getElementById('theme-css'); + themeLink.href = `/themes/${newTheme}`; + localStorage.setItem('hypermind-theme', newTheme); +} + +document.getElementById('theme-switcher').addEventListener('click', cycleTheme); + +loadSavedTheme(); + diff --git a/public/index.html b/public/index.html index 00d4feb..5b88f60 100644 --- a/public/index.html +++ b/public/index.html @@ -4,6 +4,7 @@ Hypermind + @@ -14,7 +15,7 @@
{{COUNT}}
Active Nodes
ID: {{ID}}
@@ -75,6 +76,9 @@
+