188 lines
5.5 KiB
JavaScript
188 lines
5.5 KiB
JavaScript
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));
|
|
}
|
|
}
|