From b6e14dc291ed25ba852d03639201ac49842b0170 Mon Sep 17 00:00:00 2001 From: MarekWo Date: Mon, 22 Dec 2025 19:32:02 +0100 Subject: [PATCH] fix: Resolve channel selector crash and cleanup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix critical JavaScript error that prevented channel selector from working: - Add null check for selectedOption before accessing .text property - Prevents "can't access property 'text', undefined" error at line 106 - This error occurred when selector options were being rebuilt Additional cleanup: - Remove duplicate escapeHtml() function definition - Add detailed console logging to loadChannels() for debugging Root cause: When populateChannelSelector() clears and rebuilds options, the change event can fire with an invalid selectedIndex, causing e.target.options[e.target.selectedIndex] to return undefined. Bug reported by user: TypeError at app.js:106 when switching channels 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 --- app/static/js/app.js | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/app/static/js/app.js b/app/static/js/app.js index ada1e49..3a61cd8 100644 --- a/app/static/js/app.js +++ b/app/static/js/app.js @@ -103,8 +103,12 @@ function setupEventListeners() { localStorage.setItem('mc_active_channel', currentChannelIdx); loadMessages(); - const channelName = e.target.options[e.target.selectedIndex].text; - showNotification(`Switched to channel: ${channelName}`, 'info'); + // Show notification only if we have a valid selection + const selectedOption = e.target.options[e.target.selectedIndex]; + if (selectedOption) { + const channelName = selectedOption.text; + showNotification(`Switched to channel: ${channelName}`, 'info'); + } }); // Channels modal - load channels when opened @@ -643,17 +647,21 @@ function setupEmojiPicker() { */ async function loadChannels() { try { + console.log('[loadChannels] Fetching channels from API...'); const response = await fetch('/api/channels'); const data = await response.json(); + console.log('[loadChannels] API response:', data); + if (data.success) { availableChannels = data.channels; + console.log('[loadChannels] Channels loaded:', availableChannels.length); populateChannelSelector(data.channels); } else { - console.error('Error loading channels:', data.error); + console.error('[loadChannels] Error loading channels:', data.error); } } catch (error) { - console.error('Error loading channels:', error); + console.error('[loadChannels] Exception:', error); } } @@ -824,12 +832,3 @@ function copyChannelKey() { document.execCommand('copy'); showNotification('Channel key copied to clipboard!', 'success'); } - -/** - * Escape HTML to prevent XSS - */ -function escapeHtml(text) { - const div = document.createElement('div'); - div.textContent = text; - return div.innerHTML; -}