Fix: Edge cases where animation could get stuck in incorrect position or rapidly clicking

pull/16/head
Juraj Nyíri 4 years ago
parent 95a83f2e2e
commit 74cef333ee

@ -19457,6 +19457,7 @@ class PlexMeetsHomeAssistant extends HTMLElement {
constructor() { constructor() {
super(...arguments); super(...arguments);
this.plexProtocol = 'http'; this.plexProtocol = 'http';
this.seasonContainerClickEnabled = true;
this.looseSearch = false; this.looseSearch = false;
this.movieElems = []; this.movieElems = [];
this.searchValue = ''; this.searchValue = '';
@ -19673,7 +19674,8 @@ class PlexMeetsHomeAssistant extends HTMLElement {
seasonElemLocal.dataset.clicked = 'false'; seasonElemLocal.dataset.clicked = 'false';
seasonTitleElem.style.display = 'block'; seasonTitleElem.style.display = 'block';
seasonEpisodesCount.style.display = 'block'; seasonEpisodesCount.style.display = 'block';
setTimeout(() => { // clearInterval(this.seasonTitleColorTimeout);
this.seasonTitleColorTimeout = setTimeout(() => {
seasonTitleElem.style.color = 'rgba(255,255,255,1)'; seasonTitleElem.style.color = 'rgba(255,255,255,1)';
seasonEpisodesCount.style.color = 'rgba(255,255,255,1)'; seasonEpisodesCount.style.color = 'rgba(255,255,255,1)';
}, 500); }, 500);
@ -19682,7 +19684,8 @@ class PlexMeetsHomeAssistant extends HTMLElement {
moveElem(seasonElem); moveElem(seasonElem);
} }
else { else {
setTimeout(() => { // clearInterval(this.moveElemTimeout);
this.moveElemTimeout = setTimeout(() => {
moveElem(seasonElem); moveElem(seasonElem);
}, 100); }, 100);
} }
@ -19692,28 +19695,37 @@ class PlexMeetsHomeAssistant extends HTMLElement {
this.minimizeAll = () => { this.minimizeAll = () => {
this.activeMovieElem = undefined; this.activeMovieElem = undefined;
for (let i = 0; i < this.movieElems.length; i += 1) { for (let i = 0; i < this.movieElems.length; i += 1) {
if (this.movieElems[i].dataset.clicked === 'true') { if (parseInt(this.movieElems[i].style.width, 10) > CSS_STYLE.width) {
this.movieElems[i].style.width = `${CSS_STYLE.width}px`; this.movieElems[i].style.width = `${CSS_STYLE.width}px`;
this.movieElems[i].style.height = `${CSS_STYLE.height}px`; this.movieElems[i].style.height = `${CSS_STYLE.height}px`;
this.movieElems[i].style['z-index'] = 1; this.movieElems[i].style['z-index'] = 1;
this.movieElems[i].style.position = 'absolute'; this.movieElems[i].style.position = 'absolute';
this.movieElems[i].style.left = `${this.movieElems[i].dataset.left}px`; this.movieElems[i].style.left = `${this.movieElems[i].dataset.left}px`;
this.movieElems[i].style.top = `${this.movieElems[i].dataset.top}px`; this.movieElems[i].style.top = `${this.movieElems[i].dataset.top}px`;
setTimeout(() => { this.movieElems[i].dataset.clicked = false;
this.movieElems[i].dataset.clicked = false;
}, 500);
} }
} }
this.hideSeasons(); this.hideSeasons();
this.hideEpisodes(); this.hideEpisodes();
this.hideDetails(); this.hideDetails();
clearInterval(this.showDetailsTimeout);
clearInterval(this.showSeasonElemTimeout);
clearInterval(this.seasonTitleColorTimeout);
clearInterval(this.moveElemTimeout);
clearInterval(this.hideSeasonsTimeout);
clearInterval(this.hideEpisodesTimeout);
clearInterval(this.scrollDownInactiveSeasonsTimeout);
clearInterval(this.episodesLoadTimeout);
clearInterval(this.episodesElemFreshlyLoadedTimeout);
clearInterval(this.seasonElemFreshlyLoadedTimeout);
}; };
this.hideSeasons = () => { this.hideSeasons = () => {
if (this.seasonsElem) { if (this.seasonsElem) {
this.seasonsElemHidden = true; this.seasonsElemHidden = true;
const top = this.getTop(); const top = this.getTop();
this.seasonsElem.style.top = `${top + 2000}px`; this.seasonsElem.style.top = `${top + 2000}px`;
setTimeout(() => { clearInterval(this.hideSeasonsTimeout);
this.hideSeasonsTimeout = setTimeout(() => {
if (this.seasonsElem && !this.seasonElemFreshlyLoaded) { if (this.seasonsElem && !this.seasonElemFreshlyLoaded) {
this.seasonsElem.innerHTML = ''; this.seasonsElem.innerHTML = '';
this.seasonsElem.style.display = 'none'; this.seasonsElem.style.display = 'none';
@ -19727,7 +19739,8 @@ class PlexMeetsHomeAssistant extends HTMLElement {
this.episodesElemHidden = true; this.episodesElemHidden = true;
const top = this.getTop(); const top = this.getTop();
this.episodesElem.style.top = `${top + 2000}px`; this.episodesElem.style.top = `${top + 2000}px`;
setTimeout(() => { clearInterval(this.hideEpisodesTimeout);
this.hideEpisodesTimeout = setTimeout(() => {
if (this.episodesElem && !this.episodesElemFreshlyLoaded) { if (this.episodesElem && !this.episodesElemFreshlyLoaded) {
this.episodesElem.innerHTML = ''; this.episodesElem.innerHTML = '';
this.episodesElem.style.display = 'none'; this.episodesElem.style.display = 'none';
@ -19746,7 +19759,7 @@ class PlexMeetsHomeAssistant extends HTMLElement {
if (seasonElem.dataset.clicked === 'false') { if (seasonElem.dataset.clicked === 'false') {
seasonElem.style.marginTop = '1000px'; seasonElem.style.marginTop = '1000px';
seasonElem.style.marginLeft = `0px`; seasonElem.style.marginLeft = `0px`;
setTimeout(() => { this.scrollDownInactiveSeasonsTimeout = setTimeout(() => {
seasonElem.style.display = 'none'; seasonElem.style.display = 'none';
seasonTitleElem.style.display = 'none'; seasonTitleElem.style.display = 'none';
seasonEpisodesCount.style.display = 'none'; seasonEpisodesCount.style.display = 'none';
@ -19769,7 +19782,8 @@ class PlexMeetsHomeAssistant extends HTMLElement {
if (this.detailElem) { if (this.detailElem) {
this.detailElem.style.transition = '0s'; this.detailElem.style.transition = '0s';
this.detailElem.style.top = `${top - 1000}px`; this.detailElem.style.top = `${top - 1000}px`;
setTimeout(() => { clearInterval(this.showDetailsTimeout);
this.showDetailsTimeout = setTimeout(() => {
if (this.detailElem) { if (this.detailElem) {
this.detailElem.style.visibility = 'visible'; this.detailElem.style.visibility = 'visible';
this.detailElem.style.transition = '0.7s'; this.detailElem.style.transition = '0.7s';
@ -19849,95 +19863,104 @@ class PlexMeetsHomeAssistant extends HTMLElement {
seasonContainer.append(seasonEpisodesCount); seasonContainer.append(seasonEpisodesCount);
seasonContainer.addEventListener('click', event => { seasonContainer.addEventListener('click', event => {
event.stopPropagation(); event.stopPropagation();
if (this.activeMovieElem) { if (this.seasonContainerClickEnabled) {
if (seasonElem.dataset.clicked === 'false') { this.seasonContainerClickEnabled = false;
seasonElem.dataset.clicked = 'true'; setTimeout(() => {
this.activeMovieElem.style.top = `${top - 1000}px`; this.seasonContainerClickEnabled = true;
this.scrollDownInactiveSeasons(); }, 500);
seasonContainer.style.top = `${-CSS_STYLE.expandedHeight}px`; if (this.activeMovieElem) {
seasonElem.style.width = `${CSS_STYLE.expandedWidth}px`; if (seasonElem.dataset.clicked === 'false') {
seasonElem.style.height = `${CSS_STYLE.expandedHeight - 6}px`; seasonElem.dataset.clicked = 'true';
seasonElem.style.zIndex = '3'; this.activeMovieElem.style.top = `${top - 1000}px`;
seasonElem.style.marginLeft = `-${getOffset(seasonElem).left - 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 (this.playController && this.playController.isPlaySupported(episodeData)) { const episodeElem = document.createElement('div');
const episodeInteractiveArea = document.createElement('div'); episodeElem.className = 'episodeElem';
episodeInteractiveArea.className = 'interactiveArea'; episodeElem.style.width = `${CSS_STYLE.episodeWidth}px`;
const episodePlayButton = document.createElement('button'); episodeElem.style.height = `${CSS_STYLE.episodeHeight}px`;
episodePlayButton.name = 'playButton'; episodeElem.style.backgroundImage = `url('${episodeThumbURL}')`;
episodePlayButton.addEventListener('click', episodeEvent => { episodeElem.dataset.clicked = 'false';
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.top = `${top + 16}px`;
}); if (this.detailElem && this.detailElem.children[1]) {
setTimeout(() => { const { year } = this.detailElem.children[1].dataset;
if (this.episodesElem) { if (year) {
this.episodesElem.style.transition = `0.7s`; this.detailElem.children[1].innerHTML = year;
this.episodesElem.style.top = `${top + CSS_STYLE.expandedHeight + 16}px`;
this.resizeBackground();
}
}, 200);
setTimeout(() => {
this.episodesElemFreshlyLoaded = false;
}, 700);
} }
}
})();
}
else {
seasonContainer.style.top = `${seasonContainer.dataset.top}px`;
this.minimizeSeasons();
this.hideEpisodes();
this.activeMovieElem.style.top = `${top + 16}px`;
if (this.detailElem && this.detailElem.children[1]) {
const { year } = this.detailElem.children[1].dataset;
if (year) {
this.detailElem.children[1].innerHTML = year;
} }
} }
} }
@ -19959,10 +19982,12 @@ class PlexMeetsHomeAssistant extends HTMLElement {
const seasonElem = elem; const seasonElem = elem;
seasonElem.style.position = 'absolute'; seasonElem.style.position = 'absolute';
}); });
setTimeout(() => { clearInterval(this.seasonElemFreshlyLoadedTimeout);
this.seasonElemFreshlyLoadedTimeout = setTimeout(() => {
this.seasonElemFreshlyLoaded = false; this.seasonElemFreshlyLoaded = false;
}, 700); }, 700);
setTimeout(() => { clearInterval(this.showSeasonElemTimeout);
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`;

@ -13,6 +13,28 @@ class PlexMeetsHomeAssistant extends HTMLElement {
plex: Plex | undefined; plex: Plex | undefined;
seasonContainerClickEnabled = true;
showDetailsTimeout: any;
showSeasonElemTimeout: any;
seasonTitleColorTimeout: any;
moveElemTimeout: any;
hideSeasonsTimeout: any;
hideEpisodesTimeout: any;
scrollDownInactiveSeasonsTimeout: any;
episodesLoadTimeout: any;
episodesElemFreshlyLoadedTimeout: any;
seasonElemFreshlyLoadedTimeout: any;
looseSearch = false; looseSearch = false;
playController: PlayController | undefined; playController: PlayController | undefined;
@ -294,7 +316,8 @@ class PlexMeetsHomeAssistant extends HTMLElement {
seasonElemLocal.dataset.clicked = 'false'; seasonElemLocal.dataset.clicked = 'false';
seasonTitleElem.style.display = 'block'; seasonTitleElem.style.display = 'block';
seasonEpisodesCount.style.display = 'block'; seasonEpisodesCount.style.display = 'block';
setTimeout(() => { // clearInterval(this.seasonTitleColorTimeout);
this.seasonTitleColorTimeout = setTimeout(() => {
seasonTitleElem.style.color = 'rgba(255,255,255,1)'; seasonTitleElem.style.color = 'rgba(255,255,255,1)';
seasonEpisodesCount.style.color = 'rgba(255,255,255,1)'; seasonEpisodesCount.style.color = 'rgba(255,255,255,1)';
}, 500); }, 500);
@ -303,7 +326,8 @@ class PlexMeetsHomeAssistant extends HTMLElement {
if (seasonElem.dataset.clicked === 'true') { if (seasonElem.dataset.clicked === 'true') {
moveElem(seasonElem); moveElem(seasonElem);
} else { } else {
setTimeout(() => { // clearInterval(this.moveElemTimeout);
this.moveElemTimeout = setTimeout(() => {
moveElem(seasonElem); moveElem(seasonElem);
}, 100); }, 100);
} }
@ -314,21 +338,29 @@ class PlexMeetsHomeAssistant extends HTMLElement {
minimizeAll = (): void => { minimizeAll = (): void => {
this.activeMovieElem = undefined; this.activeMovieElem = undefined;
for (let i = 0; i < this.movieElems.length; i += 1) { for (let i = 0; i < this.movieElems.length; i += 1) {
if (this.movieElems[i].dataset.clicked === 'true') { if (parseInt(this.movieElems[i].style.width, 10) > CSS_STYLE.width) {
this.movieElems[i].style.width = `${CSS_STYLE.width}px`; this.movieElems[i].style.width = `${CSS_STYLE.width}px`;
this.movieElems[i].style.height = `${CSS_STYLE.height}px`; this.movieElems[i].style.height = `${CSS_STYLE.height}px`;
this.movieElems[i].style['z-index'] = 1; this.movieElems[i].style['z-index'] = 1;
this.movieElems[i].style.position = 'absolute'; this.movieElems[i].style.position = 'absolute';
this.movieElems[i].style.left = `${this.movieElems[i].dataset.left}px`; this.movieElems[i].style.left = `${this.movieElems[i].dataset.left}px`;
this.movieElems[i].style.top = `${this.movieElems[i].dataset.top}px`; this.movieElems[i].style.top = `${this.movieElems[i].dataset.top}px`;
setTimeout(() => { this.movieElems[i].dataset.clicked = false;
this.movieElems[i].dataset.clicked = false;
}, 500);
} }
} }
this.hideSeasons(); this.hideSeasons();
this.hideEpisodes(); this.hideEpisodes();
this.hideDetails(); this.hideDetails();
clearInterval(this.showDetailsTimeout);
clearInterval(this.showSeasonElemTimeout);
clearInterval(this.seasonTitleColorTimeout);
clearInterval(this.moveElemTimeout);
clearInterval(this.hideSeasonsTimeout);
clearInterval(this.hideEpisodesTimeout);
clearInterval(this.scrollDownInactiveSeasonsTimeout);
clearInterval(this.episodesLoadTimeout);
clearInterval(this.episodesElemFreshlyLoadedTimeout);
clearInterval(this.seasonElemFreshlyLoadedTimeout);
}; };
hideSeasons = (): void => { hideSeasons = (): void => {
@ -336,7 +368,8 @@ class PlexMeetsHomeAssistant extends HTMLElement {
this.seasonsElemHidden = true; this.seasonsElemHidden = true;
const top = this.getTop(); const top = this.getTop();
this.seasonsElem.style.top = `${top + 2000}px`; this.seasonsElem.style.top = `${top + 2000}px`;
setTimeout(() => { clearInterval(this.hideSeasonsTimeout);
this.hideSeasonsTimeout = setTimeout(() => {
if (this.seasonsElem && !this.seasonElemFreshlyLoaded) { if (this.seasonsElem && !this.seasonElemFreshlyLoaded) {
this.seasonsElem.innerHTML = ''; this.seasonsElem.innerHTML = '';
this.seasonsElem.style.display = 'none'; this.seasonsElem.style.display = 'none';
@ -351,7 +384,8 @@ class PlexMeetsHomeAssistant extends HTMLElement {
this.episodesElemHidden = true; this.episodesElemHidden = true;
const top = this.getTop(); const top = this.getTop();
this.episodesElem.style.top = `${top + 2000}px`; this.episodesElem.style.top = `${top + 2000}px`;
setTimeout(() => { clearInterval(this.hideEpisodesTimeout);
this.hideEpisodesTimeout = setTimeout(() => {
if (this.episodesElem && !this.episodesElemFreshlyLoaded) { if (this.episodesElem && !this.episodesElemFreshlyLoaded) {
this.episodesElem.innerHTML = ''; this.episodesElem.innerHTML = '';
this.episodesElem.style.display = 'none'; this.episodesElem.style.display = 'none';
@ -371,7 +405,7 @@ class PlexMeetsHomeAssistant extends HTMLElement {
if (seasonElem.dataset.clicked === 'false') { if (seasonElem.dataset.clicked === 'false') {
seasonElem.style.marginTop = '1000px'; seasonElem.style.marginTop = '1000px';
seasonElem.style.marginLeft = `0px`; seasonElem.style.marginLeft = `0px`;
setTimeout(() => { this.scrollDownInactiveSeasonsTimeout = setTimeout(() => {
seasonElem.style.display = 'none'; seasonElem.style.display = 'none';
seasonTitleElem.style.display = 'none'; seasonTitleElem.style.display = 'none';
seasonEpisodesCount.style.display = 'none'; seasonEpisodesCount.style.display = 'none';
@ -396,8 +430,8 @@ class PlexMeetsHomeAssistant extends HTMLElement {
if (this.detailElem) { if (this.detailElem) {
this.detailElem.style.transition = '0s'; this.detailElem.style.transition = '0s';
this.detailElem.style.top = `${top - 1000}px`; this.detailElem.style.top = `${top - 1000}px`;
clearInterval(this.showDetailsTimeout);
setTimeout(() => { this.showDetailsTimeout = setTimeout(() => {
if (this.detailElem) { if (this.detailElem) {
this.detailElem.style.visibility = 'visible'; this.detailElem.style.visibility = 'visible';
this.detailElem.style.transition = '0.7s'; this.detailElem.style.transition = '0.7s';
@ -492,108 +526,117 @@ class PlexMeetsHomeAssistant extends HTMLElement {
seasonContainer.addEventListener('click', event => { seasonContainer.addEventListener('click', event => {
event.stopPropagation(); event.stopPropagation();
if (this.activeMovieElem) { if (this.seasonContainerClickEnabled) {
if (seasonElem.dataset.clicked === 'false') { this.seasonContainerClickEnabled = false;
seasonElem.dataset.clicked = 'true'; setTimeout(() => {
this.activeMovieElem.style.top = `${top - 1000}px`; this.seasonContainerClickEnabled = true;
}, 500);
this.scrollDownInactiveSeasons(); if (this.activeMovieElem) {
if (seasonElem.dataset.clicked === 'false') {
seasonContainer.style.top = `${-CSS_STYLE.expandedHeight}px`; seasonElem.dataset.clicked = 'true';
seasonElem.style.width = `${CSS_STYLE.expandedWidth}px`; this.activeMovieElem.style.top = `${top - 1000}px`;
seasonElem.style.height = `${CSS_STYLE.expandedHeight - 6}px`;
seasonElem.style.zIndex = '3'; this.scrollDownInactiveSeasons();
seasonElem.style.marginLeft = `-${getOffset(seasonElem).left - getOffset(this.activeMovieElem).left}px`; seasonContainer.style.top = `${-CSS_STYLE.expandedHeight}px`;
seasonElem.style.width = `${CSS_STYLE.expandedWidth}px`;
seasonTitleElem.style.color = 'rgba(255,255,255,0)'; seasonElem.style.height = `${CSS_STYLE.expandedHeight - 6}px`;
seasonEpisodesCount.style.color = 'rgba(255,255,255,0)'; 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> => { seasonTitleElem.style.color = 'rgba(255,255,255,0)';
if (seasonData.leafCount > 0 && this.plex) { seasonEpisodesCount.style.color = 'rgba(255,255,255,0)';
this.episodesElemFreshlyLoaded = true;
const episodesData = await this.plex.getLibraryData(seasonData.key.split('/')[3]); if (this.detailElem) {
if (this.episodesElem) { (this.detailElem.children[1] as HTMLElement).innerHTML = seasonData.title;
this.episodesElemHidden = false; }
this.episodesElem.style.display = 'block'; (async (): Promise<void> => {
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]);
_.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`;
_.forEach(episodesData, episodeData => {
const episodeElem = document.createElement('div'); if (this.episodesElem) {
episodeElem.className = 'episodeElem'; const episodeContainer = document.createElement('div');
episodeElem.style.width = `${CSS_STYLE.episodeWidth}px`; episodeContainer.className = 'episodeContainer';
episodeElem.style.height = `${CSS_STYLE.episodeHeight}px`; episodeContainer.style.width = `${CSS_STYLE.episodeWidth}px`;
episodeElem.style.backgroundImage = `url('${episodeThumbURL}')`; 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}`;
episodeElem.dataset.clicked = 'false';
const episodeElem = document.createElement('div');
if (this.playController && this.playController.isPlaySupported(episodeData)) { episodeElem.className = 'episodeElem';
const episodeInteractiveArea = document.createElement('div'); episodeElem.style.width = `${CSS_STYLE.episodeWidth}px`;
episodeInteractiveArea.className = 'interactiveArea'; episodeElem.style.height = `${CSS_STYLE.episodeHeight}px`;
episodeElem.style.backgroundImage = `url('${episodeThumbURL}')`;
const episodePlayButton = document.createElement('button'); episodeElem.dataset.clicked = 'false';
episodePlayButton.name = 'playButton';
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);
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'; } else {
episodeNumber.innerHTML = escapeHtml(`Episode ${escapeHtml(episodeData.index)}`); seasonContainer.style.top = `${seasonContainer.dataset.top}px`;
episodeContainer.append(episodeNumber); this.minimizeSeasons();
this.hideEpisodes();
episodeContainer.addEventListener('click', episodeEvent => { this.activeMovieElem.style.top = `${top + 16}px`;
episodeEvent.stopPropagation(); if (this.detailElem && (this.detailElem.children[1] as HTMLElement)) {
}); const { year } = (this.detailElem.children[1] as HTMLElement).dataset;
if (year) {
this.episodesElem.append(episodeContainer); (this.detailElem.children[1] as HTMLElement).innerHTML = year;
}
});
setTimeout(() => {
if (this.episodesElem) {
this.episodesElem.style.transition = `0.7s`;
this.episodesElem.style.top = `${top + CSS_STYLE.expandedHeight + 16}px`;
this.resizeBackground();
}
}, 200);
setTimeout(() => {
this.episodesElemFreshlyLoaded = false;
}, 700);
} }
}
})();
} else {
seasonContainer.style.top = `${seasonContainer.dataset.top}px`;
this.minimizeSeasons();
this.hideEpisodes();
this.activeMovieElem.style.top = `${top + 16}px`;
if (this.detailElem && (this.detailElem.children[1] as HTMLElement)) {
const { year } = (this.detailElem.children[1] as HTMLElement).dataset;
if (year) {
(this.detailElem.children[1] as HTMLElement).innerHTML = year;
} }
} }
} }
@ -618,11 +661,13 @@ class PlexMeetsHomeAssistant extends HTMLElement {
seasonElem.style.position = 'absolute'; seasonElem.style.position = 'absolute';
}); });
setTimeout(() => { clearInterval(this.seasonElemFreshlyLoadedTimeout);
this.seasonElemFreshlyLoadedTimeout = setTimeout(() => {
this.seasonElemFreshlyLoaded = false; this.seasonElemFreshlyLoaded = false;
}, 700); }, 700);
setTimeout(() => { clearInterval(this.showSeasonElemTimeout);
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`;

Loading…
Cancel
Save