From 18b00fc5ae053b41dad34859fae6a53f22b03057 Mon Sep 17 00:00:00 2001 From: Brock H Caldwell Date: Thu, 24 Jul 2025 11:54:28 -0500 Subject: [PATCH] fix: performs filtering in web component --- assets/components/episode-container.js | 72 +++++++++++++++++- .../controllers/result_filter_controller.js | 15 +++- assets/controllers/tv_results_controller.js | 73 ------------------- templates/components/TvEpisodeList.html.twig | 2 +- .../torrentio/partial/option-table.html.twig | 2 +- 5 files changed, 84 insertions(+), 80 deletions(-) diff --git a/assets/components/episode-container.js b/assets/components/episode-container.js index 8e92638..b6dc4ac 100644 --- a/assets/components/episode-container.js +++ b/assets/components/episode-container.js @@ -1,16 +1,23 @@ export default class EpisodeContainer extends HTMLElement { + H264_CODECS = ['h264', 'h.264', 'x264'] + H265_CODECS = ['h265', 'h.265', 'x265', 'hevc'] + #resultsToggleBtnEl; #resultsTableEl; #resultsCountBadgeEl; + #resultsCountNumberEl; constructor() { super(); + this.#resultsTableEl = this.querySelector('.results-container'); this.#resultsToggleBtnEl = this.querySelector('.dropdown-button'); this.#resultsCountBadgeEl = this.querySelector('.results-count-badge'); - this.#resultsTableEl = this.querySelector('.results-container'); + this.#resultsCountNumberEl = this.querySelector('.results-count-number'); this.#resultsToggleBtnEl.addEventListener('click', () => this.toggleResults()); this.#resultsCountBadgeEl.addEventListener('click', () => this.toggleResults()); + + document.addEventListener('filterDownloadOptions', this.filter.bind(this)); } connectedCallback() { @@ -31,4 +38,67 @@ export default class EpisodeContainer extends HTMLElement { this.#resultsToggleBtnEl.classList.toggle('-rotate-90'); this.#resultsTableEl.classList.toggle('hidden'); } + + filter({ detail: { activeFilter } }) { + const options = this.querySelectorAll('tr.download-option'); + + let firstIncluded = true; + let count = 0; + let selectedCount = 0; + + options.forEach((option) => { + const optionHeader = document.querySelector(`[data-option-id="${option.dataset['localId']}"]`) + const props = { + "resolution": option.querySelector('#resolution').textContent.trim(), + "codec": option.querySelector('#codec').textContent.trim(), + "provider": option.querySelector('#provider').textContent.trim(), + "languages": JSON.parse(option.dataset['languages']), + "quality": option.dataset['quality'], + } + + let include = true; + option.classList.add('r-tablerow'); + option.classList.remove('hidden'); + optionHeader.classList.add('r-tablerow'); + optionHeader.classList.remove('hidden'); + option.querySelector('input[type="checkbox"]').checked = false; + + for (let [key, value] of Object.entries(activeFilter)) { + if (value === "" || key === "season") { + continue; + } + if (key === "codec" && value === "h264") { + if (!this.H264_CODECS.includes(props[key].toLowerCase())) { + include = false; + } + } else if (key === "codec" && value === "h265") { + if (!this.H265_CODECS.includes(props[key].toLowerCase())) { + include = false; + } + } else if (key === "language") { + if (!props["languages"].includes(value)) { + include = false; + } + } else if (props[key] !== value) { + include = false; + } + } + + if (false === include) { + option.classList.remove('r-tablerow'); + option.classList.add('hidden'); + optionHeader.classList.remove('r-tablerow'); + optionHeader.classList.add('hidden'); + } else if (true === firstIncluded) { + count = 1; + selectedCount = selectedCount + 1; + option.querySelector('input[type="checkbox"]').checked = true; + firstIncluded = false; + } else { + count = count + 1; + } + + this.#resultsCountNumberEl.innerText = count; + }); + } } diff --git a/assets/controllers/result_filter_controller.js b/assets/controllers/result_filter_controller.js index ac00da4..fa13901 100644 --- a/assets/controllers/result_filter_controller.js +++ b/assets/controllers/result_filter_controller.js @@ -128,7 +128,6 @@ export default class extends Controller { async filter() { const downloadSeasonSpan = document.querySelector("#downloadSeasonModal"); - const currentSeason = this.activeFilter['season']; let results = []; this.activeFilter = { @@ -141,14 +140,22 @@ export default class extends Controller { if ("movies" === this.mediaTypeValue) { results = this.movieResultsOutlets; - await results.forEach((list) => list.filter(this.activeFilter)); } else if ("tvshows" === this.mediaTypeValue) { results = this.tvResultsOutlets; + downloadSeasonSpan.innerText = this.seasonTarget.value; this.activeFilter.season = this.seasonTarget.value; - downloadSeasonSpan.innerText = this.activeFilter.season; - await results.forEach((list) => list.filter(this.activeFilter, currentSeason, this.seasonTarget.value)); } + + const event = new CustomEvent('filterDownloadOptions', { + detail: { + activeFilter: this.activeFilter + } + }) + + document.dispatchEvent(event); + + // await results.forEach((list) => list.filter(this.activeFilter)); } setSeason(event) { diff --git a/assets/controllers/tv_results_controller.js b/assets/controllers/tv_results_controller.js index 493fc8c..cef2ee7 100644 --- a/assets/controllers/tv_results_controller.js +++ b/assets/controllers/tv_results_controller.js @@ -83,77 +83,4 @@ export default class extends Controller { } }) } - - async filter(activeFilter, currentSeason, newSeason) { - if (currentSeason !== activeFilter['season']) { - if (this.seasonValue === newSeason) { - await this.setActive(); - } else { - await this.setInActive(); - } - } - - if (false === this.isActive()) { - return; - } - - let firstIncluded = true; - let count = 0; - let selectedCount = 0; - - this.options.forEach((option) => { - const optionHeader = document.querySelector(`[data-option-id="${option.dataset['localId']}"]`) - const props = { - "resolution": option.querySelector('#resolution').textContent.trim(), - "codec": option.querySelector('#codec').textContent.trim(), - "provider": option.querySelector('#provider').textContent.trim(), - "languages": JSON.parse(option.dataset['languages']), - "quality": option.dataset['quality'], - } - - let include = true; - option.classList.add('r-tablerow'); - option.classList.remove('hidden'); - optionHeader.classList.add('r-tablerow'); - optionHeader.classList.remove('hidden'); - option.querySelector('input[type="checkbox"]').checked = false; - - for (let [key, value] of Object.entries(activeFilter)) { - if (value === "" || key === "season") { - continue; - } - if (key === "codec" && value === "h264") { - if (!this.H264_CODECS.includes(props[key].toLowerCase())) { - include = false; - } - } else if (key === "codec" && value === "h265") { - if (!this.H265_CODECS.includes(props[key].toLowerCase())) { - include = false; - } - } else if (key === "language") { - if (!props["languages"].includes(value)) { - include = false; - } - } else if (props[key] !== value) { - include = false; - } - } - - if (false === include) { - option.classList.remove('r-tablerow'); - option.classList.add('hidden'); - optionHeader.classList.remove('r-tablerow'); - optionHeader.classList.add('hidden'); - } else if (true === firstIncluded) { - count = 1; - selectedCount = selectedCount + 1; - option.querySelector('input[type="checkbox"]').checked = true; - firstIncluded = false; - } else { - count = count + 1; - } - - this.countTarget.innerText = count; - }); - } } diff --git a/templates/components/TvEpisodeList.html.twig b/templates/components/TvEpisodeList.html.twig index 6445141..69a3c0f 100644 --- a/templates/components/TvEpisodeList.html.twig +++ b/templates/components/TvEpisodeList.html.twig @@ -31,7 +31,7 @@

{{ episode['overview']|truncate }}

diff --git a/templates/torrentio/partial/option-table.html.twig b/templates/torrentio/partial/option-table.html.twig index c0a5fd9..48f9afb 100644 --- a/templates/torrentio/partial/option-table.html.twig +++ b/templates/torrentio/partial/option-table.html.twig @@ -41,7 +41,7 @@ {% for result in results.results %} - + {{ result.size }}