diff --git a/dist/plex-meets-homeassistant.js b/dist/plex-meets-homeassistant.js
index f37454b..9834204 100644
--- a/dist/plex-meets-homeassistant.js
+++ b/dist/plex-meets-homeassistant.js
@@ -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.
You might also need custom build of kodi-media-sensors, see detailed configuration 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;
}
diff --git a/src/editor.ts b/src/editor.ts
index 1510109..1870811 100644
--- a/src/editor.ts
+++ b/src/editor.ts
@@ -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 => {
- 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, ' ');
- 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.
You might also need custom build of kodi-media-sensors, see detailed configuration 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) => {
libraryItems.appendChild(addDropdownItem(section.title));
});
if (!_.isEmpty(this.collections)) {
- libraryItems.appendChild(addDropdownItem('Collections', true));
+ libraryItems.appendChild(addDropdownItem('Collections', '', true));
_.forEach(this.collections, (collection: Record) => {
libraryItems.appendChild(addDropdownItem(collection.title));
});
}
if (!_.isEmpty(this.playlists)) {
- libraryItems.appendChild(addDropdownItem('Playlists', true));
+ libraryItems.appendChild(addDropdownItem('Playlists', '', true));
_.forEach(this.playlists, (playlist: Record) => {
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) => {
+ 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, 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) => {
+ 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 {
diff --git a/src/modules/Plex.ts b/src/modules/Plex.ts
index 419601e..2ca4377 100644
--- a/src/modules/Plex.ts
+++ b/src/modules/Plex.ts
@@ -197,8 +197,8 @@ class Plex {
return _.isNil(collectionsData.data.MediaContainer.Metadata) ? [] : collectionsData.data.MediaContainer.Metadata;
};
- getSectionData = async (sectionID: number): Promise => {
- return this.exportSectionsData([await this.getSectionDataWithoutProcessing(sectionID)]);
+ getSectionData = async (sectionID: string, type: string | false = false): Promise => {
+ return this.exportSectionsData([await this.getSectionDataWithoutProcessing(sectionID, type)]);
};
private getChildren = async (childrenURL: string): Promise => {
@@ -257,10 +257,14 @@ class Plex {
return this.getChildren(playlistKey);
};
- private getSectionDataWithoutProcessing = async (sectionID: number): Promise => {
+ private getSectionDataWithoutProcessing = async (sectionID: string, type: string | false = false): Promise => {
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 = {};
try {
result = await axios.get(url, {
diff --git a/src/plex-meets-homeassistant.ts b/src/plex-meets-homeassistant.ts
index 023b648..64a2e43 100644
--- a/src/plex-meets-homeassistant.ts
+++ b/src/plex-meets-homeassistant.ts
@@ -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) => {
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 = {};
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 = {};
@@ -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 => {
- 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 => {
+ 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;
}