Add: Episodes view after opening a session

pull/16/head
Juraj Nyíri 4 years ago
parent 1e21d74e35
commit 7c91d91318

@ -18760,7 +18760,9 @@ const CSS_STYLE = {
width: 138, width: 138,
height: 203, height: 203,
expandedWidth: 220, expandedWidth: 220,
expandedHeight: 324 expandedHeight: 324,
episodeWidth: 300,
episodeHeight: 169
}; };
/** /**
@ -19012,12 +19014,21 @@ style.textContent = css `
background: orange; background: orange;
} }
.seasons { .seasons {
z-index: 5;
position: absolute;
top: ${CSS_STYLE.expandedHeight + 16}px;
width: calc(100% - 32px);
left: 0;
padding: 16px;
}
.episodes {
z-index: 4; z-index: 4;
position: absolute; position: absolute;
top: ${CSS_STYLE.expandedHeight + 16}px; top: ${CSS_STYLE.expandedHeight + 16}px;
width: 100%; width: calc(100% - 32px);
left: 0; left: 0;
padding: 16px; padding: 16px;
display: none;
} }
.ratingDetail { .ratingDetail {
background: #ffffff24; background: #ffffff24;
@ -19143,9 +19154,20 @@ style.textContent = css `
margin-top: 5px; margin-top: 5px;
transition: 0.5s; transition: 0.5s;
} }
.episodeTitleElem {
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
position: relative;
font-weight: bold;
margin-top: 5px;
transition: 0.5s;
}
.seasonEpisodesCount { .seasonEpisodesCount {
transition: 0.5s; transition: 0.5s;
} }
.episodeNumber {
}
.titleElem { .titleElem {
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
@ -19159,6 +19181,19 @@ style.textContent = css `
margin-bottom: 15px; margin-bottom: 15px;
transition: 0.5s; transition: 0.5s;
} }
.episodeContainer {
position: relative;
float: left;
margin-right: 16px;
margin-bottom: 15px;
transition: 0.5s;
}
.episodeElem {
background-repeat: no-repeat;
background-size: contain;
border-radius: 5px;
transition: 0.5s;
}
.seasonElem { .seasonElem {
background-repeat: no-repeat; background-repeat: no-repeat;
background-size: contain; background-size: contain;
@ -19259,6 +19294,9 @@ class PlexMeetsHomeAssistant extends HTMLElement {
this.movieElems = []; this.movieElems = [];
this.activeMovieElemData = {}; this.activeMovieElemData = {};
this.seasonElemFreshlyLoaded = false; this.seasonElemFreshlyLoaded = false;
this.episodesElemFreshlyLoaded = false;
this.seasonsElemHidden = true;
this.episodesElemHidden = true;
this.data = {}; this.data = {};
this.config = {}; this.config = {};
this.requestTimeout = 3000; this.requestTimeout = 3000;
@ -19267,6 +19305,7 @@ class PlexMeetsHomeAssistant extends HTMLElement {
this.playSupported = false; this.playSupported = false;
this.error = ''; this.error = '';
this.previousPositions = []; this.previousPositions = [];
this.contentBGHeight = 0;
this.loadInitialData = async () => { this.loadInitialData = async () => {
this.loading = true; this.loading = true;
this.renderPage(); this.renderPage();
@ -19318,6 +19357,8 @@ class PlexMeetsHomeAssistant extends HTMLElement {
} }
if (renderNeeded) { if (renderNeeded) {
this.renderPage(); this.renderPage();
const contentbg = this.getElementsByClassName('contentbg');
this.contentBGHeight = contentbg[0].scrollHeight;
} }
} }
}, 100); }, 100);
@ -19361,6 +19402,13 @@ class PlexMeetsHomeAssistant extends HTMLElement {
this.minimizeAll(); this.minimizeAll();
}); });
this.content.appendChild(this.seasonsElem); this.content.appendChild(this.seasonsElem);
this.episodesElem = document.createElement('div');
this.episodesElem.className = 'episodes';
this.episodesElem.addEventListener('click', () => {
this.hideBackground();
this.minimizeAll();
});
this.content.appendChild(this.episodesElem);
// todo: figure out why timeout is needed here and do it properly // todo: figure out why timeout is needed here and do it properly
setTimeout(() => { setTimeout(() => {
contentbg.addEventListener('click', () => { contentbg.addEventListener('click', () => {
@ -19405,6 +19453,8 @@ class PlexMeetsHomeAssistant extends HTMLElement {
}, 100); }, 100);
}; };
this.minimizeSeasons = () => { this.minimizeSeasons = () => {
return new Promise((resolve, reject) => {
this.seasonsElemHidden = false;
if (this.seasonsElem) { if (this.seasonsElem) {
lodash.forEach(this.seasonsElem.childNodes, child => { lodash.forEach(this.seasonsElem.childNodes, child => {
const seasonElem = child.children[0]; const seasonElem = child.children[0];
@ -19432,10 +19482,12 @@ class PlexMeetsHomeAssistant extends HTMLElement {
else { else {
setTimeout(() => { setTimeout(() => {
moveElem(seasonElem); moveElem(seasonElem);
resolve();
}, 100); }, 100);
} }
}); });
} }
});
}; };
this.minimizeAll = () => { this.minimizeAll = () => {
this.activeMovieElem = undefined; this.activeMovieElem = undefined;
@ -19453,10 +19505,12 @@ class PlexMeetsHomeAssistant extends HTMLElement {
} }
} }
this.hideSeasons(); this.hideSeasons();
this.hideEpisodes();
this.hideDetails(); this.hideDetails();
}; };
this.hideSeasons = () => { this.hideSeasons = () => {
if (this.seasonsElem) { if (this.seasonsElem) {
this.seasonsElemHidden = true;
const doc = document.documentElement; const doc = document.documentElement;
const top = (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0); const top = (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0);
this.seasonsElem.style.top = `${top + 2000}px`; this.seasonsElem.style.top = `${top + 2000}px`;
@ -19464,15 +19518,32 @@ class PlexMeetsHomeAssistant extends HTMLElement {
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';
this.resizeBackground();
}
}, 700);
}
};
this.hideEpisodes = () => {
if (this.episodesElem) {
this.episodesElemHidden = true;
const doc = document.documentElement;
const top = (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0);
this.episodesElem.style.top = `${top + 2000}px`;
setTimeout(() => {
if (this.episodesElem && !this.episodesElemFreshlyLoaded) {
this.episodesElem.innerHTML = '';
this.episodesElem.style.display = 'none';
// fix for a specific case when user scrolls outside of normal home assistant area for seasons look // fix for a specific case when user scrolls outside of normal home assistant area for seasons look
const contentbg = this.getElementsByClassName('contentbg'); console.log('AAA');
contentbg[0].style.height = '100%'; this.resizeBackground();
console.log('BBB');
} }
}, 700); }, 700);
} }
}; };
this.scrollDownInactiveSeasons = () => { this.scrollDownInactiveSeasons = () => {
if (this.seasonsElem) { if (this.seasonsElem) {
this.seasonsElemHidden = true;
lodash.forEach(this.seasonsElem.childNodes, child => { lodash.forEach(this.seasonsElem.childNodes, child => {
const seasonElem = child.children[0]; const seasonElem = child.children[0];
const seasonTitleElem = child.children[1]; const seasonTitleElem = child.children[1];
@ -19547,6 +19618,7 @@ class PlexMeetsHomeAssistant extends HTMLElement {
} }
lodash.forEach(seasonsData, seasonData => { lodash.forEach(seasonsData, seasonData => {
if (this.seasonsElem) { if (this.seasonsElem) {
this.seasonsElemHidden = false;
const seasonContainer = document.createElement('div'); const seasonContainer = document.createElement('div');
seasonContainer.className = 'seasonContainer'; seasonContainer.className = 'seasonContainer';
seasonContainer.style.width = `${CSS_STYLE.width}px`; seasonContainer.style.width = `${CSS_STYLE.width}px`;
@ -19579,6 +19651,7 @@ class PlexMeetsHomeAssistant extends HTMLElement {
seasonEpisodesCount.innerHTML = `${escapeHtml(seasonData.leafCount)} episodes`; seasonEpisodesCount.innerHTML = `${escapeHtml(seasonData.leafCount)} episodes`;
seasonContainer.append(seasonEpisodesCount); seasonContainer.append(seasonEpisodesCount);
seasonContainer.addEventListener('click', event => { seasonContainer.addEventListener('click', event => {
(async () => {
event.stopPropagation(); event.stopPropagation();
if (this.activeMovieElem) { if (this.activeMovieElem) {
if (seasonElem.dataset.clicked === 'false') { if (seasonElem.dataset.clicked === 'false') {
@ -19589,16 +19662,83 @@ class PlexMeetsHomeAssistant extends HTMLElement {
seasonElem.style.width = `${CSS_STYLE.expandedWidth}px`; seasonElem.style.width = `${CSS_STYLE.expandedWidth}px`;
seasonElem.style.height = `${CSS_STYLE.expandedHeight - 6}px`; seasonElem.style.height = `${CSS_STYLE.expandedHeight - 6}px`;
seasonElem.style.zIndex = '3'; seasonElem.style.zIndex = '3';
seasonElem.style.marginLeft = `-${getOffset(seasonElem).left - getOffset(this.activeMovieElem).left}px`; seasonElem.style.marginLeft = `-${getOffset(seasonElem).left -
getOffset(this.activeMovieElem).left}px`;
seasonTitleElem.style.color = 'rgba(255,255,255,0)'; seasonTitleElem.style.color = 'rgba(255,255,255,0)';
seasonEpisodesCount.style.color = 'rgba(255,255,255,0)'; seasonEpisodesCount.style.color = 'rgba(255,255,255,0)';
if (this.detailElem) { if (this.detailElem) {
this.detailElem.children[1].innerHTML = seasonData.title; this.detailElem.children[1].innerHTML = seasonData.title;
} }
(async () => {
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`;
lodash.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';
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.key.split('/')[3]);
}
});
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();
console.log(episodeData);
});
this.episodesElem.append(episodeContainer);
}
});
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 { else {
this.minimizeSeasons(); console.log('A');
this.activeMovieElem.style.top = `16px`; await this.minimizeSeasons();
console.log('B');
this.hideEpisodes();
this.activeMovieElem.style.top = `${top + 16}px`;
if (this.detailElem && this.detailElem.children[1]) { if (this.detailElem && this.detailElem.children[1]) {
const { year } = this.detailElem.children[1].dataset; const { year } = this.detailElem.children[1].dataset;
if (year) { if (year) {
@ -19607,24 +19747,45 @@ class PlexMeetsHomeAssistant extends HTMLElement {
} }
} }
} }
})();
}); });
this.seasonsElem.append(seasonContainer); this.seasonsElem.append(seasonContainer);
}
});
setTimeout(() => { setTimeout(() => {
this.seasonElemFreshlyLoaded = false; this.seasonElemFreshlyLoaded = false;
}, 700); }, 700);
}
});
setTimeout(() => { 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`;
const requiredBodyHeight = parseInt(this.seasonsElem.style.top.replace('px', ''), 10) + this.seasonsElem.scrollHeight; this.resizeBackground();
}
}, 200);
}
};
this.resizeBackground = () => {
if (this.seasonsElem && this.episodesElem) {
const contentbg = this.getElementsByClassName('contentbg'); const contentbg = this.getElementsByClassName('contentbg');
if (requiredBodyHeight > contentbg[0].scrollHeight) { if (this.contentBGHeight === 0) {
contentbg[0].style.height = `${requiredBodyHeight}px`; this.contentBGHeight = contentbg[0].scrollHeight;
} }
const requiredSeasonBodyHeight = parseInt(this.seasonsElem.style.top.replace('px', ''), 10) + this.seasonsElem.scrollHeight;
const requiredEpisodeBodyHeight = parseInt(this.episodesElem.style.top.replace('px', ''), 10) + this.episodesElem.scrollHeight;
console.log(this.seasonsElemHidden);
console.log(this.episodesElemHidden);
if (requiredSeasonBodyHeight > this.contentBGHeight && !this.seasonsElemHidden) {
console.log('1');
contentbg[0].style.height = `${requiredSeasonBodyHeight}px`;
}
else if (requiredEpisodeBodyHeight > this.contentBGHeight && !this.episodesElemHidden) {
console.log('2');
contentbg[0].style.height = `${requiredEpisodeBodyHeight}px`;
}
else {
console.log('3');
contentbg[0].style.height = '100%';
} }
}, 200);
} }
}; };
this.showBackground = () => { this.showBackground = () => {

@ -2,7 +2,9 @@ const CSS_STYLE = {
width: 138, width: 138,
height: 203, height: 203,
expandedWidth: 220, expandedWidth: 220,
expandedHeight: 324 expandedHeight: 324,
episodeWidth: 300,
episodeHeight: 169
}; };
const LOREM_IPSUM = `Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec semper risus vitae aliquet interdum. Nulla facilisi. Pellentesque viverra sagittis lorem eget aliquet. Cras vehicula, purus vel consectetur mattis, ipsum arcu ullamcorper mi, id viverra purus ex eu dolor. Integer vehicula lacinia sem convallis iaculis. Nulla fermentum erat interdum, efficitur felis in, mollis neque. Vivamus luctus metus eget nisl pellentesque, placerat elementum magna eleifend. const LOREM_IPSUM = `Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec semper risus vitae aliquet interdum. Nulla facilisi. Pellentesque viverra sagittis lorem eget aliquet. Cras vehicula, purus vel consectetur mattis, ipsum arcu ullamcorper mi, id viverra purus ex eu dolor. Integer vehicula lacinia sem convallis iaculis. Nulla fermentum erat interdum, efficitur felis in, mollis neque. Vivamus luctus metus eget nisl pellentesque, placerat elementum magna eleifend.

@ -15,12 +15,21 @@ style.textContent = css`
background: orange; background: orange;
} }
.seasons { .seasons {
z-index: 5;
position: absolute;
top: ${CSS_STYLE.expandedHeight + 16}px;
width: calc(100% - 32px);
left: 0;
padding: 16px;
}
.episodes {
z-index: 4; z-index: 4;
position: absolute; position: absolute;
top: ${CSS_STYLE.expandedHeight + 16}px; top: ${CSS_STYLE.expandedHeight + 16}px;
width: 100%; width: calc(100% - 32px);
left: 0; left: 0;
padding: 16px; padding: 16px;
display: none;
} }
.ratingDetail { .ratingDetail {
background: #ffffff24; background: #ffffff24;
@ -146,9 +155,20 @@ style.textContent = css`
margin-top: 5px; margin-top: 5px;
transition: 0.5s; transition: 0.5s;
} }
.episodeTitleElem {
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
position: relative;
font-weight: bold;
margin-top: 5px;
transition: 0.5s;
}
.seasonEpisodesCount { .seasonEpisodesCount {
transition: 0.5s; transition: 0.5s;
} }
.episodeNumber {
}
.titleElem { .titleElem {
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
@ -162,6 +182,19 @@ style.textContent = css`
margin-bottom: 15px; margin-bottom: 15px;
transition: 0.5s; transition: 0.5s;
} }
.episodeContainer {
position: relative;
float: left;
margin-right: 16px;
margin-bottom: 15px;
transition: 0.5s;
}
.episodeElem {
background-repeat: no-repeat;
background-size: contain;
border-radius: 5px;
transition: 0.5s;
}
.seasonElem { .seasonElem {
background-repeat: no-repeat; background-repeat: no-repeat;
background-size: contain; background-size: contain;

@ -23,10 +23,18 @@ class PlexMeetsHomeAssistant extends HTMLElement {
seasonElemFreshlyLoaded = false; seasonElemFreshlyLoaded = false;
episodesElemFreshlyLoaded = false;
detailElem: HTMLElement | undefined; detailElem: HTMLElement | undefined;
seasonsElem: HTMLElement | undefined; seasonsElem: HTMLElement | undefined;
seasonsElemHidden = true;
episodesElem: HTMLElement | undefined;
episodesElemHidden = true;
data: Record<string, any> = {}; data: Record<string, any> = {};
config: Record<string, any> = {}; config: Record<string, any> = {};
@ -47,6 +55,8 @@ class PlexMeetsHomeAssistant extends HTMLElement {
hassObj: HomeAssistant | undefined; hassObj: HomeAssistant | undefined;
contentBGHeight = 0;
set hass(hass: HomeAssistant) { set hass(hass: HomeAssistant) {
this.hassObj = hass; this.hassObj = hass;
if (this.plex) { if (this.plex) {
@ -120,6 +130,8 @@ class PlexMeetsHomeAssistant extends HTMLElement {
} }
if (renderNeeded) { if (renderNeeded) {
this.renderPage(); this.renderPage();
const contentbg = this.getElementsByClassName('contentbg');
this.contentBGHeight = (contentbg[0] as HTMLElement).scrollHeight;
} }
} }
}, 100); }, 100);
@ -174,6 +186,14 @@ class PlexMeetsHomeAssistant extends HTMLElement {
}); });
this.content.appendChild(this.seasonsElem); this.content.appendChild(this.seasonsElem);
this.episodesElem = document.createElement('div');
this.episodesElem.className = 'episodes';
this.episodesElem.addEventListener('click', () => {
this.hideBackground();
this.minimizeAll();
});
this.content.appendChild(this.episodesElem);
// todo: figure out why timeout is needed here and do it properly // todo: figure out why timeout is needed here and do it properly
setTimeout(() => { setTimeout(() => {
contentbg.addEventListener('click', () => { contentbg.addEventListener('click', () => {
@ -218,7 +238,9 @@ class PlexMeetsHomeAssistant extends HTMLElement {
}, 100); }, 100);
}; };
minimizeSeasons = (): void => { minimizeSeasons = (): Promise<void> => {
return new Promise((resolve, reject) => {
this.seasonsElemHidden = false;
if (this.seasonsElem) { if (this.seasonsElem) {
_.forEach(this.seasonsElem.childNodes, child => { _.forEach(this.seasonsElem.childNodes, child => {
const seasonElem = (child as HTMLElement).children[0] as HTMLElement; const seasonElem = (child as HTMLElement).children[0] as HTMLElement;
@ -247,10 +269,12 @@ class PlexMeetsHomeAssistant extends HTMLElement {
} else { } else {
setTimeout(() => { setTimeout(() => {
moveElem(seasonElem); moveElem(seasonElem);
resolve();
}, 100); }, 100);
} }
}); });
} }
});
}; };
minimizeAll = (): void => { minimizeAll = (): void => {
@ -269,11 +293,13 @@ class PlexMeetsHomeAssistant extends HTMLElement {
} }
} }
this.hideSeasons(); this.hideSeasons();
this.hideEpisodes();
this.hideDetails(); this.hideDetails();
}; };
hideSeasons = (): void => { hideSeasons = (): void => {
if (this.seasonsElem) { if (this.seasonsElem) {
this.seasonsElemHidden = true;
const doc = document.documentElement; const doc = document.documentElement;
const top = (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0); const top = (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0);
this.seasonsElem.style.top = `${top + 2000}px`; this.seasonsElem.style.top = `${top + 2000}px`;
@ -281,9 +307,26 @@ class PlexMeetsHomeAssistant extends HTMLElement {
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';
this.resizeBackground();
}
}, 700);
}
};
hideEpisodes = (): void => {
if (this.episodesElem) {
this.episodesElemHidden = true;
const doc = document.documentElement;
const top = (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0);
this.episodesElem.style.top = `${top + 2000}px`;
setTimeout(() => {
if (this.episodesElem && !this.episodesElemFreshlyLoaded) {
this.episodesElem.innerHTML = '';
this.episodesElem.style.display = 'none';
// fix for a specific case when user scrolls outside of normal home assistant area for seasons look // fix for a specific case when user scrolls outside of normal home assistant area for seasons look
const contentbg = this.getElementsByClassName('contentbg'); console.log('AAA');
(contentbg[0] as HTMLElement).style.height = '100%'; this.resizeBackground();
console.log('BBB');
} }
}, 700); }, 700);
} }
@ -291,6 +334,7 @@ class PlexMeetsHomeAssistant extends HTMLElement {
scrollDownInactiveSeasons = (): void => { scrollDownInactiveSeasons = (): void => {
if (this.seasonsElem) { if (this.seasonsElem) {
this.seasonsElemHidden = true;
_.forEach(this.seasonsElem.childNodes, child => { _.forEach(this.seasonsElem.childNodes, child => {
const seasonElem = (child as HTMLElement).children[0] as HTMLElement; const seasonElem = (child as HTMLElement).children[0] as HTMLElement;
const seasonTitleElem = (child as HTMLElement).children[1] as HTMLElement; const seasonTitleElem = (child as HTMLElement).children[1] as HTMLElement;
@ -375,6 +419,7 @@ class PlexMeetsHomeAssistant extends HTMLElement {
_.forEach(seasonsData, seasonData => { _.forEach(seasonsData, seasonData => {
if (this.seasonsElem) { if (this.seasonsElem) {
this.seasonsElemHidden = false;
const seasonContainer = document.createElement('div'); const seasonContainer = document.createElement('div');
seasonContainer.className = 'seasonContainer'; seasonContainer.className = 'seasonContainer';
seasonContainer.style.width = `${CSS_STYLE.width}px`; seasonContainer.style.width = `${CSS_STYLE.width}px`;
@ -414,6 +459,7 @@ class PlexMeetsHomeAssistant extends HTMLElement {
seasonContainer.append(seasonEpisodesCount); seasonContainer.append(seasonEpisodesCount);
seasonContainer.addEventListener('click', event => { seasonContainer.addEventListener('click', event => {
(async (): Promise<void> => {
event.stopPropagation(); event.stopPropagation();
if (this.activeMovieElem) { if (this.activeMovieElem) {
if (seasonElem.dataset.clicked === 'false') { if (seasonElem.dataset.clicked === 'false') {
@ -428,16 +474,93 @@ class PlexMeetsHomeAssistant extends HTMLElement {
seasonElem.style.height = `${CSS_STYLE.expandedHeight - 6}px`; seasonElem.style.height = `${CSS_STYLE.expandedHeight - 6}px`;
seasonElem.style.zIndex = '3'; seasonElem.style.zIndex = '3';
seasonElem.style.marginLeft = `-${getOffset(seasonElem).left - getOffset(this.activeMovieElem).left}px`; seasonElem.style.marginLeft = `-${getOffset(seasonElem).left -
getOffset(this.activeMovieElem).left}px`;
seasonTitleElem.style.color = 'rgba(255,255,255,0)'; seasonTitleElem.style.color = 'rgba(255,255,255,0)';
seasonEpisodesCount.style.color = 'rgba(255,255,255,0)'; seasonEpisodesCount.style.color = 'rgba(255,255,255,0)';
if (this.detailElem) { if (this.detailElem) {
(this.detailElem.children[1] as HTMLElement).innerHTML = seasonData.title; (this.detailElem.children[1] as HTMLElement).innerHTML = seasonData.title;
} }
(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';
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.key.split('/')[3]);
}
});
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();
console.log(episodeData);
});
this.episodesElem.append(episodeContainer);
}
});
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 { } else {
this.minimizeSeasons(); console.log('A');
this.activeMovieElem.style.top = `16px`; await this.minimizeSeasons();
console.log('B');
this.hideEpisodes();
this.activeMovieElem.style.top = `${top + 16}px`;
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) {
@ -446,29 +569,51 @@ class PlexMeetsHomeAssistant extends HTMLElement {
} }
} }
} }
})();
}); });
this.seasonsElem.append(seasonContainer); this.seasonsElem.append(seasonContainer);
}
});
setTimeout(() => { setTimeout(() => {
this.seasonElemFreshlyLoaded = false; this.seasonElemFreshlyLoaded = false;
}, 700); }, 700);
}
});
setTimeout(() => { 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`;
const requiredBodyHeight = this.resizeBackground();
parseInt(this.seasonsElem.style.top.replace('px', ''), 10) + this.seasonsElem.scrollHeight; }
const contentbg = this.getElementsByClassName('contentbg'); }, 200);
}
};
if (requiredBodyHeight > (contentbg[0] as HTMLElement).scrollHeight) { resizeBackground = (): void => {
(contentbg[0] as HTMLElement).style.height = `${requiredBodyHeight}px`; if (this.seasonsElem && this.episodesElem) {
const contentbg = this.getElementsByClassName('contentbg');
if (this.contentBGHeight === 0) {
this.contentBGHeight = (contentbg[0] as HTMLElement).scrollHeight;
} }
const requiredSeasonBodyHeight =
parseInt(this.seasonsElem.style.top.replace('px', ''), 10) + this.seasonsElem.scrollHeight;
const requiredEpisodeBodyHeight =
parseInt(this.episodesElem.style.top.replace('px', ''), 10) + this.episodesElem.scrollHeight;
console.log(this.seasonsElemHidden);
console.log(this.episodesElemHidden);
if (requiredSeasonBodyHeight > this.contentBGHeight && !this.seasonsElemHidden) {
console.log('1');
(contentbg[0] as HTMLElement).style.height = `${requiredSeasonBodyHeight}px`;
} else if (requiredEpisodeBodyHeight > this.contentBGHeight && !this.episodesElemHidden) {
console.log('2');
(contentbg[0] as HTMLElement).style.height = `${requiredEpisodeBodyHeight}px`;
} else {
console.log('3');
(contentbg[0] as HTMLElement).style.height = '100%';
} }
}, 200);
} }
}; };

Loading…
Cancel
Save