Skip to content

TODO: refactor items as checkboxes (notifications, theming)#11

Merged
jerryagenyi merged 11 commits intomainfrom
dev
Feb 3, 2026
Merged

TODO: refactor items as checkboxes (notifications, theming)#11
jerryagenyi merged 11 commits intomainfrom
dev

Conversation

@jerryagenyi
Copy link
Copy Markdown
Owner

@jerryagenyi jerryagenyi commented Feb 3, 2026

Moves the two recent future-refactor items into the main TODO list as unchecked items at the top:

  • Centralize notifications/alerts — Single place for toasts/notifications (styling, z-index, behaviour). Branch: fix/error-handling-refactor or refactor/centralize-notifications.
  • Centralised theming (light/dark, themes) — Refactor inline styles in index.html/streams.html to a shared theme layer for easy themes and light/dark mode.

Removes duplicate bullets from Reference section.

Summary by CodeRabbit

  • New Features

    • Unified glassmorphism design system rolled out across the UI for a cohesive, modern look.
  • Style

    • Updated cards, buttons, inputs and headers with glass-style visuals, glow and refined micro-interactions.
    • Improved focus states, keyboard/touch accessibility and motion-reduction handling.
  • Bug Fixes / Behaviour

    • Manual-stop behaviour for the Icecast server now prevents unintended automatic restarts.
  • Chores

    • Project task tracker updated to reflect completed UI and polish work.

- Add 10s timeout to play proxy to prevent hanging on Icecast issues
- Wrap upstream.resume() in try/catch for error resilience
- Add res.headersSent guard to prevent double responses
- Deduplicate streamIds in setStreamOrder() to prevent duplicates

Follow-up to deep review feedback.
…llbar, UX v2 doc

- Notification types: simple modal for duplicate name/source; full error UX for real failures
- Update UX: bell icon, auto-check on load, modal on click; single header-update-bell-btn
- Contact/Event: preserve each other when saving; remove collapsible; contact validate on entry
- Layout: remove size-full/flex-1 so one plain page scroll (no inner scrollbar)
- Stream labels: S1 - name (hyphen not em dash)
- docs: UI-UX-RECOMMENDATIONS-v2.md (glassmorphism); TODO updates
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Feb 3, 2026

📝 Walkthrough

Walkthrough

This PR applies a glassmorphism design system across the frontend (many components and pages), updates related CSS tokens and UI elements, makes minor dashboard API adjustments (default parameter and a fallback renderer), and adds an IcecastService guard to prevent automatic restart after a manual stop.

Changes

Cohort / File(s) Summary
Frontend - Core HTML
public/index.html, public/streams.html
Large glassmorphism introduction: new CSS tokens, glass-card/input/button variants, updated visuals, accessibility tweaks, and UI wiring updates. loadAudioDevices now has forceRefresh = false default; renderContactManagerFallback() added.
Components — Styling
public/components/ContactManager.js, public/components/EventManager.js, public/components/IcecastManager.js, public/components/HeaderComponent.js
Replaced explicit Tailwind utility blocks with semantic classes (glass-card, glass-card-inset, logo-glow, btn-glass-*, input-glass). Purely presentational changes; no API/logic surface changes.
FFmpeg Streams UI
public/components/FFmpegStreamsManager.js
Extensive replacement of card, input and button classes with glass variants across modals, lists and action buttons. Presentational only; behavior unchanged.
Backend service logic
src/services/IcecastService.js
Path resolution uses guarded config.icecast?.paths; start now respects manuallyStopped flag and prevents auto-start unless manual. Minor control-flow guard added.
Project tasks / docs
TODO.md
Task status updates (several moved to completed) and two new tasks added: centralised notifications and centralised theming. Minor content clarifications.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

🐇 Glass panes gleam beneath my paws,

Buttons hum and shimmer laws,
Cards that float on subtle light,
Streams that sparkle through the night,
A rabbit cheers — UI polished, bright!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately describes the main change: adding two new TODO items as checkboxes for notifications and theming refactoring work.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch dev

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
public/index.html (1)

487-495: ⚠️ Potential issue | 🟡 Minor

Duplicate @keyframes fadeIn definition will cause override.

There's a duplicate @keyframes fadeIn defined here (lines 488-491) that conflicts with the earlier definition at lines 405-414. The earlier one uses translateY(-8px) whilst this one uses translateY(10px). The second definition will override the first, which may cause unexpected animation behaviour for elements using the .fade-in class.

Consider removing or renaming one of these definitions to avoid confusion.

🔧 Suggested fix: Remove duplicate or rename

Either remove lines 488-491 if the first definition is preferred, or rename one of them:

-        `@keyframes` fadeIn {
-            from { opacity: 0; transform: translateY(10px); }
-            to { opacity: 1; transform: translateY(0); }
-        }

Or rename to distinguish them:

-        `@keyframes` fadeIn {
+        `@keyframes` fadeInUp {
             from { opacity: 0; transform: translateY(10px); }
             to { opacity: 1; transform: translateY(0); }
         }
public/components/HeaderComponent.js (1)

217-260: ⚠️ Potential issue | 🔴 Critical

Bug: originalContent is undefined and will cause a ReferenceError.

At line 255, the code references originalContent to restore the button state, but this variable is never defined in the update bell button click handler scope. This will throw a ReferenceError when the update check completes without finding an update.

Compare with the logout handler at line 277 which correctly captures originalContent before modifying the button.

🐛 Proposed fix
             bellBtn.addEventListener('click', async () => {
                 if (this.updateAvailable) {
                     // Show update modal if update is available
                     this.showUpdateModal();
                 } else {
                     // Manual check if no update available
                     console.log('🔄 Header update check requested');

+                    // Capture original content before changing
+                    const originalContent = bellBtn.innerHTML;
+
                     // Show loading state
                     bellBtn.innerHTML = `
                         <span class="material-symbols-rounded text-sm animate-spin">refresh</span>
                     `;
                     bellBtn.disabled = true;
🧹 Nitpick comments (2)
public/index.html (2)

1531-1570: Inconsistent notification styling between types.

The showNotification method applies different styling approaches:

  • success type uses the dedicated toast-success class (line 1537) which has proper glassmorphism with backdrop-filter
  • info and error types use generic glass-card class which may not have the same visual treatment

Consider creating toast-info and toast-error classes similar to toast-success for visual consistency, or ensure glass-card provides equivalent styling.

♻️ Suggested approach
 const colors = {
-    'info': 'glass-card border-blue-500/30 text-blue-300',
+    'info': 'toast-info',
     'success': 'toast-success',
-    'error': 'glass-card border-red-500/30 text-red-300'
+    'error': 'toast-error'
 };

Then add corresponding CSS classes in the style block:

.toast-info {
  background: rgba(59, 130, 246, 0.1);
  border: 1px solid rgba(59, 130, 246, 0.3);
  backdrop-filter: blur(20px);
  animation: slideIn 0.3s var(--ease-emphasized);
}

.toast-error {
  background: rgba(239, 68, 68, 0.1);
  border: 1px solid rgba(239, 68, 68, 0.3);
  backdrop-filter: blur(20px);
  animation: slideIn 0.3s var(--ease-emphasized);
}

1482-1528: Polling intervals are not stored or cleaned up.

The setInterval calls for status polling (lines 1486, 1511, 1520) don't store their return values, making it impossible to clear them later. If the dashboard is used in a context where it could be re-initialised, this could lead to multiple overlapping intervals.

For a full-page dashboard this is typically acceptable, but consider storing interval IDs if you anticipate component lifecycle management in the future.

♻️ Suggested approach for future-proofing
+            this.pollingIntervals = [];
+
             // Poll every 5 seconds for critical status updates
-            setInterval(async () => {
+            this.pollingIntervals.push(setInterval(async () => {
                 // ... existing code
-            }, 5000);
+            }, 5000));

             // Check security warnings every 30 seconds
-            setInterval(async () => {
+            this.pollingIntervals.push(setInterval(async () => {
                 // ... existing code
-            }, 30000);
+            }, 30000));

Add a cleanup method:

destroy() {
    this.pollingIntervals.forEach(id => clearInterval(id));
    this.pollingIntervals = [];
}

@jerryagenyi jerryagenyi merged commit c9f4416 into main Feb 3, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant