From 077797c7e857732fd20fc330b33b763084bb050e Mon Sep 17 00:00:00 2001 From: Shashank-8p Date: Thu, 4 Jun 2026 00:03:34 +0530 Subject: [PATCH] refactor(ui): resolve duplicate ID conflicts for global controls --- web-app/index.html | 2192 ++++++++++++++++++++++++++++---------------- web-app/js/main.js | 214 ++--- 2 files changed, 1480 insertions(+), 926 deletions(-) diff --git a/web-app/index.html b/web-app/index.html index abcded8..67ab957 100644 --- a/web-app/index.html +++ b/web-app/index.html @@ -1,581 +1,1161 @@ - + - - - - - - - - - - - - - -Python Mini Projects — Interactive Web Edition - - - - - - - -
-
-
- - - - - - - - - - - - - - - -
- - -
- - - - - - -
-
-
- py.mini() + + -
-
- - - Python Arcade - - - - System Status: Nominal - -
+ + -
-

- Build tiny Python - projects & play -

-
+
+ +
+ + + + + -

Jump into browser-ready games, math experiments, and utility labs — each one ready in your browser, no install required.

- -
- - - - - Open Contribution - -
+
+
+
+ py.mini() +
+
-
- 0 total projects - 0 games - 0 maths - 0 utilities -
-
-
- - -
- - - - - - -
- - -
- - - -
-
TRACK-ROUTE
-
-
-
- -
- 01 -

Welcome

-

Jump into a tiny Python arcade built for curious beginners

+
+ + + Python Arcade + + + + System Status: Nominal +
-
-
-
-
-
-
-
-
- -
- 02 -

Explore

-

Browse games, math puzzles & utilities — each one ready in your browser

+ +
+

+ Build tiny Python + projects & play +

-
-
-
-
- -
- 03 -

Play

-

Launch any project instantly, experiment with code, and share your wins

+ +

+ Jump into browser-ready games, math experiments, and utility labs — + each one ready in your browser, no install required. +

+ +
+ + + + + Open Contribution +
-
-
-
-
-
-
-
-
- -
- 04 -

Learn

-

Pick up Python concepts as you play — loops, logic, data & more

+ +
+ 0 total projects + 0 games + 0 maths + 0 utilities
+
+ + +
+ + + + + +
-
-
- -
- 05 -

Build

-

Create your own mini projects and share them with the community

+ + +
+ + + +
+
TRACK-ROUTE
+
+
+
+ +
+ 01 +

Welcome

+

+ Jump into a tiny Python arcade built for curious beginners +

+
+
+
+
+
+
+
+
+
+ +
+ 02 +

Explore

+

+ Browse games, math puzzles & utilities — each one ready + in your browser +

+
+
+
+
+
+ +
+ 03 +

Play

+

+ Launch any project instantly, experiment with code, and + share your wins +

+
+
+
+
+
+
+
+
+
+ +
+ 04 +

Learn

+

+ Pick up Python concepts as you play — loops, logic, data + & more +

+
+
+
+
+
+ +
+ 05 +

Build

+

+ Create your own mini projects and share them with the + community +

+
+
+
+
+
+
+
+
+
+ +
+ 06 +

Share

+

+ Show off your work, get feedback, and keep growing as a dev +

+
+
+
-
-
-
-
-
-
-
- -
- 06 -

Share

-

Show off your work, get feedback, and keep growing as a dev

+
+ + +
+
+
+

+ Projects +

+ +
+
+
- - - -
- - -
-
-
-

Projects

- -
-
- -
-
- - - + + + +
-
-
- Output Console -
-

+        
-
- - -
- - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + - - - + + + - - -
-
- -

How to Play

-
    - -
    -
    - - - \ No newline at end of file + + console.log("✅ Modal fix loaded"); + })(); + + + +
    +
    + +

    How to Play

    +
      + +
      +
      + + diff --git a/web-app/js/main.js b/web-app/js/main.js index de59f2e..01718c1 100644 --- a/web-app/js/main.js +++ b/web-app/js/main.js @@ -158,8 +158,6 @@ document.addEventListener("DOMContentLoaded", function () { window.addEventListener("load", repairLegacyHomeLayoutNow, { once: true }); var html = document.documentElement; - var themeToggle = document.querySelector(".sidebar-dock #themeToggle"); - var soundToggle = document.querySelector(".sidebar-dock #soundToggle"); var backToTopButton = document.getElementById("backToTop"); var searchInput = document.querySelector(".sidebar-dock #searchInput"); var navSearchInput = document.getElementById("navSearchInput"); @@ -211,105 +209,53 @@ document.addEventListener("DOMContentLoaded", function () { }); } - /* ── Theme Toggle ─────────────────────────────────────────── */ - function updateThemeToggleAria(isLight) { - if (!themeToggle) return; - themeToggle.setAttribute( - "aria-label", - isLight ? "Switch to dark mode" : "Switch to light mode" - ); - } - - if (themeToggle) { - var savedTheme = localStorage.getItem("theme") || "dark"; - html.setAttribute("data-theme", savedTheme); - syncThemeColor(savedTheme); - // Prefer showing a sun icon when the site is dark (site's main theme). - // Show sun for dark theme, moon for light theme so reload displays sun by default. - themeToggle.innerHTML = - savedTheme === "dark" - ? '' - : ''; - updateThemeToggleAria(savedTheme === "light"); - - themeToggle.addEventListener("click", function () { - var current = html.getAttribute("data-theme"); - var next = current === "light" ? "dark" : "light"; - html.setAttribute("data-theme", next); - localStorage.setItem("theme", next); - syncThemeColor(next); - // After toggling, show sun when the new theme is dark, moon when it's light. - themeToggle.innerHTML = - next === "dark" - ? '' - : ''; - updateThemeToggleAria(next === "light"); + /* ── Sound Toggle (Multi-Element Support) ─────────────────────────── */ + var soundToggles = document.querySelectorAll(".sound-toggle"); + + function updateSoundIcons() { + var isMuted = window.audioController + ? window.audioController.isMuted + : false; + var iconHtml = isMuted + ? '' + : ''; + soundToggles.forEach(function (btn) { + btn.innerHTML = iconHtml; }); } - /* ── Sound Toggle ─────────────────────────────────────────── */ - if (soundToggle && window.audioController) { - function updateSoundIcon() { - soundToggle.innerHTML = window.audioController.isMuted - ? '' - : ''; - } - updateSoundIcon(); - soundToggle.addEventListener("click", function () { - if (typeof window.audioController.toggleMute === "function") { - window.audioController.toggleMute(); - updateSoundIcon(); - if ( - !window.audioController.isMuted && - typeof window.audioController.play === "function" - ) { - window.audioController.play("click"); + if (window.audioController) { + updateSoundIcons(); + soundToggles.forEach(function (toggle) { + toggle.addEventListener("click", function () { + if (typeof window.audioController.toggleMute === "function") { + window.audioController.toggleMute(); + updateSoundIcons(); // Instantly updates every sound button on the screen + if ( + !window.audioController.isMuted && + typeof window.audioController.play === "function" + ) { + window.audioController.play("click"); + } } - } - }); - } else if (soundToggle) { - soundToggle.addEventListener("click", function () { - var icon = soundToggle.querySelector("i"); - if (icon) - icon.className = - icon.className === "fas fa-volume-up" - ? "fas fa-volume-mute" - : "fas fa-volume-up"; - }); - } - - /* ── Hero Controls Mirror Toggles ─────────────────────────── */ - var heroSoundToggle = document.getElementById("heroSoundToggle"); - var heroThemeToggle = document.getElementById("heroThemeToggle"); - - function syncHeroControlsIcons() { - if (heroSoundToggle && soundToggle) { - var realSoundIcon = soundToggle.querySelector("i"); - var heroSoundIcon = heroSoundToggle.querySelector("i"); - if (realSoundIcon && heroSoundIcon) { - heroSoundIcon.className = realSoundIcon.className; - } - } - if (heroThemeToggle && themeToggle) { - var realThemeIcon = themeToggle.querySelector("i"); - var heroThemeIcon = heroThemeToggle.querySelector("i"); - if (realThemeIcon && heroThemeIcon) { - heroThemeIcon.className = realThemeIcon.className; - } - } - } - - if (heroSoundToggle && soundToggle) { - heroSoundToggle.addEventListener("click", function () { - soundToggle.click(); - setTimeout(syncHeroControlsIcons, 50); + }); }); - } - - if (heroThemeToggle && themeToggle) { - heroThemeToggle.addEventListener("click", function () { - themeToggle.click(); - setTimeout(syncHeroControlsIcons, 50); + } else { + // Fallback if audioController isn't loaded + soundToggles.forEach(function (toggle) { + toggle.addEventListener("click", function () { + var icon = this.querySelector("i"); + if (icon) { + var newClass = + icon.className === "fas fa-volume-up" + ? "fas fa-volume-mute" + : "fas fa-volume-up"; + soundToggles.forEach(function (btn) { + var i = btn.querySelector("i"); + if (i) i.className = newClass; + }); + } + }); }); } @@ -1602,45 +1548,45 @@ if (progressBar) { ticking = false; } - window.addEventListener("scroll", () => { - if (!ticking) { - requestAnimationFrame(updateScrollProgress); - ticking = true; - } - }); - } + window.addEventListener("scroll", () => { + if (!ticking) { + requestAnimationFrame(updateScrollProgress); + ticking = true; + } + }); +} - // URL parameters auto-open logic - (function () { - const params = new URLSearchParams(window.location.search); - const projectParam = params.get("project"); - if (projectParam) { - const match = projectCards.find( - (c) => c.getAttribute("data-project") === projectParam - ); - if (match) { - setTimeout(() => { - openProjectSafe(projectParam, match); - match.scrollIntoView({ behavior: "smooth", block: "center" }); - }, 300); - } +// URL parameters auto-open logic +(function () { + const params = new URLSearchParams(window.location.search); + const projectParam = params.get("project"); + if (projectParam) { + const match = projectCards.find( + (c) => c.getAttribute("data-project") === projectParam + ); + if (match) { + setTimeout(() => { + openProjectSafe(projectParam, match); + match.scrollIntoView({ behavior: "smooth", block: "center" }); + }, 300); } - const catParam = params.get("category"); - const valid = [ - "all", - "games", - "math", - "utilities", - "playground", - "favorites", - ]; - if (catParam && valid.includes(catParam)) { - const tab = document.querySelector(`[data-category="${catParam}"]`); - if (tab) { - setTimeout(() => tab.click(), 100); - } + } + const catParam = params.get("category"); + const valid = [ + "all", + "games", + "math", + "utilities", + "playground", + "favorites", + ]; + if (catParam && valid.includes(catParam)) { + const tab = document.querySelector(`[data-category="${catParam}"]`); + if (tab) { + setTimeout(() => tab.click(), 100); } - })(); + } +})(); - // Initial card filtering state update - updateProjectVisibility(currentCategory, currentSearchQuery); +// Initial card filtering state update +updateProjectVisibility(currentCategory, currentSearchQuery);