Add: API endpoint for movie details

pull/16/head
Juraj Nyíri 3 years ago
parent c5f2f51f81
commit e44f141c64

@ -18724,6 +18724,12 @@ class Plex {
}); });
return this.exportSectionsData(await Promise.all(sectionsRequests)); return this.exportSectionsData(await Promise.all(sectionsRequests));
}; };
this.getDetails = async (id) => {
const url = `${this.protocol}://${this.ip}:${this.port}/library/metadata/${id}?includeConcerts=1&includeExtras=1&includeOnDeck=1&includePopularLeaves=1&includePreferences=1&includeReviews=1&includeChapters=1&includeStations=1&includeExternalMedia=1&asyncAugmentMetadata=1&asyncCheckFiles=1&asyncRefreshAnalysis=1&asyncRefreshLocalMediaAgent=1&X-Plex-Token=${this.token}`;
return (await axios.get(url, {
timeout: this.requestTimeout
})).data.MediaContainer.Metadata[0];
};
this.getLibraryData = async (id) => { this.getLibraryData = async (id) => {
const url = `${this.protocol}://${this.ip}:${this.port}/library/metadata/${id}/children?X-Plex-Token=${this.token}`; const url = `${this.protocol}://${this.ip}:${this.port}/library/metadata/${id}/children?X-Plex-Token=${this.token}`;
return (await axios.get(url, { return (await axios.get(url, {
@ -20032,210 +20038,215 @@ class PlexMeetsHomeAssistant extends HTMLElement {
} }
}, 200); }, 200);
} }
if (this.plex && data.childCount > 0) { if (this.plex) {
this.seasonElemFreshlyLoaded = true; if (data.childCount > 0) {
const seasonsData = await this.plex.getLibraryData(data.key.split('/')[3]); this.seasonElemFreshlyLoaded = true;
if (this.seasonsElem) { const seasonsData = await this.plex.getLibraryData(data.key.split('/')[3]);
this.seasonsElem.style.display = 'block';
this.seasonsElem.innerHTML = '';
this.seasonsElem.style.transition = `0s`;
this.seasonsElem.style.top = `${top + 2000}px`;
}
lodash.forEach(seasonsData, seasonData => {
if (this.seasonsElem) { if (this.seasonsElem) {
this.seasonsElemHidden = false; this.seasonsElem.style.display = 'block';
const seasonContainer = document.createElement('div'); this.seasonsElem.innerHTML = '';
seasonContainer.className = 'seasonContainer'; this.seasonsElem.style.transition = `0s`;
seasonContainer.style.width = `${CSS_STYLE.width}px`; this.seasonsElem.style.top = `${top + 2000}px`;
const thumbURL = `${this.plexProtocol}://${this.config.ip}:${this.config.port}/photo/:/transcode?width=${CSS_STYLE.expandedWidth}&height=${CSS_STYLE.expandedHeight}&minSize=1&upscale=1&url=${seasonData.thumb}&X-Plex-Token=${this.config.token}`; }
const seasonElem = document.createElement('div'); lodash.forEach(seasonsData, seasonData => {
seasonElem.className = 'seasonElem'; if (this.seasonsElem) {
seasonElem.style.width = `${CSS_STYLE.width}px`; this.seasonsElemHidden = false;
seasonElem.style.height = `${CSS_STYLE.height - 3}px`; const seasonContainer = document.createElement('div');
seasonElem.style.backgroundImage = `url('${thumbURL}')`; seasonContainer.className = 'seasonContainer';
seasonElem.dataset.clicked = 'false'; seasonContainer.style.width = `${CSS_STYLE.width}px`;
if (this.playController && !this.playController.isPlaySupported(seasonData)) { const thumbURL = `${this.plexProtocol}://${this.config.ip}:${this.config.port}/photo/:/transcode?width=${CSS_STYLE.expandedWidth}&height=${CSS_STYLE.expandedHeight}&minSize=1&upscale=1&url=${seasonData.thumb}&X-Plex-Token=${this.config.token}`;
seasonElem.style.cursor = 'pointer'; const seasonElem = document.createElement('div');
} seasonElem.className = 'seasonElem';
const interactiveArea = document.createElement('div'); seasonElem.style.width = `${CSS_STYLE.width}px`;
interactiveArea.className = 'interactiveArea'; seasonElem.style.height = `${CSS_STYLE.height - 3}px`;
if (seasonData.leafCount - seasonData.viewedLeafCount > 0) { seasonElem.style.backgroundImage = `url('${thumbURL}')`;
const toViewElem = document.createElement('div'); seasonElem.dataset.clicked = 'false';
toViewElem.className = 'toViewSeason'; if (this.playController && !this.playController.isPlaySupported(seasonData)) {
toViewElem.innerHTML = (seasonData.leafCount - seasonData.viewedLeafCount).toString(); seasonElem.style.cursor = 'pointer';
interactiveArea.appendChild(toViewElem); }
} const interactiveArea = document.createElement('div');
if (this.playController && this.playController.isPlaySupported(seasonData)) { interactiveArea.className = 'interactiveArea';
const playButton = this.getPlayButton(); if (seasonData.leafCount - seasonData.viewedLeafCount > 0) {
playButton.addEventListener('click', event => { const toViewElem = document.createElement('div');
toViewElem.className = 'toViewSeason';
toViewElem.innerHTML = (seasonData.leafCount - seasonData.viewedLeafCount).toString();
interactiveArea.appendChild(toViewElem);
}
if (this.playController && this.playController.isPlaySupported(seasonData)) {
const playButton = this.getPlayButton();
playButton.addEventListener('click', event => {
event.stopPropagation();
if (this.plex && this.playController) {
this.playController.play(seasonData, true);
}
});
interactiveArea.append(playButton);
}
seasonElem.append(interactiveArea);
seasonContainer.append(seasonElem);
const seasonTitleElem = document.createElement('div');
seasonTitleElem.className = 'seasonTitleElem';
seasonTitleElem.innerHTML = escapeHtml(seasonData.title);
seasonContainer.append(seasonTitleElem);
const seasonEpisodesCount = document.createElement('div');
seasonEpisodesCount.className = 'seasonEpisodesCount';
seasonEpisodesCount.innerHTML = `${escapeHtml(seasonData.leafCount)} episodes`;
seasonContainer.append(seasonEpisodesCount);
seasonContainer.addEventListener('click', event => {
event.stopPropagation(); event.stopPropagation();
if (this.plex && this.playController) { if (this.seasonContainerClickEnabled) {
this.playController.play(seasonData, true); this.seasonContainerClickEnabled = false;
} setTimeout(() => {
}); this.seasonContainerClickEnabled = true;
interactiveArea.append(playButton); }, 500);
} if (this.activeMovieElem) {
seasonElem.append(interactiveArea); if (seasonElem.dataset.clicked === 'false') {
seasonContainer.append(seasonElem); if (typeof seasonElem.children[0].children[0] !== 'undefined') {
const seasonTitleElem = document.createElement('div'); seasonElem.children[0].children[0].style.display = 'none';
seasonTitleElem.className = 'seasonTitleElem';
seasonTitleElem.innerHTML = escapeHtml(seasonData.title);
seasonContainer.append(seasonTitleElem);
const seasonEpisodesCount = document.createElement('div');
seasonEpisodesCount.className = 'seasonEpisodesCount';
seasonEpisodesCount.innerHTML = `${escapeHtml(seasonData.leafCount)} episodes`;
seasonContainer.append(seasonEpisodesCount);
seasonContainer.addEventListener('click', event => {
event.stopPropagation();
if (this.seasonContainerClickEnabled) {
this.seasonContainerClickEnabled = false;
setTimeout(() => {
this.seasonContainerClickEnabled = true;
}, 500);
if (this.activeMovieElem) {
if (seasonElem.dataset.clicked === 'false') {
if (typeof seasonElem.children[0].children[0] !== 'undefined') {
seasonElem.children[0].children[0].style.display = 'none';
}
seasonElem.dataset.clicked = 'true';
this.activeMovieElem.style.top = `${top - 1000}px`;
setTimeout(() => {
if (this.activeMovieElem) {
this.activeMovieElem.style.display = 'none';
} }
}, 500); seasonElem.dataset.clicked = 'true';
this.scrollDownInactiveSeasons(); this.activeMovieElem.style.top = `${top - 1000}px`;
seasonContainer.style.top = `${-CSS_STYLE.expandedHeight}px`; setTimeout(() => {
seasonElem.style.width = `${CSS_STYLE.expandedWidth}px`; if (this.activeMovieElem) {
seasonElem.style.height = `${CSS_STYLE.expandedHeight - 6}px`; this.activeMovieElem.style.display = 'none';
seasonElem.style.zIndex = '3'; }
seasonElem.style.marginLeft = `-${getOffset(seasonElem).left - }, 500);
getOffset(this.activeMovieElem).left}px`; this.scrollDownInactiveSeasons();
seasonTitleElem.style.color = 'rgba(255,255,255,0)'; seasonContainer.style.top = `${-CSS_STYLE.expandedHeight}px`;
seasonEpisodesCount.style.color = 'rgba(255,255,255,0)'; seasonElem.style.width = `${CSS_STYLE.expandedWidth}px`;
if (this.detailElem) { seasonElem.style.height = `${CSS_STYLE.expandedHeight - 6}px`;
this.detailElem.children[1].innerHTML = seasonData.title; seasonElem.style.zIndex = '3';
} seasonElem.style.marginLeft = `-${getOffset(seasonElem).left -
(async () => { getOffset(this.activeMovieElem).left}px`;
if (seasonData.leafCount > 0 && this.plex) { seasonTitleElem.style.color = 'rgba(255,255,255,0)';
this.episodesElemFreshlyLoaded = true; seasonEpisodesCount.style.color = 'rgba(255,255,255,0)';
const episodesData = await this.plex.getLibraryData(seasonData.key.split('/')[3]); if (this.detailElem) {
if (this.episodesElem) { this.detailElem.children[1].innerHTML = seasonData.title;
this.episodesElemHidden = false; }
this.episodesElem.style.display = 'block'; (async () => {
this.episodesElem.innerHTML = ''; if (seasonData.leafCount > 0 && this.plex) {
this.episodesElem.style.transition = `0s`; this.episodesElemFreshlyLoaded = true;
this.episodesElem.style.top = `${top + 2000}px`; const episodesData = await this.plex.getLibraryData(seasonData.key.split('/')[3]);
lodash.forEach(episodesData, episodeData => { if (this.episodesElem) {
if (this.episodesElem) { this.episodesElemHidden = false;
const episodeContainer = document.createElement('div'); this.episodesElem.style.display = 'block';
episodeContainer.className = 'episodeContainer'; this.episodesElem.innerHTML = '';
episodeContainer.style.width = `${CSS_STYLE.episodeWidth}px`; this.episodesElem.style.transition = `0s`;
const episodeThumbURL = `${this.plexProtocol}://${this.config.ip}:${this.config.port}/photo/:/transcode?width=${CSS_STYLE.episodeWidth}&height=${CSS_STYLE.episodeHeight}&minSize=1&upscale=1&url=${episodeData.thumb}&X-Plex-Token=${this.config.token}`; this.episodesElem.style.top = `${top + 2000}px`;
const episodeElem = document.createElement('div'); lodash.forEach(episodesData, episodeData => {
episodeElem.className = 'episodeElem'; if (this.episodesElem) {
episodeElem.style.width = `${CSS_STYLE.episodeWidth}px`; const episodeContainer = document.createElement('div');
episodeElem.style.height = `${CSS_STYLE.episodeHeight}px`; episodeContainer.className = 'episodeContainer';
episodeElem.style.backgroundImage = `url('${episodeThumbURL}')`; episodeContainer.style.width = `${CSS_STYLE.episodeWidth}px`;
episodeElem.dataset.clicked = 'false'; const episodeThumbURL = `${this.plexProtocol}://${this.config.ip}:${this.config.port}/photo/:/transcode?width=${CSS_STYLE.episodeWidth}&height=${CSS_STYLE.episodeHeight}&minSize=1&upscale=1&url=${episodeData.thumb}&X-Plex-Token=${this.config.token}`;
if (typeof episodeData.lastViewedAt === 'undefined') { const episodeElem = document.createElement('div');
const toViewElem = document.createElement('div'); episodeElem.className = 'episodeElem';
toViewElem.className = 'toViewEpisode'; episodeElem.style.width = `${CSS_STYLE.episodeWidth}px`;
episodeElem.appendChild(toViewElem); episodeElem.style.height = `${CSS_STYLE.episodeHeight}px`;
} episodeElem.style.backgroundImage = `url('${episodeThumbURL}')`;
if (this.playController && this.playController.isPlaySupported(episodeData)) { episodeElem.dataset.clicked = 'false';
const episodeInteractiveArea = document.createElement('div'); if (typeof episodeData.lastViewedAt === 'undefined') {
episodeInteractiveArea.className = 'interactiveArea'; const toViewElem = document.createElement('div');
const episodePlayButton = document.createElement('button'); toViewElem.className = 'toViewEpisode';
episodePlayButton.name = 'playButton'; episodeElem.appendChild(toViewElem);
episodePlayButton.addEventListener('click', episodeEvent => { }
if (this.playController && this.playController.isPlaySupported(episodeData)) {
const episodeInteractiveArea = document.createElement('div');
episodeInteractiveArea.className = 'interactiveArea';
const episodePlayButton = document.createElement('button');
episodePlayButton.name = 'playButton';
episodePlayButton.addEventListener('click', episodeEvent => {
episodeEvent.stopPropagation();
if (this.plex && this.playController) {
this.playController.play(episodeData, true);
}
});
episodeInteractiveArea.append(episodePlayButton);
episodeElem.append(episodeInteractiveArea);
}
episodeContainer.append(episodeElem);
const episodeTitleElem = document.createElement('div');
episodeTitleElem.className = 'episodeTitleElem';
episodeTitleElem.innerHTML = escapeHtml(episodeData.title);
episodeContainer.append(episodeTitleElem);
const episodeNumber = document.createElement('div');
episodeNumber.className = 'episodeNumber';
episodeNumber.innerHTML = escapeHtml(`Episode ${escapeHtml(episodeData.index)}`);
episodeContainer.append(episodeNumber);
episodeContainer.addEventListener('click', episodeEvent => {
episodeEvent.stopPropagation(); episodeEvent.stopPropagation();
if (this.plex && this.playController) {
this.playController.play(episodeData, true);
}
}); });
episodeInteractiveArea.append(episodePlayButton); this.episodesElem.append(episodeContainer);
episodeElem.append(episodeInteractiveArea); }
});
clearInterval(this.episodesLoadTimeout);
this.episodesLoadTimeout = setTimeout(() => {
if (this.episodesElem) {
this.episodesElem.style.transition = `0.7s`;
this.episodesElem.style.top = `${top + CSS_STYLE.expandedHeight + 16}px`;
this.resizeBackground();
} }
episodeContainer.append(episodeElem); }, 200);
const episodeTitleElem = document.createElement('div'); clearInterval(this.episodesElemFreshlyLoadedTimeout);
episodeTitleElem.className = 'episodeTitleElem'; this.episodesElemFreshlyLoadedTimeout = setTimeout(() => {
episodeTitleElem.innerHTML = escapeHtml(episodeData.title); this.episodesElemFreshlyLoaded = false;
episodeContainer.append(episodeTitleElem); }, 700);
const episodeNumber = document.createElement('div'); }
episodeNumber.className = 'episodeNumber'; }
episodeNumber.innerHTML = escapeHtml(`Episode ${escapeHtml(episodeData.index)}`); })();
episodeContainer.append(episodeNumber); }
episodeContainer.addEventListener('click', episodeEvent => { else {
episodeEvent.stopPropagation(); seasonContainer.style.top = `${seasonContainer.dataset.top}px`;
}); this.minimizeSeasons();
this.episodesElem.append(episodeContainer); this.hideEpisodes();
} this.activeMovieElem.style.display = `block`;
}); setTimeout(() => {
clearInterval(this.episodesLoadTimeout); if (this.activeMovieElem) {
this.episodesLoadTimeout = setTimeout(() => { this.activeMovieElem.style.top = `${top + 16}px`;
if (this.episodesElem) { }
this.episodesElem.style.transition = `0.7s`; }, 10);
this.episodesElem.style.top = `${top + CSS_STYLE.expandedHeight + 16}px`; if (this.detailElem && this.detailElem.children[1]) {
this.resizeBackground(); const { year } = this.detailElem.children[1].dataset;
} if (year) {
}, 200); this.detailElem.children[1].innerHTML = year;
clearInterval(this.episodesElemFreshlyLoadedTimeout);
this.episodesElemFreshlyLoadedTimeout = setTimeout(() => {
this.episodesElemFreshlyLoaded = false;
}, 700);
} }
}
})();
}
else {
seasonContainer.style.top = `${seasonContainer.dataset.top}px`;
this.minimizeSeasons();
this.hideEpisodes();
this.activeMovieElem.style.display = `block`;
setTimeout(() => {
if (this.activeMovieElem) {
this.activeMovieElem.style.top = `${top + 16}px`;
}
}, 10);
if (this.detailElem && this.detailElem.children[1]) {
const { year } = this.detailElem.children[1].dataset;
if (year) {
this.detailElem.children[1].innerHTML = year;
} }
} }
} }
} }
} });
}); this.seasonsElem.append(seasonContainer);
this.seasonsElem.append(seasonContainer); }
} });
}); lodash.forEach(this.seasonsElem.children, elem => {
lodash.forEach(this.seasonsElem.children, elem => { const seasonElem = elem;
const seasonElem = elem; const left = seasonElem.offsetLeft;
const left = seasonElem.offsetLeft; const topElem = seasonElem.offsetTop;
const topElem = seasonElem.offsetTop; seasonElem.style.left = `${left}px`;
seasonElem.style.left = `${left}px`; seasonElem.dataset.left = `${left}`;
seasonElem.dataset.left = `${left}`; seasonElem.style.top = `${topElem}px`;
seasonElem.style.top = `${topElem}px`; seasonElem.dataset.top = `${topElem}`;
seasonElem.dataset.top = `${topElem}`; });
}); lodash.forEach(this.seasonsElem.children, elem => {
lodash.forEach(this.seasonsElem.children, elem => { const seasonElem = elem;
const seasonElem = elem; seasonElem.style.position = 'absolute';
seasonElem.style.position = 'absolute'; });
}); clearInterval(this.seasonElemFreshlyLoadedTimeout);
clearInterval(this.seasonElemFreshlyLoadedTimeout); this.seasonElemFreshlyLoadedTimeout = setTimeout(() => {
this.seasonElemFreshlyLoadedTimeout = setTimeout(() => { this.seasonElemFreshlyLoaded = false;
this.seasonElemFreshlyLoaded = false; }, 700);
}, 700); clearInterval(this.showSeasonElemTimeout);
clearInterval(this.showSeasonElemTimeout); this.showSeasonElemTimeout = setTimeout(() => {
this.showSeasonElemTimeout = setTimeout(() => { if (this.seasonsElem) {
if (this.seasonsElem) { this.seasonsElem.style.transition = `0.7s`;
this.seasonsElem.style.transition = `0.7s`; this.seasonsElem.style.top = `${top + CSS_STYLE.expandedHeight + 16}px`;
this.seasonsElem.style.top = `${top + CSS_STYLE.expandedHeight + 16}px`; this.resizeBackground();
this.resizeBackground(); }
} }, 200);
}, 200); }
else {
console.log(await this.plex.getDetails(data.key.split('/')[3]));
}
} }
}; };
this.resizeBackground = () => { this.resizeBackground = () => {

@ -90,6 +90,15 @@ class Plex {
return this.exportSectionsData(await Promise.all(sectionsRequests)); return this.exportSectionsData(await Promise.all(sectionsRequests));
}; };
getDetails = async (id: number): Promise<any> => {
const url = `${this.protocol}://${this.ip}:${this.port}/library/metadata/${id}?includeConcerts=1&includeExtras=1&includeOnDeck=1&includePopularLeaves=1&includePreferences=1&includeReviews=1&includeChapters=1&includeStations=1&includeExternalMedia=1&asyncAugmentMetadata=1&asyncCheckFiles=1&asyncRefreshAnalysis=1&asyncRefreshLocalMediaAgent=1&X-Plex-Token=${this.token}`;
return (
await axios.get(url, {
timeout: this.requestTimeout
})
).data.MediaContainer.Metadata[0];
};
getLibraryData = async (id: number): Promise<any> => { getLibraryData = async (id: number): Promise<any> => {
const url = `${this.protocol}://${this.ip}:${this.port}/library/metadata/${id}/children?X-Plex-Token=${this.token}`; const url = `${this.protocol}://${this.ip}:${this.port}/library/metadata/${id}/children?X-Plex-Token=${this.token}`;
return ( return (

@ -526,240 +526,244 @@ class PlexMeetsHomeAssistant extends HTMLElement {
} }
}, 200); }, 200);
} }
if (this.plex && data.childCount > 0) { if (this.plex) {
this.seasonElemFreshlyLoaded = true; if (data.childCount > 0) {
const seasonsData = await this.plex.getLibraryData(data.key.split('/')[3]); this.seasonElemFreshlyLoaded = true;
if (this.seasonsElem) { const seasonsData = await this.plex.getLibraryData(data.key.split('/')[3]);
this.seasonsElem.style.display = 'block';
this.seasonsElem.innerHTML = '';
this.seasonsElem.style.transition = `0s`;
this.seasonsElem.style.top = `${top + 2000}px`;
}
_.forEach(seasonsData, seasonData => {
if (this.seasonsElem) { if (this.seasonsElem) {
this.seasonsElemHidden = false; this.seasonsElem.style.display = 'block';
const seasonContainer = document.createElement('div'); this.seasonsElem.innerHTML = '';
seasonContainer.className = 'seasonContainer'; this.seasonsElem.style.transition = `0s`;
seasonContainer.style.width = `${CSS_STYLE.width}px`; this.seasonsElem.style.top = `${top + 2000}px`;
const thumbURL = `${this.plexProtocol}://${this.config.ip}:${this.config.port}/photo/:/transcode?width=${CSS_STYLE.expandedWidth}&height=${CSS_STYLE.expandedHeight}&minSize=1&upscale=1&url=${seasonData.thumb}&X-Plex-Token=${this.config.token}`; }
const seasonElem = document.createElement('div');
seasonElem.className = 'seasonElem';
seasonElem.style.width = `${CSS_STYLE.width}px`;
seasonElem.style.height = `${CSS_STYLE.height - 3}px`;
seasonElem.style.backgroundImage = `url('${thumbURL}')`;
seasonElem.dataset.clicked = 'false';
if (this.playController && !this.playController.isPlaySupported(seasonData)) {
seasonElem.style.cursor = 'pointer';
}
const interactiveArea = document.createElement('div'); _.forEach(seasonsData, seasonData => {
interactiveArea.className = 'interactiveArea'; if (this.seasonsElem) {
if (seasonData.leafCount - seasonData.viewedLeafCount > 0) { this.seasonsElemHidden = false;
const toViewElem = document.createElement('div'); const seasonContainer = document.createElement('div');
toViewElem.className = 'toViewSeason'; seasonContainer.className = 'seasonContainer';
toViewElem.innerHTML = (seasonData.leafCount - seasonData.viewedLeafCount).toString(); seasonContainer.style.width = `${CSS_STYLE.width}px`;
interactiveArea.appendChild(toViewElem); const thumbURL = `${this.plexProtocol}://${this.config.ip}:${this.config.port}/photo/:/transcode?width=${CSS_STYLE.expandedWidth}&height=${CSS_STYLE.expandedHeight}&minSize=1&upscale=1&url=${seasonData.thumb}&X-Plex-Token=${this.config.token}`;
}
const seasonElem = document.createElement('div');
seasonElem.className = 'seasonElem';
seasonElem.style.width = `${CSS_STYLE.width}px`;
seasonElem.style.height = `${CSS_STYLE.height - 3}px`;
seasonElem.style.backgroundImage = `url('${thumbURL}')`;
seasonElem.dataset.clicked = 'false';
if (this.playController && !this.playController.isPlaySupported(seasonData)) {
seasonElem.style.cursor = 'pointer';
}
if (this.playController && this.playController.isPlaySupported(seasonData)) { const interactiveArea = document.createElement('div');
const playButton = this.getPlayButton(); interactiveArea.className = 'interactiveArea';
playButton.addEventListener('click', event => { if (seasonData.leafCount - seasonData.viewedLeafCount > 0) {
event.stopPropagation(); const toViewElem = document.createElement('div');
if (this.plex && this.playController) { toViewElem.className = 'toViewSeason';
this.playController.play(seasonData, true); toViewElem.innerHTML = (seasonData.leafCount - seasonData.viewedLeafCount).toString();
} interactiveArea.appendChild(toViewElem);
}); }
interactiveArea.append(playButton); if (this.playController && this.playController.isPlaySupported(seasonData)) {
} const playButton = this.getPlayButton();
seasonElem.append(interactiveArea); playButton.addEventListener('click', event => {
seasonContainer.append(seasonElem); event.stopPropagation();
if (this.plex && this.playController) {
const seasonTitleElem = document.createElement('div'); this.playController.play(seasonData, true);
seasonTitleElem.className = 'seasonTitleElem'; }
seasonTitleElem.innerHTML = escapeHtml(seasonData.title); });
seasonContainer.append(seasonTitleElem);
const seasonEpisodesCount = document.createElement('div');
seasonEpisodesCount.className = 'seasonEpisodesCount';
seasonEpisodesCount.innerHTML = `${escapeHtml(seasonData.leafCount)} episodes`;
seasonContainer.append(seasonEpisodesCount);
seasonContainer.addEventListener('click', event => {
event.stopPropagation();
if (this.seasonContainerClickEnabled) {
this.seasonContainerClickEnabled = false;
setTimeout(() => {
this.seasonContainerClickEnabled = true;
}, 500);
if (this.activeMovieElem) {
if (seasonElem.dataset.clicked === 'false') {
if (typeof seasonElem.children[0].children[0] !== 'undefined') {
(seasonElem.children[0].children[0] as HTMLElement).style.display = 'none';
}
seasonElem.dataset.clicked = 'true'; interactiveArea.append(playButton);
this.activeMovieElem.style.top = `${top - 1000}px`; }
setTimeout(() => { seasonElem.append(interactiveArea);
if (this.activeMovieElem) { seasonContainer.append(seasonElem);
this.activeMovieElem.style.display = 'none';
} const seasonTitleElem = document.createElement('div');
}, 500); seasonTitleElem.className = 'seasonTitleElem';
seasonTitleElem.innerHTML = escapeHtml(seasonData.title);
seasonContainer.append(seasonTitleElem);
this.scrollDownInactiveSeasons(); const seasonEpisodesCount = document.createElement('div');
seasonEpisodesCount.className = 'seasonEpisodesCount';
seasonEpisodesCount.innerHTML = `${escapeHtml(seasonData.leafCount)} episodes`;
seasonContainer.append(seasonEpisodesCount);
seasonContainer.style.top = `${-CSS_STYLE.expandedHeight}px`; seasonContainer.addEventListener('click', event => {
seasonElem.style.width = `${CSS_STYLE.expandedWidth}px`; event.stopPropagation();
seasonElem.style.height = `${CSS_STYLE.expandedHeight - 6}px`; if (this.seasonContainerClickEnabled) {
seasonElem.style.zIndex = '3'; this.seasonContainerClickEnabled = false;
setTimeout(() => {
this.seasonContainerClickEnabled = true;
}, 500);
if (this.activeMovieElem) {
if (seasonElem.dataset.clicked === 'false') {
if (typeof seasonElem.children[0].children[0] !== 'undefined') {
(seasonElem.children[0].children[0] as HTMLElement).style.display = 'none';
}
seasonElem.dataset.clicked = 'true';
this.activeMovieElem.style.top = `${top - 1000}px`;
setTimeout(() => {
if (this.activeMovieElem) {
this.activeMovieElem.style.display = 'none';
}
}, 500);
seasonElem.style.marginLeft = `-${getOffset(seasonElem).left - this.scrollDownInactiveSeasons();
getOffset(this.activeMovieElem).left}px`;
seasonTitleElem.style.color = 'rgba(255,255,255,0)'; seasonContainer.style.top = `${-CSS_STYLE.expandedHeight}px`;
seasonEpisodesCount.style.color = 'rgba(255,255,255,0)'; seasonElem.style.width = `${CSS_STYLE.expandedWidth}px`;
seasonElem.style.height = `${CSS_STYLE.expandedHeight - 6}px`;
seasonElem.style.zIndex = '3';
if (this.detailElem) { seasonElem.style.marginLeft = `-${getOffset(seasonElem).left -
(this.detailElem.children[1] as HTMLElement).innerHTML = seasonData.title; getOffset(this.activeMovieElem).left}px`;
}
(async (): Promise<void> => {
if (seasonData.leafCount > 0 && this.plex) {
this.episodesElemFreshlyLoaded = true;
const episodesData = await this.plex.getLibraryData(seasonData.key.split('/')[3]);
if (this.episodesElem) {
this.episodesElemHidden = false;
this.episodesElem.style.display = 'block';
this.episodesElem.innerHTML = '';
this.episodesElem.style.transition = `0s`;
this.episodesElem.style.top = `${top + 2000}px`;
_.forEach(episodesData, episodeData => {
if (this.episodesElem) {
const episodeContainer = document.createElement('div');
episodeContainer.className = 'episodeContainer';
episodeContainer.style.width = `${CSS_STYLE.episodeWidth}px`;
const episodeThumbURL = `${this.plexProtocol}://${this.config.ip}:${this.config.port}/photo/:/transcode?width=${CSS_STYLE.episodeWidth}&height=${CSS_STYLE.episodeHeight}&minSize=1&upscale=1&url=${episodeData.thumb}&X-Plex-Token=${this.config.token}`;
const episodeElem = document.createElement('div');
episodeElem.className = 'episodeElem';
episodeElem.style.width = `${CSS_STYLE.episodeWidth}px`;
episodeElem.style.height = `${CSS_STYLE.episodeHeight}px`;
episodeElem.style.backgroundImage = `url('${episodeThumbURL}')`;
episodeElem.dataset.clicked = 'false';
if (typeof episodeData.lastViewedAt === 'undefined') {
const toViewElem = document.createElement('div');
toViewElem.className = 'toViewEpisode';
episodeElem.appendChild(toViewElem);
}
if (this.playController && this.playController.isPlaySupported(episodeData)) { seasonTitleElem.style.color = 'rgba(255,255,255,0)';
const episodeInteractiveArea = document.createElement('div'); seasonEpisodesCount.style.color = 'rgba(255,255,255,0)';
episodeInteractiveArea.className = 'interactiveArea';
const episodePlayButton = document.createElement('button'); if (this.detailElem) {
episodePlayButton.name = 'playButton'; (this.detailElem.children[1] as HTMLElement).innerHTML = seasonData.title;
episodePlayButton.addEventListener('click', episodeEvent => { }
(async (): Promise<void> => {
if (seasonData.leafCount > 0 && this.plex) {
this.episodesElemFreshlyLoaded = true;
const episodesData = await this.plex.getLibraryData(seasonData.key.split('/')[3]);
if (this.episodesElem) {
this.episodesElemHidden = false;
this.episodesElem.style.display = 'block';
this.episodesElem.innerHTML = '';
this.episodesElem.style.transition = `0s`;
this.episodesElem.style.top = `${top + 2000}px`;
_.forEach(episodesData, episodeData => {
if (this.episodesElem) {
const episodeContainer = document.createElement('div');
episodeContainer.className = 'episodeContainer';
episodeContainer.style.width = `${CSS_STYLE.episodeWidth}px`;
const episodeThumbURL = `${this.plexProtocol}://${this.config.ip}:${this.config.port}/photo/:/transcode?width=${CSS_STYLE.episodeWidth}&height=${CSS_STYLE.episodeHeight}&minSize=1&upscale=1&url=${episodeData.thumb}&X-Plex-Token=${this.config.token}`;
const episodeElem = document.createElement('div');
episodeElem.className = 'episodeElem';
episodeElem.style.width = `${CSS_STYLE.episodeWidth}px`;
episodeElem.style.height = `${CSS_STYLE.episodeHeight}px`;
episodeElem.style.backgroundImage = `url('${episodeThumbURL}')`;
episodeElem.dataset.clicked = 'false';
if (typeof episodeData.lastViewedAt === 'undefined') {
const toViewElem = document.createElement('div');
toViewElem.className = 'toViewEpisode';
episodeElem.appendChild(toViewElem);
}
if (this.playController && this.playController.isPlaySupported(episodeData)) {
const episodeInteractiveArea = document.createElement('div');
episodeInteractiveArea.className = 'interactiveArea';
const episodePlayButton = document.createElement('button');
episodePlayButton.name = 'playButton';
episodePlayButton.addEventListener('click', episodeEvent => {
episodeEvent.stopPropagation();
if (this.plex && this.playController) {
this.playController.play(episodeData, true);
}
});
episodeInteractiveArea.append(episodePlayButton);
episodeElem.append(episodeInteractiveArea);
}
episodeContainer.append(episodeElem);
const episodeTitleElem = document.createElement('div');
episodeTitleElem.className = 'episodeTitleElem';
episodeTitleElem.innerHTML = escapeHtml(episodeData.title);
episodeContainer.append(episodeTitleElem);
const episodeNumber = document.createElement('div');
episodeNumber.className = 'episodeNumber';
episodeNumber.innerHTML = escapeHtml(`Episode ${escapeHtml(episodeData.index)}`);
episodeContainer.append(episodeNumber);
episodeContainer.addEventListener('click', episodeEvent => {
episodeEvent.stopPropagation(); episodeEvent.stopPropagation();
if (this.plex && this.playController) {
this.playController.play(episodeData, true);
}
}); });
episodeInteractiveArea.append(episodePlayButton); this.episodesElem.append(episodeContainer);
episodeElem.append(episodeInteractiveArea); }
});
clearInterval(this.episodesLoadTimeout);
this.episodesLoadTimeout = setTimeout(() => {
if (this.episodesElem) {
this.episodesElem.style.transition = `0.7s`;
this.episodesElem.style.top = `${top + CSS_STYLE.expandedHeight + 16}px`;
this.resizeBackground();
} }
episodeContainer.append(episodeElem); }, 200);
clearInterval(this.episodesElemFreshlyLoadedTimeout);
const episodeTitleElem = document.createElement('div'); this.episodesElemFreshlyLoadedTimeout = setTimeout(() => {
episodeTitleElem.className = 'episodeTitleElem'; this.episodesElemFreshlyLoaded = false;
episodeTitleElem.innerHTML = escapeHtml(episodeData.title); }, 700);
episodeContainer.append(episodeTitleElem); }
const episodeNumber = document.createElement('div');
episodeNumber.className = 'episodeNumber';
episodeNumber.innerHTML = escapeHtml(`Episode ${escapeHtml(episodeData.index)}`);
episodeContainer.append(episodeNumber);
episodeContainer.addEventListener('click', episodeEvent => {
episodeEvent.stopPropagation();
});
this.episodesElem.append(episodeContainer);
}
});
clearInterval(this.episodesLoadTimeout);
this.episodesLoadTimeout = setTimeout(() => {
if (this.episodesElem) {
this.episodesElem.style.transition = `0.7s`;
this.episodesElem.style.top = `${top + CSS_STYLE.expandedHeight + 16}px`;
this.resizeBackground();
}
}, 200);
clearInterval(this.episodesElemFreshlyLoadedTimeout);
this.episodesElemFreshlyLoadedTimeout = setTimeout(() => {
this.episodesElemFreshlyLoaded = false;
}, 700);
} }
} })();
})(); } else {
} else { seasonContainer.style.top = `${seasonContainer.dataset.top}px`;
seasonContainer.style.top = `${seasonContainer.dataset.top}px`; this.minimizeSeasons();
this.minimizeSeasons(); this.hideEpisodes();
this.hideEpisodes(); this.activeMovieElem.style.display = `block`;
this.activeMovieElem.style.display = `block`; setTimeout(() => {
setTimeout(() => { if (this.activeMovieElem) {
if (this.activeMovieElem) { this.activeMovieElem.style.top = `${top + 16}px`;
this.activeMovieElem.style.top = `${top + 16}px`; }
} }, 10);
}, 10);
if (this.detailElem && (this.detailElem.children[1] as HTMLElement)) { if (this.detailElem && (this.detailElem.children[1] as HTMLElement)) {
const { year } = (this.detailElem.children[1] as HTMLElement).dataset; const { year } = (this.detailElem.children[1] as HTMLElement).dataset;
if (year) { if (year) {
(this.detailElem.children[1] as HTMLElement).innerHTML = year; (this.detailElem.children[1] as HTMLElement).innerHTML = year;
}
} }
} }
} }
} }
} });
});
this.seasonsElem.append(seasonContainer); this.seasonsElem.append(seasonContainer);
} }
}); });
_.forEach((this.seasonsElem as HTMLElement).children, elem => { _.forEach((this.seasonsElem as HTMLElement).children, elem => {
const seasonElem = elem as HTMLElement; const seasonElem = elem as HTMLElement;
const left = seasonElem.offsetLeft; const left = seasonElem.offsetLeft;
const topElem = seasonElem.offsetTop; const topElem = seasonElem.offsetTop;
seasonElem.style.left = `${left}px`; seasonElem.style.left = `${left}px`;
seasonElem.dataset.left = `${left}`; seasonElem.dataset.left = `${left}`;
seasonElem.style.top = `${topElem}px`; seasonElem.style.top = `${topElem}px`;
seasonElem.dataset.top = `${topElem}`; seasonElem.dataset.top = `${topElem}`;
}); });
_.forEach((this.seasonsElem as HTMLElement).children, elem => { _.forEach((this.seasonsElem as HTMLElement).children, elem => {
const seasonElem = elem as HTMLElement; const seasonElem = elem as HTMLElement;
seasonElem.style.position = 'absolute'; seasonElem.style.position = 'absolute';
}); });
clearInterval(this.seasonElemFreshlyLoadedTimeout); clearInterval(this.seasonElemFreshlyLoadedTimeout);
this.seasonElemFreshlyLoadedTimeout = setTimeout(() => { this.seasonElemFreshlyLoadedTimeout = setTimeout(() => {
this.seasonElemFreshlyLoaded = false; this.seasonElemFreshlyLoaded = false;
}, 700); }, 700);
clearInterval(this.showSeasonElemTimeout); clearInterval(this.showSeasonElemTimeout);
this.showSeasonElemTimeout = setTimeout(() => { this.showSeasonElemTimeout = setTimeout(() => {
if (this.seasonsElem) { if (this.seasonsElem) {
this.seasonsElem.style.transition = `0.7s`; this.seasonsElem.style.transition = `0.7s`;
this.seasonsElem.style.top = `${top + CSS_STYLE.expandedHeight + 16}px`; this.seasonsElem.style.top = `${top + CSS_STYLE.expandedHeight + 16}px`;
this.resizeBackground(); this.resizeBackground();
} }
}, 200); }, 200);
} else {
console.log(await this.plex.getDetails(data.key.split('/')[3]));
}
} }
}; };

Loading…
Cancel
Save