From fea26fd435dbb5d08149817c48a6de0bf687a2a8 Mon Sep 17 00:00:00 2001 From: Jonathan Sykes Date: Sun, 21 Jun 2026 21:13:44 +0800 Subject: [PATCH] feat: make channel names clickable in related, up-next, and mini-bar --- frontend/app.js | 34 +++++++++++++++++++++++++++++----- frontend/styles.css | 6 ++++++ 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/frontend/app.js b/frontend/app.js index cd23546..c151cf0 100755 --- a/frontend/app.js +++ b/frontend/app.js @@ -675,7 +675,9 @@ function updateProgress() { function showMiniBar() { if (!current || !current.meta) return; $('miniTitle').textContent = current.meta.title; - $('miniChannel').textContent = current.meta.channel || ''; + const miniCh = $('miniChannel'); + miniCh.textContent = current.meta.channel || ''; + miniCh.classList.toggle('link', !!channelKeyOf(current.meta)); $('miniBar').classList.remove('hidden'); updateMiniBar(); } @@ -774,9 +776,17 @@ function renderUpNext() { item.innerHTML = `
-
${v.title}
-
${v.channel || ''}
+
+
`; + item.querySelector('.upnext-title').textContent = v.title; + const upChEl = item.querySelector('.upnext-channel'); + upChEl.textContent = v.channel || ''; + if (channelKeyOf(v)) { + upChEl.classList.add('link'); + upChEl.title = 'View channel'; + upChEl.addEventListener('click', (e) => { e.stopPropagation(); openChannel(channelKeyOf(v), v.channel); }); + } item.addEventListener('click', () => { const idx = queue.findIndex((x) => x.id === v.id); if (idx >= 0) { queueIndex = idx - 1; playNext(); } @@ -2008,6 +2018,11 @@ document.querySelectorAll('.chip').forEach((c) => { openChannel(channelKeyOf(current.meta), current.meta.channel); } }); + $('miniChannel').addEventListener('click', () => { + if (current && current.meta && channelKeyOf(current.meta)) { + openChannel(channelKeyOf(current.meta), current.meta.channel); + } + }); // Controls els.playBtn.addEventListener('click', () => Player.toggle()); @@ -2220,8 +2235,17 @@ function renderRelated() { item.className = 'related-item'; item.innerHTML = `
`; item.querySelector('.ri-title').textContent = v.title; - item.querySelector('.ri-channel').textContent = v.channel || ''; - item.addEventListener('click', () => { queue = [v]; queueIndex = 0; Player.loadVideo(v); renderUpNext(); }); + const riChEl = item.querySelector('.ri-channel'); + riChEl.textContent = v.channel || ''; + if (channelKeyOf(v)) { + riChEl.classList.add('link'); + riChEl.title = 'View channel'; + riChEl.addEventListener('click', (e) => { e.stopPropagation(); openChannel(channelKeyOf(v), v.channel); }); + } + item.addEventListener('click', (e) => { + if (e.target.closest('.ri-channel.link')) return; + queue = [v]; queueIndex = 0; Player.loadVideo(v); renderUpNext(); + }); list.appendChild(item); }); } diff --git a/frontend/styles.css b/frontend/styles.css index eddcc49..edcacb8 100755 --- a/frontend/styles.css +++ b/frontend/styles.css @@ -1195,6 +1195,12 @@ input[type="range"]::-webkit-slider-thumb:hover { transform: scale(1.25); } .card-channel.link:hover { color: var(--accent); text-decoration: underline; } .np-channel { cursor: pointer; } .np-channel:hover { color: var(--text-2); } +.upnext-channel.link { cursor: pointer; } +.upnext-channel.link:hover { color: var(--accent); text-decoration: underline; } +.ri-channel.link { cursor: pointer; } +.ri-channel.link:hover { color: var(--accent); text-decoration: underline; } +.mini-channel.link { cursor: pointer; } +.mini-channel.link:hover { color: var(--accent); text-decoration: underline; } /* ============================================================================ * Per-card delete button (playlist / queue / saved)