Merge pull request #51 from JurajNyiri/3.2

3.2
sonos 3.3
Juraj Nyíri 3 years ago committed by GitHub
commit 468947b6d9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -18815,8 +18815,8 @@ class Plex {
});
return lodash.isNil(collectionsData.data.MediaContainer.Metadata) ? [] : collectionsData.data.MediaContainer.Metadata;
};
this.getSectionData = async (sectionID) => {
return this.exportSectionsData([await this.getSectionDataWithoutProcessing(sectionID)]);
this.getSectionData = async (sectionID, type = false) => {
return this.exportSectionsData([await this.getSectionDataWithoutProcessing(sectionID, type)]);
};
this.getChildren = async (childrenURL) => {
const bulkItems = 50;
@ -18861,10 +18861,14 @@ class Plex {
this.getPlaylistData = async (playlistKey) => {
return this.getChildren(playlistKey);
};
this.getSectionDataWithoutProcessing = async (sectionID) => {
this.getSectionDataWithoutProcessing = async (sectionID, type = false) => {
const bulkItems = 50;
let url = this.authorizeURL(`${this.getBasicURL()}/library/sections/${sectionID}/all`);
url += `&sort=${this.sort}`;
if (type) {
url += `&type=${type}`;
}
url += `&includeCollections=1&includeExternalMedia=1&includeAdvanced=1&includeMeta=1`;
let result = {};
try {
result = await axios.get(url, {
@ -20158,6 +20162,7 @@ class PlexMeetsHomeAssistantEditor extends HTMLElement {
this.protocol = document.createElement('paper-dropdown-menu');
this.tabs = document.createElement('paper-tabs');
this.sort = document.createElement('paper-dropdown-menu');
this.displayType = document.createElement('paper-dropdown-menu');
this.sortOrder = document.createElement('paper-dropdown-menu');
this.playTrailer = document.createElement('paper-dropdown-menu');
this.showExtras = document.createElement('paper-dropdown-menu');
@ -20213,6 +20218,7 @@ class PlexMeetsHomeAssistantEditor extends HTMLElement {
else {
this.config.sort = ``;
}
this.config.displayType = this.displayType.value;
if (lodash.isEmpty(this.maxCount.value)) {
this.config.maxCount = '';
}
@ -20335,10 +20341,14 @@ class PlexMeetsHomeAssistantEditor extends HTMLElement {
}
};
this.render = async () => {
const addDropdownItem = (text, disabled = false) => {
const addDropdownItem = (value, text = '', disabled = false) => {
if (lodash.isEmpty(text)) {
// eslint-disable-next-line no-param-reassign
text = value;
}
const libraryItem = document.createElement('paper-item');
libraryItem.innerHTML = text.replace(/ /g, ' ');
libraryItem.label = text;
libraryItem.label = value;
if (disabled) {
libraryItem.disabled = true;
}
@ -20448,7 +20458,7 @@ class PlexMeetsHomeAssistantEditor extends HTMLElement {
this.content.appendChild(this.token);
this.libraryName.innerHTML = '';
const libraryItems = document.createElement('paper-listbox');
libraryItems.appendChild(addDropdownItem('Smart Libraries', true));
libraryItems.appendChild(addDropdownItem('Smart Libraries', '', true));
libraryItems.appendChild(addDropdownItem('Continue Watching'));
libraryItems.appendChild(addDropdownItem('Deck'));
libraryItems.appendChild(addDropdownItem('Recently Added'));
@ -20554,6 +20564,14 @@ class PlexMeetsHomeAssistantEditor extends HTMLElement {
viewTitle.style.marginBottom = '0px';
viewTitle.style.marginTop = '20px';
this.plexValidSection.appendChild(viewTitle);
this.displayType.innerHTML = '';
const typeItems = document.createElement('paper-listbox');
typeItems.slot = 'dropdown-content';
this.displayType.label = 'Display Type (Optional)';
this.displayType.appendChild(typeItems);
this.displayType.style.width = '100%';
this.displayType.addEventListener('value-changed', this.valueUpdated);
this.plexValidSection.appendChild(this.displayType);
this.cardTitle.label = 'Card title (Optional)';
this.cardTitle.value = this.config.title;
this.cardTitle.addEventListener('change', this.valueUpdated);
@ -20772,7 +20790,7 @@ class PlexMeetsHomeAssistantEditor extends HTMLElement {
this.fontSize4.addEventListener('change', this.valueUpdated);
this.plexValidSection.appendChild(this.fontSize4);
if (!lodash.isEmpty(this.livetv)) {
libraryItems.appendChild(addDropdownItem('Live TV', true));
libraryItems.appendChild(addDropdownItem('Live TV', '', true));
lodash.forEach(lodash.keys(this.livetv), (livetv) => {
if (lodash.isEqual(this.config.libraryName, livetv)) {
warningLibrary.innerHTML = `Warning: ${this.config.libraryName} play action currently only supported with Kodi.<br/>You might also need custom build of kodi-media-sensors, see <a href="https://github.com/JurajNyiri/PlexMeetsHomeAssistant/blob/main/DETAILED_CONFIGURATION.md#kodi" target="_blank">detailed configuration</a> for more information.`;
@ -20781,66 +20799,96 @@ class PlexMeetsHomeAssistantEditor extends HTMLElement {
});
}
if (!lodash.isEmpty(this.sections)) {
libraryItems.appendChild(addDropdownItem('Libraries', true));
libraryItems.appendChild(addDropdownItem('Libraries', '', true));
lodash.forEach(this.sections, (section) => {
libraryItems.appendChild(addDropdownItem(section.title));
});
if (!lodash.isEmpty(this.collections)) {
libraryItems.appendChild(addDropdownItem('Collections', true));
libraryItems.appendChild(addDropdownItem('Collections', '', true));
lodash.forEach(this.collections, (collection) => {
libraryItems.appendChild(addDropdownItem(collection.title));
});
}
if (!lodash.isEmpty(this.playlists)) {
libraryItems.appendChild(addDropdownItem('Playlists', true));
libraryItems.appendChild(addDropdownItem('Playlists', '', true));
lodash.forEach(this.playlists, (playlist) => {
libraryItems.appendChild(addDropdownItem(playlist.title));
});
}
this.libraryName.disabled = false;
this.libraryName.value = this.config.libraryName;
let libraryType = '';
let libraryKey = '';
// eslint-disable-next-line consistent-return
lodash.forEach(this.sections, section => {
if (lodash.isEqual(section.title, this.libraryName.value)) {
libraryType = section.type;
libraryKey = section.key;
return false;
}
});
if (lodash.isEqual(libraryType, 'show')) {
sortItems.appendChild(addDropdownItem('titleSort'));
sortItems.appendChild(addDropdownItem('title'));
sortItems.appendChild(addDropdownItem('year'));
sortItems.appendChild(addDropdownItem('originallyAvailableAt'));
sortItems.appendChild(addDropdownItem('rating'));
sortItems.appendChild(addDropdownItem('audienceRating'));
sortItems.appendChild(addDropdownItem('userRating'));
sortItems.appendChild(addDropdownItem('contentRating'));
sortItems.appendChild(addDropdownItem('unviewedLeafCount'));
sortItems.appendChild(addDropdownItem('episode.addedAt'));
sortItems.appendChild(addDropdownItem('addedAt'));
sortItems.appendChild(addDropdownItem('lastViewedAt'));
this.sort.style.display = 'block';
this.sortOrder.style.display = 'block';
}
else if (lodash.isEqual(libraryType, 'movie')) {
sortItems.appendChild(addDropdownItem('titleSort'));
sortItems.appendChild(addDropdownItem('title'));
sortItems.appendChild(addDropdownItem('originallyAvailableAt'));
sortItems.appendChild(addDropdownItem('rating'));
sortItems.appendChild(addDropdownItem('audienceRating'));
sortItems.appendChild(addDropdownItem('userRating'));
sortItems.appendChild(addDropdownItem('duration'));
sortItems.appendChild(addDropdownItem('viewOffset'));
sortItems.appendChild(addDropdownItem('viewCount'));
sortItems.appendChild(addDropdownItem('addedAt'));
sortItems.appendChild(addDropdownItem('lastViewedAt'));
sortItems.appendChild(addDropdownItem('mediaHeight'));
sortItems.appendChild(addDropdownItem('mediaBitrate'));
this.sort.style.display = 'block';
this.sortOrder.style.display = 'block';
if (!lodash.isEmpty(libraryKey)) {
const libraryData = await this.plex.getSectionData(libraryKey);
const types = lodash.get(libraryData, '[0].Meta.Type');
if (!lodash.isNil(types) && types.length > 1) {
let addedTypes = 0;
typeItems.appendChild(addDropdownItem('', ''));
let typeAvailable = false;
lodash.forEach(types, (sectionType) => {
if (sectionType.type !== 'folder' && sectionType.type !== 'track' && sectionType.type !== 'episode') {
const key = sectionType.key.split('type=')[1];
if (lodash.isEqual(key, this.config.displayType)) {
typeAvailable = true;
}
typeItems.appendChild(addDropdownItem(key, sectionType.title));
addedTypes += 1;
}
});
if (addedTypes > 1) {
this.displayType.style.display = 'block';
if (lodash.isEmpty(this.config.displayType) || !typeAvailable) {
this.displayType.value = '';
}
else {
this.displayType.value = this.config.displayType;
}
}
else {
this.displayType.style.display = 'none';
this.config.displayType = '';
this.displayType.value = '';
}
}
else {
this.displayType.style.display = 'none';
this.config.displayType = '';
this.displayType.value = '';
}
let displayTypeIndex = 0;
if (this.config.displayType) {
lodash.forEach(types, (sectionType, sectionKey) => {
const key = sectionType.key.split('type=')[1];
if (key === parseInt(this.config.displayType, 10)) {
displayTypeIndex = parseInt(sectionKey, 10);
}
});
}
const sortFields = lodash.get(libraryData, `[0].Meta.Type[${displayTypeIndex}].Sort`);
if (!lodash.isNil(sortFields) && sortFields.length > 0) {
lodash.forEach(sortFields, (sortField) => {
sortItems.appendChild(addDropdownItem(sortField.key));
});
this.sort.style.display = 'block';
this.sortOrder.style.display = 'block';
}
else {
this.sort.style.display = 'none';
this.sortOrder.style.display = 'none';
this.config.sort = '';
}
}
else {
this.displayType.style.display = 'none';
this.config.displayType = '';
this.displayType.value = '';
this.sort.style.display = 'none';
this.sortOrder.style.display = 'none';
this.config.sort = '';
@ -20890,6 +20938,9 @@ class PlexMeetsHomeAssistantEditor extends HTMLElement {
if (!config.sort) {
this.config.sort = 'titleSort:asc';
}
if (!config.displayType) {
this.config.displayType = '';
}
if (!lodash.isNil(config.playTrailer)) {
this.config.playTrailer = config.playTrailer;
}
@ -21777,6 +21828,7 @@ class PlexMeetsHomeAssistant extends HTMLElement {
this.renderPageRetries = 0;
this.searchInputElem = document.createElement('input');
this.plexProtocol = 'http';
this.displayType = false;
this.useHorizontalScroll = false;
this.displayTitleMain = true;
this.displaySubtitleMain = true;
@ -22096,7 +22148,7 @@ class PlexMeetsHomeAssistant extends HTMLElement {
this.epgData = await this.plex.getEPG();
}
};
let sectionKey = 0;
let sectionKey = false;
lodash.forEach(plexAllSections, (section) => {
if (lodash.isEqual(section.title, this.config.libraryName)) {
sectionKey = section.key;
@ -22106,7 +22158,7 @@ class PlexMeetsHomeAssistant extends HTMLElement {
});
const loadDataRequests = [];
if (sectionKey) {
loadDataRequests.push(this.plex.getSectionData(sectionKey));
loadDataRequests.push(this.plex.getSectionData(sectionKey, this.displayType));
}
if (lodash.isEqual(this.config.libraryName, 'Deck')) {
loadDataRequests.push(getOnDeck());
@ -22897,7 +22949,7 @@ class PlexMeetsHomeAssistant extends HTMLElement {
if (lodash.isEqual(data.type, 'episode')) {
childrenData = await this.plex.getLibraryData(data.grandparentKey.split('/')[3]);
}
else if (data.childCount > 0 || lodash.isEqual(data.type, 'artist')) {
else if (data.childCount > 0 || lodash.isEqual(data.type, 'artist') || lodash.isEqual(data.type, 'album')) {
childrenData = await this.plex.getLibraryData(data.key.split('/')[3]);
}
let dataDetails = {};
@ -23010,230 +23062,279 @@ class PlexMeetsHomeAssistant extends HTMLElement {
this.seasonsElem.style.transition = `0s`;
this.seasonsElem.style.top = `${top + 2000}px`;
}
lodash.forEach(childrenData, childData => {
if (this.seasonsElem && this.plex) {
this.seasonsElemHidden = false;
const seasonContainer = document.createElement('div');
seasonContainer.className = 'seasonContainer';
seasonContainer.style.width = `${CSS_STYLE.width}px`;
const thumbURL = `${this.plex.getBasicURL()}/photo/:/transcode?width=${this.minExpandedWidth}&height=${this.minExpandedHeight}&minSize=1&upscale=1&url=${childData.thumb}&X-Plex-Token=${this.config.token}`;
const seasonElem = document.createElement('div');
seasonElem.className = 'seasonElem';
seasonElem.style.width = `${CSS_STYLE.width}px`;
if (lodash.isEqual(childData.type, 'album')) {
seasonElem.style.height = `${CSS_STYLE.width}px`;
}
else {
seasonElem.style.height = `${CSS_STYLE.height - 3}px`;
}
seasonElem.style.backgroundImage = `url('${thumbURL}')`;
seasonElem.dataset.clicked = 'false';
if (this.playController && !this.playController.isPlaySupported(childData)) {
seasonElem.style.cursor = 'pointer';
if (lodash.isEqual(lodash.get(childrenData[0], 'type'), 'track')) {
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`;
const tableView = document.createElement('table');
tableView.style.width = 'calc(100% - 10px)';
tableView.style.border = 'none';
tableView.cellSpacing = '0';
tableView.cellPadding = '0';
if (lodash.isEqual(data.type, 'album')) {
this.episodesElem.append(tableView);
}
const interactiveArea = document.createElement('div');
interactiveArea.className = 'interactiveArea';
if (childData.leafCount - childData.viewedLeafCount > 0) {
const toViewElem = document.createElement('div');
toViewElem.className = 'toViewSeason';
toViewElem.innerHTML = (childData.leafCount - childData.viewedLeafCount).toString();
toViewElem.style.fontSize = `${this.fontSize4}px`;
toViewElem.style.lineHeight = `${this.fontSize4}px`;
toViewElem.style.padding = `${this.fontSize4 / 2}px`;
interactiveArea.appendChild(toViewElem);
}
if (this.playController) {
const playButton = this.playController.getPlayButton(childData.type);
if (this.playController.isPlaySupported(childData)) {
playButton.classList.remove('disabled');
}
playButton.addEventListener('click', event => {
event.stopPropagation();
if (this.plex && this.playController) {
this.playController.play(childData, true);
let isEven = false;
lodash.forEach(childrenData, childData => {
if (this.episodesElem && this.playController && this.plex) {
if (lodash.isEqual(childData.type, 'track')) {
tableView.append(createTrackView(this.playController, this.plex, childData, this.fontSize1, this.fontSize2, isEven));
isEven = !isEven;
}
});
interactiveArea.append(playButton);
}
seasonElem.append(interactiveArea);
seasonContainer.append(seasonElem);
const seasonTitleElem = document.createElement('div');
seasonTitleElem.className = 'seasonTitleElem';
seasonTitleElem.innerHTML = escapeHtml(childData.title);
seasonTitleElem.style.fontSize = `${this.fontSize1}px`;
seasonTitleElem.style.lineHeight = `${this.fontSize1}px`;
seasonContainer.append(seasonTitleElem);
const seasonEpisodesCount = document.createElement('div');
seasonEpisodesCount.className = 'seasonEpisodesCount';
if (childData.leafCount > 0) {
seasonEpisodesCount.innerHTML = `${escapeHtml(childData.leafCount)} episodes`;
}
else if (!lodash.isNil(childData.year)) {
seasonEpisodesCount.innerHTML = `${escapeHtml(childData.year)} `;
}
seasonEpisodesCount.style.fontSize = `${this.fontSize2}px`;
seasonEpisodesCount.style.lineHeight = `${this.fontSize2}px`;
seasonContainer.append(seasonEpisodesCount);
seasonContainer.addEventListener('click', event => {
event.stopPropagation();
if (this.seasonContainerClickEnabled) {
this.seasonContainerClickEnabled = false;
setTimeout(() => {
this.seasonContainerClickEnabled = true;
}, 500);
else {
this.episodesElem.append(createEpisodesView(this.playController, this.plex, childData, this.fontSize1, this.fontSize2));
}
}
});
clearInterval(this.episodesLoadTimeout);
this.episodesLoadTimeout = setTimeout(() => {
if (this.episodesElem) {
this.episodesElem.style.transition = `0.7s`;
if (this.activeMovieElem) {
if (seasonElem.dataset.clicked === 'false') {
if (this.playController) {
this.playController.setPlayActionButtonType(childData.type);
this.playController.setPlayButtonClickFunction((thisEvent) => {
thisEvent.preventDefault();
thisEvent.stopPropagation();
if (this.playController) {
this.playController.play(childData, true);
this.episodesElem.style.top = `${top + getHeight(this.activeMovieElem) + 16 * 2}px`;
}
else {
this.episodesElem.style.top = `${top + this.minExpandedHeight + 16}px`;
}
this.resizeBackground();
}
}, 200);
clearInterval(this.episodesElemFreshlyLoadedTimeout);
this.episodesElemFreshlyLoadedTimeout = setTimeout(() => {
this.episodesElemFreshlyLoaded = false;
}, 700);
}
}
else {
lodash.forEach(childrenData, childData => {
if (this.seasonsElem && this.plex) {
console.log(childData);
this.seasonsElemHidden = false;
const seasonContainer = document.createElement('div');
seasonContainer.className = 'seasonContainer';
seasonContainer.style.width = `${CSS_STYLE.width}px`;
const thumbURL = `${this.plex.getBasicURL()}/photo/:/transcode?width=${this.minExpandedWidth}&height=${this.minExpandedHeight}&minSize=1&upscale=1&url=${childData.thumb}&X-Plex-Token=${this.config.token}`;
const seasonElem = document.createElement('div');
seasonElem.className = 'seasonElem';
seasonElem.style.width = `${CSS_STYLE.width}px`;
if (lodash.isEqual(childData.type, 'album')) {
seasonElem.style.height = `${CSS_STYLE.width}px`;
}
else {
seasonElem.style.height = `${CSS_STYLE.height - 3}px`;
}
seasonElem.style.backgroundImage = `url('${thumbURL}')`;
seasonElem.dataset.clicked = 'false';
if (this.playController && !this.playController.isPlaySupported(childData)) {
seasonElem.style.cursor = 'pointer';
}
const interactiveArea = document.createElement('div');
interactiveArea.className = 'interactiveArea';
if (childData.leafCount - childData.viewedLeafCount > 0) {
const toViewElem = document.createElement('div');
toViewElem.className = 'toViewSeason';
toViewElem.innerHTML = (childData.leafCount - childData.viewedLeafCount).toString();
toViewElem.style.fontSize = `${this.fontSize4}px`;
toViewElem.style.lineHeight = `${this.fontSize4}px`;
toViewElem.style.padding = `${this.fontSize4 / 2}px`;
interactiveArea.appendChild(toViewElem);
}
if (this.playController) {
const playButton = this.playController.getPlayButton(childData.type);
if (this.playController.isPlaySupported(childData)) {
playButton.classList.remove('disabled');
}
playButton.addEventListener('click', event => {
event.stopPropagation();
if (this.plex && this.playController) {
this.playController.play(childData, true);
}
});
interactiveArea.append(playButton);
}
seasonElem.append(interactiveArea);
seasonContainer.append(seasonElem);
const seasonTitleElem = document.createElement('div');
seasonTitleElem.className = 'seasonTitleElem';
seasonTitleElem.innerHTML = escapeHtml(childData.title);
seasonTitleElem.style.fontSize = `${this.fontSize1}px`;
seasonTitleElem.style.lineHeight = `${this.fontSize1}px`;
seasonContainer.append(seasonTitleElem);
const seasonEpisodesCount = document.createElement('div');
seasonEpisodesCount.className = 'seasonEpisodesCount';
if (childData.leafCount > 0) {
seasonEpisodesCount.innerHTML = `${escapeHtml(childData.leafCount)} episodes`;
}
else if (!lodash.isNil(childData.year)) {
seasonEpisodesCount.innerHTML = `${escapeHtml(childData.year)} `;
}
seasonEpisodesCount.style.fontSize = `${this.fontSize2}px`;
seasonEpisodesCount.style.lineHeight = `${this.fontSize2}px`;
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 (this.playController) {
this.playController.setPlayActionButtonType(childData.type);
this.playController.setPlayButtonClickFunction((thisEvent) => {
thisEvent.preventDefault();
thisEvent.stopPropagation();
if (this.playController) {
this.playController.play(childData, true);
}
});
}
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';
}
});
}
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(() => {
}, 500);
this.scrollDownInactiveSeasons();
if (this.activeMovieElem) {
this.activeMovieElem.style.display = 'none';
seasonContainer.style.top = `${-getHeight(this.activeMovieElem)}px`;
}
}, 500);
this.scrollDownInactiveSeasons();
if (this.activeMovieElem) {
seasonContainer.style.top = `${-getHeight(this.activeMovieElem)}px`;
}
else {
seasonContainer.style.top = `${-this.minExpandedHeight}px`;
}
seasonElem.dataset.type = childData.type;
seasonElem.style.width = `${this.minExpandedWidth}px`;
if (lodash.isEqual(childData.type, 'album')) {
seasonElem.style.height = `${this.minExpandedWidth}px`;
}
else {
seasonElem.style.height = `${this.minExpandedHeight - 6}px`;
}
seasonElem.style.zIndex = '3';
seasonElem.style.marginLeft = `-${getOffset(seasonElem).left -
getOffset(this.activeMovieElem).left}px`;
seasonTitleElem.style.color = 'rgba(255,255,255,0)';
seasonEpisodesCount.style.color = 'rgba(255,255,255,0)';
if (this.detailElem) {
this.detailElem.children[1].innerHTML = childData.title;
}
(async () => {
if (this.plex && (childData.leafCount > 0 || lodash.isEqual(childData.type, 'album'))) {
this.episodesElemFreshlyLoaded = true;
const episodesData = await this.plex.getLibraryData(childData.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`;
const tableView = document.createElement('table');
tableView.style.width = 'calc(100% - 10px)';
tableView.style.border = 'none';
tableView.cellSpacing = '0';
tableView.cellPadding = '0';
if (lodash.isEqual(childData.type, 'album')) {
this.episodesElem.append(tableView);
}
let isEven = false;
lodash.forEach(episodesData, episodeData => {
if (this.episodesElem && this.playController && this.plex) {
if (lodash.isEqual(episodeData.type, 'track')) {
tableView.append(createTrackView(this.playController, this.plex, episodeData, this.fontSize1, this.fontSize2, isEven));
isEven = !isEven;
}
else {
this.episodesElem.append(createEpisodesView(this.playController, this.plex, episodeData, this.fontSize1, this.fontSize2));
}
else {
seasonContainer.style.top = `${-this.minExpandedHeight}px`;
}
seasonElem.dataset.type = childData.type;
seasonElem.style.width = `${this.minExpandedWidth}px`;
if (lodash.isEqual(childData.type, 'album')) {
seasonElem.style.height = `${this.minExpandedWidth}px`;
}
else {
seasonElem.style.height = `${this.minExpandedHeight - 6}px`;
}
seasonElem.style.zIndex = '3';
seasonElem.style.marginLeft = `-${getOffset(seasonElem).left -
getOffset(this.activeMovieElem).left}px`;
seasonTitleElem.style.color = 'rgba(255,255,255,0)';
seasonEpisodesCount.style.color = 'rgba(255,255,255,0)';
if (this.detailElem) {
this.detailElem.children[1].innerHTML = childData.title;
}
(async () => {
if (this.plex && (childData.leafCount > 0 || lodash.isEqual(childData.type, 'album'))) {
this.episodesElemFreshlyLoaded = true;
const episodesData = await this.plex.getLibraryData(childData.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`;
const tableView = document.createElement('table');
tableView.style.width = 'calc(100% - 10px)';
tableView.style.border = 'none';
tableView.cellSpacing = '0';
tableView.cellPadding = '0';
if (lodash.isEqual(childData.type, 'album')) {
this.episodesElem.append(tableView);
}
});
clearInterval(this.episodesLoadTimeout);
this.episodesLoadTimeout = setTimeout(() => {
if (this.episodesElem) {
this.episodesElem.style.transition = `0.7s`;
if (this.activeMovieElem) {
this.episodesElem.style.top = `${top + getHeight(this.activeMovieElem) + 16 * 2}px`;
let isEven = false;
lodash.forEach(episodesData, episodeData => {
if (this.episodesElem && this.playController && this.plex) {
if (lodash.isEqual(episodeData.type, 'track')) {
tableView.append(createTrackView(this.playController, this.plex, episodeData, this.fontSize1, this.fontSize2, isEven));
isEven = !isEven;
}
else {
this.episodesElem.append(createEpisodesView(this.playController, this.plex, episodeData, this.fontSize1, this.fontSize2));
}
}
else {
this.episodesElem.style.top = `${top + this.minExpandedHeight + 16}px`;
});
clearInterval(this.episodesLoadTimeout);
this.episodesLoadTimeout = setTimeout(() => {
if (this.episodesElem) {
this.episodesElem.style.transition = `0.7s`;
if (this.activeMovieElem) {
this.episodesElem.style.top = `${top + getHeight(this.activeMovieElem) + 16 * 2}px`;
}
else {
this.episodesElem.style.top = `${top + this.minExpandedHeight + 16}px`;
}
this.resizeBackground();
}
this.resizeBackground();
}
}, 200);
clearInterval(this.episodesElemFreshlyLoadedTimeout);
this.episodesElemFreshlyLoadedTimeout = setTimeout(() => {
this.episodesElemFreshlyLoaded = false;
}, 700);
}, 200);
clearInterval(this.episodesElemFreshlyLoadedTimeout);
this.episodesElemFreshlyLoadedTimeout = setTimeout(() => {
this.episodesElemFreshlyLoaded = false;
}, 700);
}
}
}
})();
}
else {
// todo: change title from season and change media type of play button back
if (this.playController) {
this.playController.setPlayActionButtonType(childData.type);
})();
}
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`;
else {
// todo: change title from season and change media type of play button back
if (this.playController) {
this.playController.setPlayActionButtonType(childData.type);
}
}, 10);
if (this.detailElem && this.detailElem.children[1]) {
const { year } = this.detailElem.children[1].dataset;
if (year) {
this.detailElem.children[1].innerHTML = year;
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);
}
});
lodash.forEach(this.seasonsElem.children, elem => {
const seasonElem = elem;
const left = seasonElem.offsetLeft;
const topElem = seasonElem.offsetTop;
seasonElem.style.left = `${left}px`;
seasonElem.dataset.left = `${left}`;
seasonElem.style.top = `${topElem}px`;
seasonElem.dataset.top = `${topElem}`;
});
lodash.forEach(this.seasonsElem.children, elem => {
const seasonElem = elem;
seasonElem.style.position = 'absolute';
});
clearInterval(this.seasonElemFreshlyLoadedTimeout);
this.seasonElemFreshlyLoadedTimeout = setTimeout(() => {
this.seasonElemFreshlyLoaded = false;
}, 700);
clearInterval(this.showSeasonElemTimeout);
this.showSeasonElemTimeout = setTimeout(() => {
if (this.seasonsElem) {
this.seasonsElem.style.transition = `0.7s`;
if (this.activeMovieElem) {
this.seasonsElem.style.top = `${top + getHeight(this.activeMovieElem) + 16 * 2}px`;
});
this.seasonsElem.append(seasonContainer);
}
else {
this.seasonsElem.style.top = `${top + this.minExpandedHeight + 16}px`;
});
lodash.forEach(this.seasonsElem.children, elem => {
const seasonElem = elem;
const left = seasonElem.offsetLeft;
const topElem = seasonElem.offsetTop;
seasonElem.style.left = `${left}px`;
seasonElem.dataset.left = `${left}`;
seasonElem.style.top = `${topElem}px`;
seasonElem.dataset.top = `${topElem}`;
});
lodash.forEach(this.seasonsElem.children, elem => {
const seasonElem = elem;
seasonElem.style.position = 'absolute';
});
clearInterval(this.seasonElemFreshlyLoadedTimeout);
this.seasonElemFreshlyLoadedTimeout = setTimeout(() => {
this.seasonElemFreshlyLoaded = false;
}, 700);
clearInterval(this.showSeasonElemTimeout);
this.showSeasonElemTimeout = setTimeout(() => {
if (this.seasonsElem) {
this.seasonsElem.style.transition = `0.7s`;
if (this.activeMovieElem) {
this.seasonsElem.style.top = `${top + getHeight(this.activeMovieElem) + 16 * 2}px`;
}
else {
this.seasonsElem.style.top = `${top + this.minExpandedHeight + 16}px`;
}
this.resizeBackground();
}
this.resizeBackground();
}
}, 200);
}, 200);
}
}
else {
this.episodesElemFreshlyLoaded = true;
@ -23384,8 +23485,8 @@ class PlexMeetsHomeAssistant extends HTMLElement {
movieElem.className = 'movieElem';
movieElem.style.width = `${CSS_STYLE.width}px`;
movieElem.style.height = `${CSS_STYLE.height}px`;
if (!lodash.isNil(data.channelCallSign) || lodash.isEqual(data.type, 'artist')) {
if (!lodash.isEqual(data.type, 'artist')) {
if (!lodash.isNil(data.channelCallSign) || lodash.isEqual(data.type, 'artist') || lodash.isEqual(data.type, 'album')) {
if (!lodash.isEqual(data.type, 'artist') && !lodash.isEqual(data.type, 'album')) {
movieElem.style.backgroundSize = '80%';
}
movieElem.style.backgroundColor = 'rgba(0,0,0,0.2)';
@ -23536,6 +23637,9 @@ class PlexMeetsHomeAssistant extends HTMLElement {
if (config.protocol) {
this.plexProtocol = config.protocol;
}
if (config.displayType && !lodash.isEmpty(config.displayType)) {
this.displayType = config.displayType;
}
if (config.useHorizontalScroll && lodash.isEqual(config.useHorizontalScroll, 'Yes')) {
this.useHorizontalScroll = true;
}

@ -58,6 +58,8 @@ class PlexMeetsHomeAssistantEditor extends HTMLElement {
sort: any = document.createElement('paper-dropdown-menu');
displayType: any = document.createElement('paper-dropdown-menu');
sortOrder: any = document.createElement('paper-dropdown-menu');
playTrailer: any = document.createElement('paper-dropdown-menu');
@ -139,6 +141,8 @@ class PlexMeetsHomeAssistantEditor extends HTMLElement {
this.config.sort = ``;
}
this.config.displayType = this.displayType.value;
if (_.isEmpty(this.maxCount.value)) {
this.config.maxCount = '';
} else {
@ -258,10 +262,14 @@ class PlexMeetsHomeAssistantEditor extends HTMLElement {
};
render = async (): Promise<void> => {
const addDropdownItem = (text: string, disabled = false): HTMLElement => {
const addDropdownItem = (value: string, text = '', disabled = false): HTMLElement => {
if (_.isEmpty(text)) {
// eslint-disable-next-line no-param-reassign
text = value;
}
const libraryItem: any = document.createElement('paper-item');
libraryItem.innerHTML = text.replace(/ /g, '&nbsp;');
libraryItem.label = text;
libraryItem.label = value;
if (disabled) {
libraryItem.disabled = true;
}
@ -381,7 +389,7 @@ class PlexMeetsHomeAssistantEditor extends HTMLElement {
this.libraryName.innerHTML = '';
const libraryItems: any = document.createElement('paper-listbox');
libraryItems.appendChild(addDropdownItem('Smart Libraries', true));
libraryItems.appendChild(addDropdownItem('Smart Libraries', '', true));
libraryItems.appendChild(addDropdownItem('Continue Watching'));
libraryItems.appendChild(addDropdownItem('Deck'));
libraryItems.appendChild(addDropdownItem('Recently Added'));
@ -396,6 +404,7 @@ class PlexMeetsHomeAssistantEditor extends HTMLElement {
const warningLibrary = document.createElement('div');
warningLibrary.style.color = 'red';
this.content.appendChild(this.libraryName);
this.content.appendChild(warningLibrary);
this.appendChild(this.content);
@ -500,6 +509,15 @@ class PlexMeetsHomeAssistantEditor extends HTMLElement {
viewTitle.style.marginTop = '20px';
this.plexValidSection.appendChild(viewTitle);
this.displayType.innerHTML = '';
const typeItems: any = document.createElement('paper-listbox');
typeItems.slot = 'dropdown-content';
this.displayType.label = 'Display Type (Optional)';
this.displayType.appendChild(typeItems);
this.displayType.style.width = '100%';
this.displayType.addEventListener('value-changed', this.valueUpdated);
this.plexValidSection.appendChild(this.displayType);
this.cardTitle.label = 'Card title (Optional)';
this.cardTitle.value = this.config.title;
this.cardTitle.addEventListener('change', this.valueUpdated);
@ -734,7 +752,7 @@ class PlexMeetsHomeAssistantEditor extends HTMLElement {
this.plexValidSection.appendChild(this.fontSize4);
if (!_.isEmpty(this.livetv)) {
libraryItems.appendChild(addDropdownItem('Live TV', true));
libraryItems.appendChild(addDropdownItem('Live TV', '', true));
_.forEach(_.keys(this.livetv), (livetv: string) => {
if (_.isEqual(this.config.libraryName, livetv)) {
warningLibrary.innerHTML = `Warning: ${this.config.libraryName} play action currently only supported with Kodi.<br/>You might also need custom build of kodi-media-sensors, see <a href="https://github.com/JurajNyiri/PlexMeetsHomeAssistant/blob/main/DETAILED_CONFIGURATION.md#kodi" target="_blank">detailed configuration</a> for more information.`;
@ -743,18 +761,18 @@ class PlexMeetsHomeAssistantEditor extends HTMLElement {
});
}
if (!_.isEmpty(this.sections)) {
libraryItems.appendChild(addDropdownItem('Libraries', true));
libraryItems.appendChild(addDropdownItem('Libraries', '', true));
_.forEach(this.sections, (section: Record<string, any>) => {
libraryItems.appendChild(addDropdownItem(section.title));
});
if (!_.isEmpty(this.collections)) {
libraryItems.appendChild(addDropdownItem('Collections', true));
libraryItems.appendChild(addDropdownItem('Collections', '', true));
_.forEach(this.collections, (collection: Record<string, any>) => {
libraryItems.appendChild(addDropdownItem(collection.title));
});
}
if (!_.isEmpty(this.playlists)) {
libraryItems.appendChild(addDropdownItem('Playlists', true));
libraryItems.appendChild(addDropdownItem('Playlists', '', true));
_.forEach(this.playlists, (playlist: Record<string, any>) => {
libraryItems.appendChild(addDropdownItem(playlist.title));
});
@ -763,46 +781,75 @@ class PlexMeetsHomeAssistantEditor extends HTMLElement {
this.libraryName.disabled = false;
this.libraryName.value = this.config.libraryName;
let libraryType = '';
let libraryKey = '';
// eslint-disable-next-line consistent-return
_.forEach(this.sections, section => {
if (_.isEqual(section.title, this.libraryName.value)) {
libraryType = section.type;
libraryKey = section.key;
return false;
}
});
if (_.isEqual(libraryType, 'show')) {
sortItems.appendChild(addDropdownItem('titleSort'));
sortItems.appendChild(addDropdownItem('title'));
sortItems.appendChild(addDropdownItem('year'));
sortItems.appendChild(addDropdownItem('originallyAvailableAt'));
sortItems.appendChild(addDropdownItem('rating'));
sortItems.appendChild(addDropdownItem('audienceRating'));
sortItems.appendChild(addDropdownItem('userRating'));
sortItems.appendChild(addDropdownItem('contentRating'));
sortItems.appendChild(addDropdownItem('unviewedLeafCount'));
sortItems.appendChild(addDropdownItem('episode.addedAt'));
sortItems.appendChild(addDropdownItem('addedAt'));
sortItems.appendChild(addDropdownItem('lastViewedAt'));
this.sort.style.display = 'block';
this.sortOrder.style.display = 'block';
} else if (_.isEqual(libraryType, 'movie')) {
sortItems.appendChild(addDropdownItem('titleSort'));
sortItems.appendChild(addDropdownItem('title'));
sortItems.appendChild(addDropdownItem('originallyAvailableAt'));
sortItems.appendChild(addDropdownItem('rating'));
sortItems.appendChild(addDropdownItem('audienceRating'));
sortItems.appendChild(addDropdownItem('userRating'));
sortItems.appendChild(addDropdownItem('duration'));
sortItems.appendChild(addDropdownItem('viewOffset'));
sortItems.appendChild(addDropdownItem('viewCount'));
sortItems.appendChild(addDropdownItem('addedAt'));
sortItems.appendChild(addDropdownItem('lastViewedAt'));
sortItems.appendChild(addDropdownItem('mediaHeight'));
sortItems.appendChild(addDropdownItem('mediaBitrate'));
this.sort.style.display = 'block';
this.sortOrder.style.display = 'block';
if (!_.isEmpty(libraryKey)) {
const libraryData = await this.plex.getSectionData(libraryKey);
const types = _.get(libraryData, '[0].Meta.Type');
if (!_.isNil(types) && types.length > 1) {
let addedTypes = 0;
typeItems.appendChild(addDropdownItem('', ''));
let typeAvailable = false;
_.forEach(types, (sectionType: Record<string, any>) => {
if (sectionType.type !== 'folder' && sectionType.type !== 'track' && sectionType.type !== 'episode') {
const key = sectionType.key.split('type=')[1];
if (_.isEqual(key, this.config.displayType)) {
typeAvailable = true;
}
typeItems.appendChild(addDropdownItem(key, sectionType.title));
addedTypes += 1;
}
});
if (addedTypes > 1) {
this.displayType.style.display = 'block';
if (_.isEmpty(this.config.displayType) || !typeAvailable) {
this.displayType.value = '';
} else {
this.displayType.value = this.config.displayType;
}
} else {
this.displayType.style.display = 'none';
this.config.displayType = '';
this.displayType.value = '';
}
} else {
this.displayType.style.display = 'none';
this.config.displayType = '';
this.displayType.value = '';
}
let displayTypeIndex = 0;
if (this.config.displayType) {
_.forEach(types, (sectionType: Record<string, any>, sectionKey) => {
const key = sectionType.key.split('type=')[1];
if (key === parseInt(this.config.displayType, 10)) {
displayTypeIndex = parseInt(sectionKey, 10);
}
});
}
const sortFields = _.get(libraryData, `[0].Meta.Type[${displayTypeIndex}].Sort`);
if (!_.isNil(sortFields) && sortFields.length > 0) {
_.forEach(sortFields, (sortField: Record<string, any>) => {
sortItems.appendChild(addDropdownItem(sortField.key));
});
this.sort.style.display = 'block';
this.sortOrder.style.display = 'block';
} else {
this.sort.style.display = 'none';
this.sortOrder.style.display = 'none';
this.config.sort = '';
}
} else {
this.displayType.style.display = 'none';
this.config.displayType = '';
this.displayType.value = '';
this.sort.style.display = 'none';
this.sortOrder.style.display = 'none';
this.config.sort = '';
@ -853,6 +900,10 @@ class PlexMeetsHomeAssistantEditor extends HTMLElement {
this.config.sort = 'titleSort:asc';
}
if (!config.displayType) {
this.config.displayType = '';
}
if (!_.isNil(config.playTrailer)) {
this.config.playTrailer = config.playTrailer;
} else {

@ -197,8 +197,8 @@ class Plex {
return _.isNil(collectionsData.data.MediaContainer.Metadata) ? [] : collectionsData.data.MediaContainer.Metadata;
};
getSectionData = async (sectionID: number): Promise<any> => {
return this.exportSectionsData([await this.getSectionDataWithoutProcessing(sectionID)]);
getSectionData = async (sectionID: string, type: string | false = false): Promise<any> => {
return this.exportSectionsData([await this.getSectionDataWithoutProcessing(sectionID, type)]);
};
private getChildren = async (childrenURL: string): Promise<any> => {
@ -257,10 +257,14 @@ class Plex {
return this.getChildren(playlistKey);
};
private getSectionDataWithoutProcessing = async (sectionID: number): Promise<any> => {
private getSectionDataWithoutProcessing = async (sectionID: string, type: string | false = false): Promise<any> => {
const bulkItems = 50;
let url = this.authorizeURL(`${this.getBasicURL()}/library/sections/${sectionID}/all`);
url += `&sort=${this.sort}`;
if (type) {
url += `&type=${type}`;
}
url += `&includeCollections=1&includeExternalMedia=1&includeAdvanced=1&includeMeta=1`;
let result: Record<string, any> = {};
try {
result = await axios.get(url, {

@ -37,6 +37,8 @@ class PlexMeetsHomeAssistant extends HTMLElement {
plexProtocol: 'http' | 'https' = 'http';
displayType: string | false = false;
useHorizontalScroll = false;
displayTitleMain = true;
@ -469,7 +471,7 @@ class PlexMeetsHomeAssistant extends HTMLElement {
}
};
let sectionKey: number | false = 0;
let sectionKey: string | false = false;
_.forEach(plexAllSections, (section: Record<string, any>) => {
if (_.isEqual(section.title, this.config.libraryName)) {
sectionKey = section.key;
@ -479,7 +481,7 @@ class PlexMeetsHomeAssistant extends HTMLElement {
});
const loadDataRequests = [];
if (sectionKey) {
loadDataRequests.push(this.plex.getSectionData(sectionKey));
loadDataRequests.push(this.plex.getSectionData(sectionKey, this.displayType));
}
if (_.isEqual(this.config.libraryName, 'Deck')) {
loadDataRequests.push(getOnDeck());
@ -1338,7 +1340,7 @@ class PlexMeetsHomeAssistant extends HTMLElement {
let childrenData: Record<string, any> = {};
if (_.isEqual(data.type, 'episode')) {
childrenData = await this.plex.getLibraryData(data.grandparentKey.split('/')[3]);
} else if (data.childCount > 0 || _.isEqual(data.type, 'artist')) {
} else if (data.childCount > 0 || _.isEqual(data.type, 'artist') || _.isEqual(data.type, 'album')) {
childrenData = await this.plex.getLibraryData(data.key.split('/')[3]);
}
let dataDetails: Record<string, any> = {};
@ -1460,268 +1462,319 @@ class PlexMeetsHomeAssistant extends HTMLElement {
this.seasonsElem.style.top = `${top + 2000}px`;
}
_.forEach(childrenData, childData => {
if (this.seasonsElem && this.plex) {
this.seasonsElemHidden = false;
const seasonContainer = document.createElement('div');
seasonContainer.className = 'seasonContainer';
seasonContainer.style.width = `${CSS_STYLE.width}px`;
const thumbURL = `${this.plex.getBasicURL()}/photo/:/transcode?width=${this.minExpandedWidth}&height=${
this.minExpandedHeight
}&minSize=1&upscale=1&url=${childData.thumb}&X-Plex-Token=${this.config.token}`;
const seasonElem = document.createElement('div');
seasonElem.className = 'seasonElem';
seasonElem.style.width = `${CSS_STYLE.width}px`;
if (_.isEqual(childData.type, 'album')) {
seasonElem.style.height = `${CSS_STYLE.width}px`;
} else {
seasonElem.style.height = `${CSS_STYLE.height - 3}px`;
if (_.isEqual(_.get(childrenData[0], 'type'), 'track')) {
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`;
const tableView = document.createElement('table');
tableView.style.width = 'calc(100% - 10px)';
tableView.style.border = 'none';
tableView.cellSpacing = '0';
tableView.cellPadding = '0';
if (_.isEqual(data.type, 'album')) {
this.episodesElem.append(tableView);
}
let isEven = false;
_.forEach(childrenData, childData => {
if (this.episodesElem && this.playController && this.plex) {
if (_.isEqual(childData.type, 'track')) {
tableView.append(
createTrackView(this.playController, this.plex, childData, this.fontSize1, this.fontSize2, isEven)
);
isEven = !isEven;
} else {
this.episodesElem.append(
createEpisodesView(this.playController, this.plex, childData, this.fontSize1, this.fontSize2)
);
}
}
});
clearInterval(this.episodesLoadTimeout);
this.episodesLoadTimeout = setTimeout(() => {
if (this.episodesElem) {
this.episodesElem.style.transition = `0.7s`;
if (this.activeMovieElem) {
this.episodesElem.style.top = `${top + getHeight(this.activeMovieElem) + 16 * 2}px`;
} else {
this.episodesElem.style.top = `${top + this.minExpandedHeight + 16}px`;
}
seasonElem.style.backgroundImage = `url('${thumbURL}')`;
seasonElem.dataset.clicked = 'false';
this.resizeBackground();
}
}, 200);
clearInterval(this.episodesElemFreshlyLoadedTimeout);
this.episodesElemFreshlyLoadedTimeout = setTimeout(() => {
this.episodesElemFreshlyLoaded = false;
}, 700);
}
} else {
_.forEach(childrenData, childData => {
if (this.seasonsElem && this.plex) {
console.log(childData);
this.seasonsElemHidden = false;
const seasonContainer = document.createElement('div');
seasonContainer.className = 'seasonContainer';
seasonContainer.style.width = `${CSS_STYLE.width}px`;
const thumbURL = `${this.plex.getBasicURL()}/photo/:/transcode?width=${this.minExpandedWidth}&height=${
this.minExpandedHeight
}&minSize=1&upscale=1&url=${childData.thumb}&X-Plex-Token=${this.config.token}`;
const seasonElem = document.createElement('div');
seasonElem.className = 'seasonElem';
seasonElem.style.width = `${CSS_STYLE.width}px`;
if (_.isEqual(childData.type, 'album')) {
seasonElem.style.height = `${CSS_STYLE.width}px`;
} else {
seasonElem.style.height = `${CSS_STYLE.height - 3}px`;
}
if (this.playController && !this.playController.isPlaySupported(childData)) {
seasonElem.style.cursor = 'pointer';
}
seasonElem.style.backgroundImage = `url('${thumbURL}')`;
seasonElem.dataset.clicked = 'false';
const interactiveArea = document.createElement('div');
interactiveArea.className = 'interactiveArea';
if (childData.leafCount - childData.viewedLeafCount > 0) {
const toViewElem = document.createElement('div');
toViewElem.className = 'toViewSeason';
toViewElem.innerHTML = (childData.leafCount - childData.viewedLeafCount).toString();
if (this.playController && !this.playController.isPlaySupported(childData)) {
seasonElem.style.cursor = 'pointer';
}
toViewElem.style.fontSize = `${this.fontSize4}px`;
toViewElem.style.lineHeight = `${this.fontSize4}px`;
toViewElem.style.padding = `${this.fontSize4 / 2}px`;
const interactiveArea = document.createElement('div');
interactiveArea.className = 'interactiveArea';
if (childData.leafCount - childData.viewedLeafCount > 0) {
const toViewElem = document.createElement('div');
toViewElem.className = 'toViewSeason';
toViewElem.innerHTML = (childData.leafCount - childData.viewedLeafCount).toString();
interactiveArea.appendChild(toViewElem);
}
toViewElem.style.fontSize = `${this.fontSize4}px`;
toViewElem.style.lineHeight = `${this.fontSize4}px`;
toViewElem.style.padding = `${this.fontSize4 / 2}px`;
if (this.playController) {
const playButton = this.playController.getPlayButton(childData.type);
if (this.playController.isPlaySupported(childData)) {
playButton.classList.remove('disabled');
interactiveArea.appendChild(toViewElem);
}
playButton.addEventListener('click', event => {
event.stopPropagation();
if (this.plex && this.playController) {
this.playController.play(childData, true);
if (this.playController) {
const playButton = this.playController.getPlayButton(childData.type);
if (this.playController.isPlaySupported(childData)) {
playButton.classList.remove('disabled');
}
});
playButton.addEventListener('click', event => {
event.stopPropagation();
if (this.plex && this.playController) {
this.playController.play(childData, true);
}
});
interactiveArea.append(playButton);
}
interactiveArea.append(playButton);
}
seasonElem.append(interactiveArea);
seasonContainer.append(seasonElem);
const seasonTitleElem = document.createElement('div');
seasonTitleElem.className = 'seasonTitleElem';
seasonTitleElem.innerHTML = escapeHtml(childData.title);
seasonTitleElem.style.fontSize = `${this.fontSize1}px`;
seasonTitleElem.style.lineHeight = `${this.fontSize1}px`;
seasonContainer.append(seasonTitleElem);
const seasonEpisodesCount = document.createElement('div');
seasonEpisodesCount.className = 'seasonEpisodesCount';
if (childData.leafCount > 0) {
seasonEpisodesCount.innerHTML = `${escapeHtml(childData.leafCount)} episodes`;
} else if (!_.isNil(childData.year)) {
seasonEpisodesCount.innerHTML = `${escapeHtml(childData.year)} `;
}
seasonElem.append(interactiveArea);
seasonContainer.append(seasonElem);
const seasonTitleElem = document.createElement('div');
seasonTitleElem.className = 'seasonTitleElem';
seasonTitleElem.innerHTML = escapeHtml(childData.title);
seasonTitleElem.style.fontSize = `${this.fontSize1}px`;
seasonTitleElem.style.lineHeight = `${this.fontSize1}px`;
seasonContainer.append(seasonTitleElem);
const seasonEpisodesCount = document.createElement('div');
seasonEpisodesCount.className = 'seasonEpisodesCount';
if (childData.leafCount > 0) {
seasonEpisodesCount.innerHTML = `${escapeHtml(childData.leafCount)} episodes`;
} else if (!_.isNil(childData.year)) {
seasonEpisodesCount.innerHTML = `${escapeHtml(childData.year)} `;
}
seasonEpisodesCount.style.fontSize = `${this.fontSize2}px`;
seasonEpisodesCount.style.lineHeight = `${this.fontSize2}px`;
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 (this.playController) {
this.playController.setPlayActionButtonType(childData.type);
this.playController.setPlayButtonClickFunction((thisEvent: MouseEvent) => {
thisEvent.preventDefault();
thisEvent.stopPropagation();
if (this.playController) {
this.playController.play(childData, true);
}
});
}
if (typeof seasonElem.children[0].children[0] !== 'undefined') {
(seasonElem.children[0].children[0] as HTMLElement).style.display = 'none';
}
seasonEpisodesCount.style.fontSize = `${this.fontSize2}px`;
seasonEpisodesCount.style.lineHeight = `${this.fontSize2}px`;
seasonContainer.append(seasonEpisodesCount);
seasonElem.dataset.clicked = 'true';
this.activeMovieElem.style.top = `${top - 1000}px`;
setTimeout(() => {
if (this.activeMovieElem) {
this.activeMovieElem.style.display = 'none';
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 (this.playController) {
this.playController.setPlayActionButtonType(childData.type);
this.playController.setPlayButtonClickFunction((thisEvent: MouseEvent) => {
thisEvent.preventDefault();
thisEvent.stopPropagation();
if (this.playController) {
this.playController.play(childData, true);
}
});
}
if (typeof seasonElem.children[0].children[0] !== 'undefined') {
(seasonElem.children[0].children[0] as HTMLElement).style.display = 'none';
}
}, 500);
this.scrollDownInactiveSeasons();
seasonElem.dataset.clicked = 'true';
this.activeMovieElem.style.top = `${top - 1000}px`;
setTimeout(() => {
if (this.activeMovieElem) {
this.activeMovieElem.style.display = 'none';
}
}, 500);
if (this.activeMovieElem) {
seasonContainer.style.top = `${-getHeight(this.activeMovieElem)}px`;
} else {
seasonContainer.style.top = `${-this.minExpandedHeight}px`;
}
this.scrollDownInactiveSeasons();
seasonElem.dataset.type = childData.type;
seasonElem.style.width = `${this.minExpandedWidth}px`;
if (_.isEqual(childData.type, 'album')) {
seasonElem.style.height = `${this.minExpandedWidth}px`;
} else {
seasonElem.style.height = `${this.minExpandedHeight - 6}px`;
}
seasonElem.style.zIndex = '3';
if (this.activeMovieElem) {
seasonContainer.style.top = `${-getHeight(this.activeMovieElem)}px`;
} else {
seasonContainer.style.top = `${-this.minExpandedHeight}px`;
}
seasonElem.style.marginLeft = `-${getOffset(seasonElem).left -
getOffset(this.activeMovieElem).left}px`;
seasonElem.dataset.type = childData.type;
seasonElem.style.width = `${this.minExpandedWidth}px`;
if (_.isEqual(childData.type, 'album')) {
seasonElem.style.height = `${this.minExpandedWidth}px`;
} else {
seasonElem.style.height = `${this.minExpandedHeight - 6}px`;
}
seasonElem.style.zIndex = '3';
seasonTitleElem.style.color = 'rgba(255,255,255,0)';
seasonEpisodesCount.style.color = 'rgba(255,255,255,0)';
seasonElem.style.marginLeft = `-${getOffset(seasonElem).left -
getOffset(this.activeMovieElem).left}px`;
if (this.detailElem) {
(this.detailElem.children[1] as HTMLElement).innerHTML = childData.title;
}
(async (): Promise<void> => {
if (this.plex && (childData.leafCount > 0 || _.isEqual(childData.type, 'album'))) {
this.episodesElemFreshlyLoaded = true;
const episodesData = await this.plex.getLibraryData(childData.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`;
const tableView = document.createElement('table');
tableView.style.width = 'calc(100% - 10px)';
tableView.style.border = 'none';
tableView.cellSpacing = '0';
tableView.cellPadding = '0';
if (_.isEqual(childData.type, 'album')) {
this.episodesElem.append(tableView);
}
let isEven = false;
_.forEach(episodesData, episodeData => {
if (this.episodesElem && this.playController && this.plex) {
if (_.isEqual(episodeData.type, 'track')) {
tableView.append(
createTrackView(
this.playController,
this.plex,
episodeData,
this.fontSize1,
this.fontSize2,
isEven
)
);
isEven = !isEven;
} else {
this.episodesElem.append(
createEpisodesView(
this.playController,
this.plex,
episodeData,
this.fontSize1,
this.fontSize2
)
);
}
}
});
clearInterval(this.episodesLoadTimeout);
this.episodesLoadTimeout = setTimeout(() => {
if (this.episodesElem) {
this.episodesElem.style.transition = `0.7s`;
if (this.activeMovieElem) {
this.episodesElem.style.top = `${top + getHeight(this.activeMovieElem) + 16 * 2}px`;
} else {
this.episodesElem.style.top = `${top + this.minExpandedHeight + 16}px`;
}
seasonTitleElem.style.color = 'rgba(255,255,255,0)';
seasonEpisodesCount.style.color = 'rgba(255,255,255,0)';
this.resizeBackground();
if (this.detailElem) {
(this.detailElem.children[1] as HTMLElement).innerHTML = childData.title;
}
(async (): Promise<void> => {
if (this.plex && (childData.leafCount > 0 || _.isEqual(childData.type, 'album'))) {
this.episodesElemFreshlyLoaded = true;
const episodesData = await this.plex.getLibraryData(childData.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`;
const tableView = document.createElement('table');
tableView.style.width = 'calc(100% - 10px)';
tableView.style.border = 'none';
tableView.cellSpacing = '0';
tableView.cellPadding = '0';
if (_.isEqual(childData.type, 'album')) {
this.episodesElem.append(tableView);
}
}, 200);
clearInterval(this.episodesElemFreshlyLoadedTimeout);
this.episodesElemFreshlyLoadedTimeout = setTimeout(() => {
this.episodesElemFreshlyLoaded = false;
}, 700);
let isEven = false;
_.forEach(episodesData, episodeData => {
if (this.episodesElem && this.playController && this.plex) {
if (_.isEqual(episodeData.type, 'track')) {
tableView.append(
createTrackView(
this.playController,
this.plex,
episodeData,
this.fontSize1,
this.fontSize2,
isEven
)
);
isEven = !isEven;
} else {
this.episodesElem.append(
createEpisodesView(
this.playController,
this.plex,
episodeData,
this.fontSize1,
this.fontSize2
)
);
}
}
});
clearInterval(this.episodesLoadTimeout);
this.episodesLoadTimeout = setTimeout(() => {
if (this.episodesElem) {
this.episodesElem.style.transition = `0.7s`;
if (this.activeMovieElem) {
this.episodesElem.style.top = `${top + getHeight(this.activeMovieElem) + 16 * 2}px`;
} else {
this.episodesElem.style.top = `${top + this.minExpandedHeight + 16}px`;
}
this.resizeBackground();
}
}, 200);
clearInterval(this.episodesElemFreshlyLoadedTimeout);
this.episodesElemFreshlyLoadedTimeout = setTimeout(() => {
this.episodesElemFreshlyLoaded = false;
}, 700);
}
}
})();
} else {
// todo: change title from season and change media type of play button back
if (this.playController) {
this.playController.setPlayActionButtonType(childData.type);
}
})();
} else {
// todo: change title from season and change media type of play button back
if (this.playController) {
this.playController.setPlayActionButtonType(childData.type);
}
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);
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] as HTMLElement)) {
const { year } = (this.detailElem.children[1] as HTMLElement).dataset;
if (year) {
(this.detailElem.children[1] as HTMLElement).innerHTML = year;
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;
}
}
}
}
}
}
});
});
this.seasonsElem.append(seasonContainer);
}
});
this.seasonsElem.append(seasonContainer);
}
});
_.forEach((this.seasonsElem as HTMLElement).children, elem => {
const seasonElem = elem as HTMLElement;
const left = seasonElem.offsetLeft;
const topElem = seasonElem.offsetTop;
seasonElem.style.left = `${left}px`;
seasonElem.dataset.left = `${left}`;
seasonElem.style.top = `${topElem}px`;
seasonElem.dataset.top = `${topElem}`;
});
_.forEach((this.seasonsElem as HTMLElement).children, elem => {
const seasonElem = elem as HTMLElement;
seasonElem.style.position = 'absolute';
});
_.forEach((this.seasonsElem as HTMLElement).children, elem => {
const seasonElem = elem as HTMLElement;
const left = seasonElem.offsetLeft;
const topElem = seasonElem.offsetTop;
seasonElem.style.left = `${left}px`;
seasonElem.dataset.left = `${left}`;
seasonElem.style.top = `${topElem}px`;
seasonElem.dataset.top = `${topElem}`;
});
_.forEach((this.seasonsElem as HTMLElement).children, elem => {
const seasonElem = elem as HTMLElement;
seasonElem.style.position = 'absolute';
});
clearInterval(this.seasonElemFreshlyLoadedTimeout);
this.seasonElemFreshlyLoadedTimeout = setTimeout(() => {
this.seasonElemFreshlyLoaded = false;
}, 700);
clearInterval(this.showSeasonElemTimeout);
this.showSeasonElemTimeout = setTimeout(() => {
if (this.seasonsElem) {
this.seasonsElem.style.transition = `0.7s`;
if (this.activeMovieElem) {
this.seasonsElem.style.top = `${top + getHeight(this.activeMovieElem) + 16 * 2}px`;
} else {
this.seasonsElem.style.top = `${top + this.minExpandedHeight + 16}px`;
}
clearInterval(this.seasonElemFreshlyLoadedTimeout);
this.seasonElemFreshlyLoadedTimeout = setTimeout(() => {
this.seasonElemFreshlyLoaded = false;
}, 700);
this.resizeBackground();
}
}, 200);
clearInterval(this.showSeasonElemTimeout);
this.showSeasonElemTimeout = setTimeout(() => {
if (this.seasonsElem) {
this.seasonsElem.style.transition = `0.7s`;
if (this.activeMovieElem) {
this.seasonsElem.style.top = `${top + getHeight(this.activeMovieElem) + 16 * 2}px`;
} else {
this.seasonsElem.style.top = `${top + this.minExpandedHeight + 16}px`;
}
this.resizeBackground();
}
}, 200);
}
} else {
this.episodesElemFreshlyLoaded = true;
if (this.episodesElem) {
@ -1893,8 +1946,8 @@ class PlexMeetsHomeAssistant extends HTMLElement {
movieElem.style.width = `${CSS_STYLE.width}px`;
movieElem.style.height = `${CSS_STYLE.height}px`;
if (!_.isNil(data.channelCallSign) || _.isEqual(data.type, 'artist')) {
if (!_.isEqual(data.type, 'artist')) {
if (!_.isNil(data.channelCallSign) || _.isEqual(data.type, 'artist') || _.isEqual(data.type, 'album')) {
if (!_.isEqual(data.type, 'artist') && !_.isEqual(data.type, 'album')) {
movieElem.style.backgroundSize = '80%';
}
movieElem.style.backgroundColor = 'rgba(0,0,0,0.2)';
@ -2060,6 +2113,9 @@ class PlexMeetsHomeAssistant extends HTMLElement {
if (config.protocol) {
this.plexProtocol = config.protocol;
}
if (config.displayType && !_.isEmpty(config.displayType)) {
this.displayType = config.displayType;
}
if (config.useHorizontalScroll && _.isEqual(config.useHorizontalScroll, 'Yes')) {
this.useHorizontalScroll = true;
}

Loading…
Cancel
Save