diff --git a/dist/plex-meets-homeassistant.js b/dist/plex-meets-homeassistant.js index 1dff1ad..a32855b 100644 --- a/dist/plex-meets-homeassistant.js +++ b/dist/plex-meets-homeassistant.js @@ -19157,6 +19157,18 @@ const getOffset = (el) => { } return { top: y, left: x }; }; +const getDetailsBottom = (seasonContainers, episodeContainers, activeElem) => { + const lastSeasonContainer = seasonContainers[seasonContainers.length - 1]; + const lastEpisodeContainer = episodeContainers[episodeContainers.length - 1]; + let detailBottom = false; + if (seasonContainers.length > 0 && parseInt(activeElem.style.top, 10) > 0) { + detailBottom = getHeight(lastSeasonContainer) + parseInt(getOffset(lastSeasonContainer).top, 10) + 10; + } + else if (episodeContainers.length > 0) { + detailBottom = getHeight(lastEpisodeContainer) + parseInt(getOffset(lastEpisodeContainer).top, 10) + 10; + } + return detailBottom; +}; const hasEpisodes = (media) => { let result = false; // eslint-disable-next-line consistent-return @@ -19683,6 +19695,10 @@ style.textContent = css ` top: 0; background-size: cover; } + .stop-scrolling { + height: 100%; + overflow: hidden; + } .contentArt { position: absolute; background-color: rgba(0, 0, 0, 0); @@ -20016,12 +20032,44 @@ class PlexMeetsHomeAssistant extends HTMLElement { }; this.loadInitialData = async () => { window.addEventListener('scroll', () => { - if (this.detailsShown && - this.activeMovieElem && - this.getTop() + 15 < parseInt(this.activeMovieElem.style.top, 10)) { - window.scroll({ - top: getOffset(this.activeMovieElem).top - 80 + // todo: improve performance by calculating this when needed only + if (this.detailsShown && this.activeMovieElem) { + const seasonContainers = this.getElementsByClassName('seasonContainer'); + const episodeContainers = this.getElementsByClassName('episodeContainer'); + const seasonElems = this.getElementsByClassName('seasonElem'); + let activeElem = this.activeMovieElem; + // eslint-disable-next-line consistent-return + lodash.forEach(seasonElems, seasonElem => { + if (lodash.isEqual(seasonElem.dataset.clicked, 'true')) { + activeElem = seasonElem; + return false; + } }); + const detailTop = parseInt(getOffset(activeElem).top, 10) - 70; + const detailBottom = getDetailsBottom(seasonContainers, episodeContainers, activeElem); + console.log(this); + if (this.getTop() < detailTop) { + window.scroll({ + top: detailTop + }); + this.children[0].classList.add('stop-scrolling'); + } + else if (detailBottom) { + if (window.innerHeight < detailBottom - detailTop) { + if (detailBottom && this.getTop() + window.innerHeight > detailBottom) { + window.scroll({ + top: detailBottom - window.innerHeight + }); + this.children[0].classList.add('stop-scrolling'); + } + } + else { + window.scroll({ + top: detailTop + }); + this.children[0].classList.add('stop-scrolling'); + } + } } this.renderNewElementsIfNeeded(); }); diff --git a/src/modules/style.ts b/src/modules/style.ts index 9f7f6cf..26f9b0d 100644 --- a/src/modules/style.ts +++ b/src/modules/style.ts @@ -182,6 +182,10 @@ style.textContent = css` top: 0; background-size: cover; } + .stop-scrolling { + height: 100%; + overflow: hidden; + } .contentArt { position: absolute; background-color: rgba(0, 0, 0, 0); diff --git a/src/modules/utils.ts b/src/modules/utils.ts index be33e1b..598fe36 100644 --- a/src/modules/utils.ts +++ b/src/modules/utils.ts @@ -47,6 +47,23 @@ const getOffset = (el: Element): Record => { return { top: y, left: x }; }; +const getDetailsBottom = ( + seasonContainers: HTMLCollectionOf, + episodeContainers: HTMLCollectionOf, + activeElem: HTMLElement +): number | false => { + const lastSeasonContainer = seasonContainers[seasonContainers.length - 1]; + const lastEpisodeContainer = episodeContainers[episodeContainers.length - 1]; + let detailBottom: number | false = false; + + if (seasonContainers.length > 0 && parseInt(activeElem.style.top, 10) > 0) { + detailBottom = getHeight(lastSeasonContainer) + parseInt(getOffset(lastSeasonContainer).top, 10) + 10; + } else if (episodeContainers.length > 0) { + detailBottom = getHeight(lastEpisodeContainer) + parseInt(getOffset(lastEpisodeContainer).top, 10) + 10; + } + return detailBottom; +}; + const hasEpisodes = (media: Array>): boolean => { let result = false; // eslint-disable-next-line consistent-return @@ -187,5 +204,6 @@ export { isVideoFullScreen, hasEpisodes, getOldPlexServerErrorMessage, - getWidth + getWidth, + getDetailsBottom }; diff --git a/src/plex-meets-homeassistant.ts b/src/plex-meets-homeassistant.ts index 24a91a3..1282dfe 100644 --- a/src/plex-meets-homeassistant.ts +++ b/src/plex-meets-homeassistant.ts @@ -15,7 +15,7 @@ import { isVideoFullScreen, hasEpisodes, getOldPlexServerErrorMessage, - getWidth + getDetailsBottom } from './modules/utils'; import style from './modules/style'; @@ -151,15 +151,45 @@ class PlexMeetsHomeAssistant extends HTMLElement { loadInitialData = async (): Promise => { window.addEventListener('scroll', () => { - if ( - this.detailsShown && - this.activeMovieElem && - this.getTop() + 15 < parseInt(this.activeMovieElem.style.top, 10) - ) { - window.scroll({ - top: getOffset(this.activeMovieElem as Element).top - 80 + // todo: improve performance by calculating this when needed only + if (this.detailsShown && this.activeMovieElem) { + const seasonContainers = this.getElementsByClassName('seasonContainer') as HTMLCollectionOf; + const episodeContainers = this.getElementsByClassName('episodeContainer') as HTMLCollectionOf; + const seasonElems = this.getElementsByClassName('seasonElem') as HTMLCollectionOf; + let activeElem = this.activeMovieElem; + // eslint-disable-next-line consistent-return + _.forEach(seasonElems, seasonElem => { + if (_.isEqual(seasonElem.dataset.clicked, 'true')) { + activeElem = seasonElem; + return false; + } }); + + const detailTop = parseInt(getOffset(activeElem as Element).top, 10) - 70; + const detailBottom = getDetailsBottom(seasonContainers, episodeContainers, activeElem); + console.log(this); + if (this.getTop() < detailTop) { + window.scroll({ + top: detailTop + }); + this.children[0].classList.add('stop-scrolling'); + } else if (detailBottom) { + if (window.innerHeight < detailBottom - detailTop) { + if (detailBottom && this.getTop() + window.innerHeight > detailBottom) { + window.scroll({ + top: detailBottom - window.innerHeight + }); + this.children[0].classList.add('stop-scrolling'); + } + } else { + window.scroll({ + top: detailTop + }); + this.children[0].classList.add('stop-scrolling'); + } + } } + this.renderNewElementsIfNeeded(); }); window.addEventListener('resize', () => {