export default class DownloadOptionTr extends HTMLTableRowElement { H264_CODECS = { 'h264': 'h264', 'h.264': 'h264', 'x264': 'h264', } H265_CODECS = { 'h265': 'h265', 'h.265': 'h265', 'x265': 'h265', 'hevc': 'h265', } #downloadBtnEl; #selectEpisodeInputEl; url; size; quality; resolution; codec; seeders; provider; languages; mediaType; season; episode; filename; imdbId; episodeId; mediaTitle; constructor() { super(); this.url = this.getAttribute('url'); this.size = this.getAttribute('size'); this.quality = this.getAttribute('quality'); this.resolution = this.getAttribute('resolution'); this.codec = this.getAttribute('codec'); this.seeders = this.getAttribute('seeders'); this.provider = this.getAttribute('provider'); this.filename = this.getAttribute('filename'); this.imdbId = this.getAttribute('imdb-id'); this.languages = JSON.parse(this.getAttribute('languages')); this.mediaType = this.getAttribute('media-type'); this.mediaTitle = this.getAttribute('media-title'); this.season = this.getAttribute('season') ?? null; this.episode = this.getAttribute('episode') ?? null; this.episodeId = this.getAttribute('episode-id') ?? null; this.#downloadBtnEl = this.querySelector('.download-btn'); this.#selectEpisodeInputEl = this.querySelector('input[type="checkbox"]'); this.#downloadBtnEl.addEventListener('click', () => this.download()); } get isSelected() { return this.#selectEpisodeInputEl.checked; } set isSelected(value) { this.#selectEpisodeInputEl.checked = value; } filter({ detail: { activeFilter } }) { const optionHeader = document.querySelector(`[data-option-id="${this.dataset['localId']}"]`) let include = true; this.classList.add('r-tablerow'); this.classList.remove('hidden'); optionHeader.classList.add('r-tablerow'); optionHeader.classList.remove('hidden'); this.querySelector('input[type="checkbox"]').checked = false; if (!this.#validateResolutions(activeFilter.resolution)) { include = false; } if (!this.#validateCodecs(activeFilter.codec)) { include = false; } if (!this.#validateLanguages(activeFilter.language)) { include = false; } if (!this.#validateQualities(activeFilter.quality)) { include = false; } if (!this.#validateProviders(activeFilter.provider)) { include = false; } if (false === include) { this.classList.remove('r-tablerow'); this.classList.add('hidden'); optionHeader.classList.remove('r-tablerow'); optionHeader.classList.add('hidden'); } return include; } download() { fetch('/api/download', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', }, body: JSON.stringify({ url: this.url, title: this.mediaTitle, filename: this.filename, mediaType: this.mediaType, imdbId: this.imdbId, episodeId: this.episodeId }) }) .then(res => res.json()) .then(json => { console.log(json) }) } #validateResolutions(selectedOptions) { return this.#validateIntersection(selectedOptions, this.resolution.trim().split(',')); } #validateCodecs(selectedOptions) { if (this.#validateIntersection(selectedOptions, Object.keys(this.H264_CODECS))) { return this.#validateIntersection( selectedOptions, [...this.codec.trim().split(','), '', 'n/a'] ); } if (this.#validateIntersection(selectedOptions, Object.keys(this.H265_CODECS))) { return this.#validateIntersection( selectedOptions, [...this.codec.trim().split(','), '', 'n/a'] ); } return false; } #validateQualities(selectedOptions) { return this.#validateIntersection(selectedOptions, this.quality.trim().split(',')); } #validateProviders(selectedOptions) { return this.#validateIntersection(selectedOptions, this.provider.trim().split(',')); } #validateLanguages(selectedOptions) { return this.#validateIntersection(selectedOptions, this.languages); } #validateIntersection(selectedOptions, localOptions) { if (selectedOptions === null || selectedOptions === undefined) { return true; } if (typeof selectedOptions === 'string' || selectedOptions instanceof String) { selectedOptions = [selectedOptions]; } if (selectedOptions.length === 0 || (selectedOptions.length === 1 && selectedOptions[0] === "") || (selectedOptions.length === 1 && selectedOptions[0] === "n/a") ) { return true; } return this.#doesIntersect(localOptions, selectedOptions); } #doesIntersect(a, b) { if (a.length === 0 || b.length === 0) { return false; } return this.#intersect(a, b).length > 0; } #intersect(a, b) { return a.filter(Set.prototype.has, new Set(b)); } }