Add: Bottom and top boundaries for scrolling - includes bug for full height

pull/16/head
Juraj Nyíri 3 years ago
parent e80ae67128
commit 9ad716a42a

@ -19157,6 +19157,18 @@ const getOffset = (el) => {
} }
return { top: y, left: x }; return { top: y, left: x };
}; };
const getDetailsBottom = (seasonContainers, episodeContainers) => {
const lastSeasonContainer = seasonContainers[seasonContainers.length - 1];
const lastEpisodeContainer = episodeContainers[episodeContainers.length - 1];
let detailBottom = false;
if (seasonContainers.length > 0 && parseInt(lastSeasonContainer.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) => { const hasEpisodes = (media) => {
let result = false; let result = false;
// eslint-disable-next-line consistent-return // eslint-disable-next-line consistent-return
@ -20015,25 +20027,29 @@ class PlexMeetsHomeAssistant extends HTMLElement {
}; };
this.loadInitialData = async () => { this.loadInitialData = async () => {
window.addEventListener('scroll', () => { window.addEventListener('scroll', () => {
// todo: improve performance by calculating this when needed only
if (this.detailsShown && this.activeMovieElem) { if (this.detailsShown && this.activeMovieElem) {
if (this.getTop() + 15 < parseInt(this.activeMovieElem.style.top, 10)) { 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;
}
});
if (this.getTop() < parseInt(getOffset(activeElem).top, 10) - 70) {
window.scroll({ window.scroll({
top: getOffset(this.activeMovieElem).top - 80 top: getOffset(activeElem).top - 70
}); });
} }
else { else {
// todo move final bottom value to class to safe performance const detailBottom = getDetailsBottom(seasonContainers, episodeContainers);
// todo: make it work with episodes and extras if (detailBottom && this.getTop() + window.innerHeight > detailBottom) {
const season = this.getElementsByClassName('seasons')[0];
const seasonContainers = this.getElementsByClassName('seasonContainer');
const lastSeasonContainer = seasonContainers[seasonContainers.length - 1];
const seasonContainersBottom = parseInt(lastSeasonContainer.style.top, 10) +
parseInt(season.style.top, 10) +
getHeight(lastSeasonContainer) +
60;
if (this.getTop() + window.innerHeight > seasonContainersBottom) {
window.scroll({ window.scroll({
top: seasonContainersBottom - window.innerHeight top: detailBottom - window.innerHeight
}); });
} }
} }

@ -47,6 +47,22 @@ const getOffset = (el: Element): Record<string, any> => {
return { top: y, left: x }; return { top: y, left: x };
}; };
const getDetailsBottom = (
seasonContainers: HTMLCollectionOf<HTMLElement>,
episodeContainers: HTMLCollectionOf<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(lastSeasonContainer.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<Record<string, any>>): boolean => { const hasEpisodes = (media: Array<Record<string, any>>): boolean => {
let result = false; let result = false;
// eslint-disable-next-line consistent-return // eslint-disable-next-line consistent-return
@ -190,5 +206,6 @@ export {
isVideoFullScreen, isVideoFullScreen,
hasEpisodes, hasEpisodes,
getOldPlexServerErrorMessage, getOldPlexServerErrorMessage,
getWidth getWidth,
getDetailsBottom
}; };

@ -15,7 +15,7 @@ import {
isVideoFullScreen, isVideoFullScreen,
hasEpisodes, hasEpisodes,
getOldPlexServerErrorMessage, getOldPlexServerErrorMessage,
getWidth getDetailsBottom
} from './modules/utils'; } from './modules/utils';
import style from './modules/style'; import style from './modules/style';
@ -149,25 +149,29 @@ class PlexMeetsHomeAssistant extends HTMLElement {
loadInitialData = async (): Promise<void> => { loadInitialData = async (): Promise<void> => {
window.addEventListener('scroll', () => { window.addEventListener('scroll', () => {
// todo: improve performance by calculating this when needed only
if (this.detailsShown && this.activeMovieElem) { if (this.detailsShown && this.activeMovieElem) {
if (this.getTop() + 15 < parseInt(this.activeMovieElem.style.top, 10)) { const seasonContainers = this.getElementsByClassName('seasonContainer') as HTMLCollectionOf<HTMLElement>;
const episodeContainers = this.getElementsByClassName('episodeContainer') as HTMLCollectionOf<HTMLElement>;
const seasonElems = this.getElementsByClassName('seasonElem') as HTMLCollectionOf<HTMLElement>;
let activeElem = this.activeMovieElem;
// eslint-disable-next-line consistent-return
_.forEach(seasonElems, seasonElem => {
if (_.isEqual(seasonElem.dataset.clicked, 'true')) {
activeElem = seasonElem;
return false;
}
});
if (this.getTop() < parseInt(getOffset(activeElem as Element).top, 10) - 70) {
window.scroll({ window.scroll({
top: getOffset(this.activeMovieElem as Element).top - 80 top: getOffset(activeElem as Element).top - 70
}); });
} else { } else {
// todo move final bottom value to class to safe performance const detailBottom = getDetailsBottom(seasonContainers, episodeContainers);
// todo: make it work with episodes and extras if (detailBottom && this.getTop() + window.innerHeight > detailBottom) {
const season = this.getElementsByClassName('seasons')[0] as HTMLElement;
const seasonContainers = this.getElementsByClassName('seasonContainer');
const lastSeasonContainer = seasonContainers[seasonContainers.length - 1] as HTMLElement;
const seasonContainersBottom =
parseInt(lastSeasonContainer.style.top, 10) +
parseInt(season.style.top, 10) +
getHeight(lastSeasonContainer) +
60;
if (this.getTop() + window.innerHeight > seasonContainersBottom) {
window.scroll({ window.scroll({
top: seasonContainersBottom - window.innerHeight top: detailBottom - window.innerHeight
}); });
} }
} }

Loading…
Cancel
Save