Add: Ability to set display type

pull/51/head
Juraj Nyíri 3 years ago
parent b738269d8d
commit 047dbe2d73

@ -18815,8 +18815,8 @@ class Plex {
}); });
return lodash.isNil(collectionsData.data.MediaContainer.Metadata) ? [] : collectionsData.data.MediaContainer.Metadata; return lodash.isNil(collectionsData.data.MediaContainer.Metadata) ? [] : collectionsData.data.MediaContainer.Metadata;
}; };
this.getSectionData = async (sectionID) => { this.getSectionData = async (sectionID, type = false) => {
return this.exportSectionsData([await this.getSectionDataWithoutProcessing(sectionID)]); return this.exportSectionsData([await this.getSectionDataWithoutProcessing(sectionID, type)]);
}; };
this.getChildren = async (childrenURL) => { this.getChildren = async (childrenURL) => {
const bulkItems = 50; const bulkItems = 50;
@ -18861,10 +18861,14 @@ class Plex {
this.getPlaylistData = async (playlistKey) => { this.getPlaylistData = async (playlistKey) => {
return this.getChildren(playlistKey); return this.getChildren(playlistKey);
}; };
this.getSectionDataWithoutProcessing = async (sectionID) => { this.getSectionDataWithoutProcessing = async (sectionID, type = false) => {
const bulkItems = 50; const bulkItems = 50;
let url = this.authorizeURL(`${this.getBasicURL()}/library/sections/${sectionID}/all`); let url = this.authorizeURL(`${this.getBasicURL()}/library/sections/${sectionID}/all`);
url += `&sort=${this.sort}`; url += `&sort=${this.sort}`;
if (type) {
url += `&type=${type}`;
}
url += `&includeCollections=1&includeExternalMedia=1&includeAdvanced=1&includeMeta=1`;
let result = {}; let result = {};
try { try {
result = await axios.get(url, { result = await axios.get(url, {
@ -20158,6 +20162,7 @@ class PlexMeetsHomeAssistantEditor extends HTMLElement {
this.protocol = document.createElement('paper-dropdown-menu'); this.protocol = document.createElement('paper-dropdown-menu');
this.tabs = document.createElement('paper-tabs'); this.tabs = document.createElement('paper-tabs');
this.sort = document.createElement('paper-dropdown-menu'); this.sort = document.createElement('paper-dropdown-menu');
this.displayType = document.createElement('paper-dropdown-menu');
this.sortOrder = document.createElement('paper-dropdown-menu'); this.sortOrder = document.createElement('paper-dropdown-menu');
this.playTrailer = document.createElement('paper-dropdown-menu'); this.playTrailer = document.createElement('paper-dropdown-menu');
this.showExtras = document.createElement('paper-dropdown-menu'); this.showExtras = document.createElement('paper-dropdown-menu');
@ -20213,6 +20218,7 @@ class PlexMeetsHomeAssistantEditor extends HTMLElement {
else { else {
this.config.sort = ``; this.config.sort = ``;
} }
this.config.displayType = this.displayType.value;
if (lodash.isEmpty(this.maxCount.value)) { if (lodash.isEmpty(this.maxCount.value)) {
this.config.maxCount = ''; this.config.maxCount = '';
} }
@ -20335,10 +20341,14 @@ class PlexMeetsHomeAssistantEditor extends HTMLElement {
} }
}; };
this.render = async () => { 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'); const libraryItem = document.createElement('paper-item');
libraryItem.innerHTML = text.replace(/ /g, ' '); libraryItem.innerHTML = text.replace(/ /g, ' ');
libraryItem.label = text; libraryItem.label = value;
if (disabled) { if (disabled) {
libraryItem.disabled = true; libraryItem.disabled = true;
} }
@ -20448,7 +20458,7 @@ class PlexMeetsHomeAssistantEditor extends HTMLElement {
this.content.appendChild(this.token); this.content.appendChild(this.token);
this.libraryName.innerHTML = ''; this.libraryName.innerHTML = '';
const libraryItems = document.createElement('paper-listbox'); 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('Continue Watching'));
libraryItems.appendChild(addDropdownItem('Deck')); libraryItems.appendChild(addDropdownItem('Deck'));
libraryItems.appendChild(addDropdownItem('Recently Added')); libraryItems.appendChild(addDropdownItem('Recently Added'));
@ -20462,6 +20472,14 @@ class PlexMeetsHomeAssistantEditor extends HTMLElement {
const warningLibrary = document.createElement('div'); const warningLibrary = document.createElement('div');
warningLibrary.style.color = 'red'; warningLibrary.style.color = 'red';
this.content.appendChild(this.libraryName); this.content.appendChild(this.libraryName);
this.displayType.innerHTML = '';
const typeItems = document.createElement('paper-listbox');
typeItems.slot = 'dropdown-content';
this.displayType.label = 'Display Type';
this.displayType.appendChild(typeItems);
this.displayType.style.width = '100%';
this.displayType.addEventListener('value-changed', this.valueUpdated);
this.content.appendChild(this.displayType);
this.content.appendChild(warningLibrary); this.content.appendChild(warningLibrary);
this.appendChild(this.content); this.appendChild(this.content);
this.plex = new Plex(this.config.ip.replace(/^https?\:\/\//i, '').replace(/\/$/, ''), this.plexPort, this.config.token, this.plexProtocol, this.config.sort); this.plex = new Plex(this.config.ip.replace(/^https?\:\/\//i, '').replace(/\/$/, ''), this.plexPort, this.config.token, this.plexProtocol, this.config.sort);
@ -20772,7 +20790,7 @@ class PlexMeetsHomeAssistantEditor extends HTMLElement {
this.fontSize4.addEventListener('change', this.valueUpdated); this.fontSize4.addEventListener('change', this.valueUpdated);
this.plexValidSection.appendChild(this.fontSize4); this.plexValidSection.appendChild(this.fontSize4);
if (!lodash.isEmpty(this.livetv)) { if (!lodash.isEmpty(this.livetv)) {
libraryItems.appendChild(addDropdownItem('Live TV', true)); libraryItems.appendChild(addDropdownItem('Live TV', '', true));
lodash.forEach(lodash.keys(this.livetv), (livetv) => { lodash.forEach(lodash.keys(this.livetv), (livetv) => {
if (lodash.isEqual(this.config.libraryName, 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.`; 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,18 +20799,18 @@ class PlexMeetsHomeAssistantEditor extends HTMLElement {
}); });
} }
if (!lodash.isEmpty(this.sections)) { if (!lodash.isEmpty(this.sections)) {
libraryItems.appendChild(addDropdownItem('Libraries', true)); libraryItems.appendChild(addDropdownItem('Libraries', '', true));
lodash.forEach(this.sections, (section) => { lodash.forEach(this.sections, (section) => {
libraryItems.appendChild(addDropdownItem(section.title)); libraryItems.appendChild(addDropdownItem(section.title));
}); });
if (!lodash.isEmpty(this.collections)) { if (!lodash.isEmpty(this.collections)) {
libraryItems.appendChild(addDropdownItem('Collections', true)); libraryItems.appendChild(addDropdownItem('Collections', '', true));
lodash.forEach(this.collections, (collection) => { lodash.forEach(this.collections, (collection) => {
libraryItems.appendChild(addDropdownItem(collection.title)); libraryItems.appendChild(addDropdownItem(collection.title));
}); });
} }
if (!lodash.isEmpty(this.playlists)) { if (!lodash.isEmpty(this.playlists)) {
libraryItems.appendChild(addDropdownItem('Playlists', true)); libraryItems.appendChild(addDropdownItem('Playlists', '', true));
lodash.forEach(this.playlists, (playlist) => { lodash.forEach(this.playlists, (playlist) => {
libraryItems.appendChild(addDropdownItem(playlist.title)); libraryItems.appendChild(addDropdownItem(playlist.title));
}); });
@ -20800,13 +20818,58 @@ class PlexMeetsHomeAssistantEditor extends HTMLElement {
this.libraryName.disabled = false; this.libraryName.disabled = false;
this.libraryName.value = this.config.libraryName; this.libraryName.value = this.config.libraryName;
let libraryType = ''; let libraryType = '';
let libraryKey = '';
// eslint-disable-next-line consistent-return // eslint-disable-next-line consistent-return
lodash.forEach(this.sections, section => { lodash.forEach(this.sections, section => {
if (lodash.isEqual(section.title, this.libraryName.value)) { if (lodash.isEqual(section.title, this.libraryName.value)) {
libraryType = section.type; libraryType = section.type;
libraryKey = section.key;
return false; return false;
} }
}); });
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 = '';
}
}
else {
this.displayType.style.display = 'none';
this.config.displayType = '';
this.displayType.value = '';
}
if (lodash.isEqual(libraryType, 'show')) { if (lodash.isEqual(libraryType, 'show')) {
sortItems.appendChild(addDropdownItem('titleSort')); sortItems.appendChild(addDropdownItem('titleSort'));
sortItems.appendChild(addDropdownItem('title')); sortItems.appendChild(addDropdownItem('title'));
@ -20890,6 +20953,9 @@ class PlexMeetsHomeAssistantEditor extends HTMLElement {
if (!config.sort) { if (!config.sort) {
this.config.sort = 'titleSort:asc'; this.config.sort = 'titleSort:asc';
} }
if (!config.displayType) {
this.config.displayType = '';
}
if (!lodash.isNil(config.playTrailer)) { if (!lodash.isNil(config.playTrailer)) {
this.config.playTrailer = config.playTrailer; this.config.playTrailer = config.playTrailer;
} }
@ -21777,6 +21843,7 @@ class PlexMeetsHomeAssistant extends HTMLElement {
this.renderPageRetries = 0; this.renderPageRetries = 0;
this.searchInputElem = document.createElement('input'); this.searchInputElem = document.createElement('input');
this.plexProtocol = 'http'; this.plexProtocol = 'http';
this.displayType = false;
this.useHorizontalScroll = false; this.useHorizontalScroll = false;
this.displayTitleMain = true; this.displayTitleMain = true;
this.displaySubtitleMain = true; this.displaySubtitleMain = true;
@ -22096,7 +22163,7 @@ class PlexMeetsHomeAssistant extends HTMLElement {
this.epgData = await this.plex.getEPG(); this.epgData = await this.plex.getEPG();
} }
}; };
let sectionKey = 0; let sectionKey = false;
lodash.forEach(plexAllSections, (section) => { lodash.forEach(plexAllSections, (section) => {
if (lodash.isEqual(section.title, this.config.libraryName)) { if (lodash.isEqual(section.title, this.config.libraryName)) {
sectionKey = section.key; sectionKey = section.key;
@ -22106,7 +22173,7 @@ class PlexMeetsHomeAssistant extends HTMLElement {
}); });
const loadDataRequests = []; const loadDataRequests = [];
if (sectionKey) { if (sectionKey) {
loadDataRequests.push(this.plex.getSectionData(sectionKey)); loadDataRequests.push(this.plex.getSectionData(sectionKey, this.displayType));
} }
if (lodash.isEqual(this.config.libraryName, 'Deck')) { if (lodash.isEqual(this.config.libraryName, 'Deck')) {
loadDataRequests.push(getOnDeck()); loadDataRequests.push(getOnDeck());
@ -22897,7 +22964,7 @@ class PlexMeetsHomeAssistant extends HTMLElement {
if (lodash.isEqual(data.type, 'episode')) { if (lodash.isEqual(data.type, 'episode')) {
childrenData = await this.plex.getLibraryData(data.grandparentKey.split('/')[3]); 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]); childrenData = await this.plex.getLibraryData(data.key.split('/')[3]);
} }
let dataDetails = {}; let dataDetails = {};
@ -23010,230 +23077,279 @@ class PlexMeetsHomeAssistant extends HTMLElement {
this.seasonsElem.style.transition = `0s`; this.seasonsElem.style.transition = `0s`;
this.seasonsElem.style.top = `${top + 2000}px`; this.seasonsElem.style.top = `${top + 2000}px`;
} }
lodash.forEach(childrenData, childData => { if (lodash.isEqual(lodash.get(childrenData[0], 'type'), 'track')) {
if (this.seasonsElem && this.plex) { if (this.episodesElem) {
this.seasonsElemHidden = false; this.episodesElemHidden = false;
const seasonContainer = document.createElement('div'); this.episodesElem.style.display = 'block';
seasonContainer.className = 'seasonContainer'; this.episodesElem.innerHTML = '';
seasonContainer.style.width = `${CSS_STYLE.width}px`; this.episodesElem.style.transition = `0s`;
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}`; this.episodesElem.style.top = `${top + 2000}px`;
const seasonElem = document.createElement('div'); const tableView = document.createElement('table');
seasonElem.className = 'seasonElem'; tableView.style.width = 'calc(100% - 10px)';
seasonElem.style.width = `${CSS_STYLE.width}px`; tableView.style.border = 'none';
if (lodash.isEqual(childData.type, 'album')) { tableView.cellSpacing = '0';
seasonElem.style.height = `${CSS_STYLE.width}px`; tableView.cellPadding = '0';
if (lodash.isEqual(data.type, 'album')) {
this.episodesElem.append(tableView);
} }
else { let isEven = false;
seasonElem.style.height = `${CSS_STYLE.height - 3}px`; lodash.forEach(childrenData, childData => {
} if (this.episodesElem && this.playController && this.plex) {
seasonElem.style.backgroundImage = `url('${thumbURL}')`; if (lodash.isEqual(childData.type, 'track')) {
seasonElem.dataset.clicked = 'false'; tableView.append(createTrackView(this.playController, this.plex, childData, this.fontSize1, this.fontSize2, isEven));
if (this.playController && !this.playController.isPlaySupported(childData)) { isEven = !isEven;
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);
} }
}); else {
interactiveArea.append(playButton); this.episodesElem.append(createEpisodesView(this.playController, this.plex, childData, this.fontSize1, this.fontSize2));
} }
seasonElem.append(interactiveArea); }
seasonContainer.append(seasonElem); });
const seasonTitleElem = document.createElement('div'); clearInterval(this.episodesLoadTimeout);
seasonTitleElem.className = 'seasonTitleElem'; this.episodesLoadTimeout = setTimeout(() => {
seasonTitleElem.innerHTML = escapeHtml(childData.title); if (this.episodesElem) {
seasonTitleElem.style.fontSize = `${this.fontSize1}px`; this.episodesElem.style.transition = `0.7s`;
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 (this.activeMovieElem) {
if (seasonElem.dataset.clicked === 'false') { this.episodesElem.style.top = `${top + getHeight(this.activeMovieElem) + 16 * 2}px`;
if (this.playController) { }
this.playController.setPlayActionButtonType(childData.type); else {
this.playController.setPlayButtonClickFunction((thisEvent) => { this.episodesElem.style.top = `${top + this.minExpandedHeight + 16}px`;
thisEvent.preventDefault(); }
thisEvent.stopPropagation(); this.resizeBackground();
if (this.playController) { }
this.playController.play(childData, true); }, 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';
} }
}); }, 500);
} this.scrollDownInactiveSeasons();
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) { if (this.activeMovieElem) {
this.activeMovieElem.style.display = 'none'; seasonContainer.style.top = `${-getHeight(this.activeMovieElem)}px`;
} }
}, 500); else {
this.scrollDownInactiveSeasons(); seasonContainer.style.top = `${-this.minExpandedHeight}px`;
if (this.activeMovieElem) { }
seasonContainer.style.top = `${-getHeight(this.activeMovieElem)}px`; seasonElem.dataset.type = childData.type;
} seasonElem.style.width = `${this.minExpandedWidth}px`;
else { if (lodash.isEqual(childData.type, 'album')) {
seasonContainer.style.top = `${-this.minExpandedHeight}px`; seasonElem.style.height = `${this.minExpandedWidth}px`;
} }
seasonElem.dataset.type = childData.type; else {
seasonElem.style.width = `${this.minExpandedWidth}px`; seasonElem.style.height = `${this.minExpandedHeight - 6}px`;
if (lodash.isEqual(childData.type, 'album')) { }
seasonElem.style.height = `${this.minExpandedWidth}px`; seasonElem.style.zIndex = '3';
} seasonElem.style.marginLeft = `-${getOffset(seasonElem).left -
else { getOffset(this.activeMovieElem).left}px`;
seasonElem.style.height = `${this.minExpandedHeight - 6}px`; seasonTitleElem.style.color = 'rgba(255,255,255,0)';
} seasonEpisodesCount.style.color = 'rgba(255,255,255,0)';
seasonElem.style.zIndex = '3'; if (this.detailElem) {
seasonElem.style.marginLeft = `-${getOffset(seasonElem).left - this.detailElem.children[1].innerHTML = childData.title;
getOffset(this.activeMovieElem).left}px`; }
seasonTitleElem.style.color = 'rgba(255,255,255,0)'; (async () => {
seasonEpisodesCount.style.color = 'rgba(255,255,255,0)'; if (this.plex && (childData.leafCount > 0 || lodash.isEqual(childData.type, 'album'))) {
if (this.detailElem) { this.episodesElemFreshlyLoaded = true;
this.detailElem.children[1].innerHTML = childData.title; const episodesData = await this.plex.getLibraryData(childData.key.split('/')[3]);
} if (this.episodesElem) {
(async () => { this.episodesElemHidden = false;
if (this.plex && (childData.leafCount > 0 || lodash.isEqual(childData.type, 'album'))) { this.episodesElem.style.display = 'block';
this.episodesElemFreshlyLoaded = true; this.episodesElem.innerHTML = '';
const episodesData = await this.plex.getLibraryData(childData.key.split('/')[3]); this.episodesElem.style.transition = `0s`;
if (this.episodesElem) { this.episodesElem.style.top = `${top + 2000}px`;
this.episodesElemHidden = false; const tableView = document.createElement('table');
this.episodesElem.style.display = 'block'; tableView.style.width = 'calc(100% - 10px)';
this.episodesElem.innerHTML = ''; tableView.style.border = 'none';
this.episodesElem.style.transition = `0s`; tableView.cellSpacing = '0';
this.episodesElem.style.top = `${top + 2000}px`; tableView.cellPadding = '0';
const tableView = document.createElement('table'); if (lodash.isEqual(childData.type, 'album')) {
tableView.style.width = 'calc(100% - 10px)'; this.episodesElem.append(tableView);
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));
}
} }
}); let isEven = false;
clearInterval(this.episodesLoadTimeout); lodash.forEach(episodesData, episodeData => {
this.episodesLoadTimeout = setTimeout(() => { if (this.episodesElem && this.playController && this.plex) {
if (this.episodesElem) { if (lodash.isEqual(episodeData.type, 'track')) {
this.episodesElem.style.transition = `0.7s`; tableView.append(createTrackView(this.playController, this.plex, episodeData, this.fontSize1, this.fontSize2, isEven));
if (this.activeMovieElem) { isEven = !isEven;
this.episodesElem.style.top = `${top + getHeight(this.activeMovieElem) + 16 * 2}px`; }
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);
}, 200); this.episodesElemFreshlyLoadedTimeout = setTimeout(() => {
clearInterval(this.episodesElemFreshlyLoadedTimeout); this.episodesElemFreshlyLoaded = false;
this.episodesElemFreshlyLoadedTimeout = setTimeout(() => { }, 700);
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`; else {
this.minimizeSeasons(); // todo: change title from season and change media type of play button back
this.hideEpisodes(); if (this.playController) {
this.activeMovieElem.style.display = `block`; this.playController.setPlayActionButtonType(childData.type);
setTimeout(() => {
if (this.activeMovieElem) {
this.activeMovieElem.style.top = `${top + 16}px`;
} }
}, 10); seasonContainer.style.top = `${seasonContainer.dataset.top}px`;
if (this.detailElem && this.detailElem.children[1]) { this.minimizeSeasons();
const { year } = this.detailElem.children[1].dataset; this.hideEpisodes();
if (year) { this.activeMovieElem.style.display = `block`;
this.detailElem.children[1].innerHTML = year; 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);
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`;
} }
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 { else {
this.episodesElemFreshlyLoaded = true; this.episodesElemFreshlyLoaded = true;
@ -23384,8 +23500,8 @@ class PlexMeetsHomeAssistant extends HTMLElement {
movieElem.className = 'movieElem'; movieElem.className = 'movieElem';
movieElem.style.width = `${CSS_STYLE.width}px`; movieElem.style.width = `${CSS_STYLE.width}px`;
movieElem.style.height = `${CSS_STYLE.height}px`; movieElem.style.height = `${CSS_STYLE.height}px`;
if (!lodash.isNil(data.channelCallSign) || 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')) { if (!lodash.isEqual(data.type, 'artist') && !lodash.isEqual(data.type, 'album')) {
movieElem.style.backgroundSize = '80%'; movieElem.style.backgroundSize = '80%';
} }
movieElem.style.backgroundColor = 'rgba(0,0,0,0.2)'; movieElem.style.backgroundColor = 'rgba(0,0,0,0.2)';
@ -23536,6 +23652,9 @@ class PlexMeetsHomeAssistant extends HTMLElement {
if (config.protocol) { if (config.protocol) {
this.plexProtocol = 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')) { if (config.useHorizontalScroll && lodash.isEqual(config.useHorizontalScroll, 'Yes')) {
this.useHorizontalScroll = true; this.useHorizontalScroll = true;
} }

@ -58,6 +58,8 @@ class PlexMeetsHomeAssistantEditor extends HTMLElement {
sort: any = document.createElement('paper-dropdown-menu'); sort: any = document.createElement('paper-dropdown-menu');
displayType: any = document.createElement('paper-dropdown-menu');
sortOrder: any = document.createElement('paper-dropdown-menu'); sortOrder: any = document.createElement('paper-dropdown-menu');
playTrailer: 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.sort = ``;
} }
this.config.displayType = this.displayType.value;
if (_.isEmpty(this.maxCount.value)) { if (_.isEmpty(this.maxCount.value)) {
this.config.maxCount = ''; this.config.maxCount = '';
} else { } else {
@ -258,10 +262,14 @@ class PlexMeetsHomeAssistantEditor extends HTMLElement {
}; };
render = async (): Promise<void> => { 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'); const libraryItem: any = document.createElement('paper-item');
libraryItem.innerHTML = text.replace(/ /g, '&nbsp;'); libraryItem.innerHTML = text.replace(/ /g, '&nbsp;');
libraryItem.label = text; libraryItem.label = value;
if (disabled) { if (disabled) {
libraryItem.disabled = true; libraryItem.disabled = true;
} }
@ -381,7 +389,7 @@ class PlexMeetsHomeAssistantEditor extends HTMLElement {
this.libraryName.innerHTML = ''; this.libraryName.innerHTML = '';
const libraryItems: any = document.createElement('paper-listbox'); 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('Continue Watching'));
libraryItems.appendChild(addDropdownItem('Deck')); libraryItems.appendChild(addDropdownItem('Deck'));
libraryItems.appendChild(addDropdownItem('Recently Added')); libraryItems.appendChild(addDropdownItem('Recently Added'));
@ -396,6 +404,16 @@ class PlexMeetsHomeAssistantEditor extends HTMLElement {
const warningLibrary = document.createElement('div'); const warningLibrary = document.createElement('div');
warningLibrary.style.color = 'red'; warningLibrary.style.color = 'red';
this.content.appendChild(this.libraryName); this.content.appendChild(this.libraryName);
this.displayType.innerHTML = '';
const typeItems: any = document.createElement('paper-listbox');
typeItems.slot = 'dropdown-content';
this.displayType.label = 'Display Type';
this.displayType.appendChild(typeItems);
this.displayType.style.width = '100%';
this.displayType.addEventListener('value-changed', this.valueUpdated);
this.content.appendChild(this.displayType);
this.content.appendChild(warningLibrary); this.content.appendChild(warningLibrary);
this.appendChild(this.content); this.appendChild(this.content);
@ -734,7 +752,7 @@ class PlexMeetsHomeAssistantEditor extends HTMLElement {
this.plexValidSection.appendChild(this.fontSize4); this.plexValidSection.appendChild(this.fontSize4);
if (!_.isEmpty(this.livetv)) { if (!_.isEmpty(this.livetv)) {
libraryItems.appendChild(addDropdownItem('Live TV', true)); libraryItems.appendChild(addDropdownItem('Live TV', '', true));
_.forEach(_.keys(this.livetv), (livetv: string) => { _.forEach(_.keys(this.livetv), (livetv: string) => {
if (_.isEqual(this.config.libraryName, livetv)) { 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.`; 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)) { if (!_.isEmpty(this.sections)) {
libraryItems.appendChild(addDropdownItem('Libraries', true)); libraryItems.appendChild(addDropdownItem('Libraries', '', true));
_.forEach(this.sections, (section: Record<string, any>) => { _.forEach(this.sections, (section: Record<string, any>) => {
libraryItems.appendChild(addDropdownItem(section.title)); libraryItems.appendChild(addDropdownItem(section.title));
}); });
if (!_.isEmpty(this.collections)) { if (!_.isEmpty(this.collections)) {
libraryItems.appendChild(addDropdownItem('Collections', true)); libraryItems.appendChild(addDropdownItem('Collections', '', true));
_.forEach(this.collections, (collection: Record<string, any>) => { _.forEach(this.collections, (collection: Record<string, any>) => {
libraryItems.appendChild(addDropdownItem(collection.title)); libraryItems.appendChild(addDropdownItem(collection.title));
}); });
} }
if (!_.isEmpty(this.playlists)) { if (!_.isEmpty(this.playlists)) {
libraryItems.appendChild(addDropdownItem('Playlists', true)); libraryItems.appendChild(addDropdownItem('Playlists', '', true));
_.forEach(this.playlists, (playlist: Record<string, any>) => { _.forEach(this.playlists, (playlist: Record<string, any>) => {
libraryItems.appendChild(addDropdownItem(playlist.title)); libraryItems.appendChild(addDropdownItem(playlist.title));
}); });
@ -764,13 +782,56 @@ class PlexMeetsHomeAssistantEditor extends HTMLElement {
this.libraryName.value = this.config.libraryName; this.libraryName.value = this.config.libraryName;
let libraryType = ''; let libraryType = '';
let libraryKey = '';
// eslint-disable-next-line consistent-return // eslint-disable-next-line consistent-return
_.forEach(this.sections, section => { _.forEach(this.sections, section => {
if (_.isEqual(section.title, this.libraryName.value)) { if (_.isEqual(section.title, this.libraryName.value)) {
libraryType = section.type; libraryType = section.type;
libraryKey = section.key;
return false; return false;
} }
}); });
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 = '';
}
} else {
this.displayType.style.display = 'none';
this.config.displayType = '';
this.displayType.value = '';
}
if (_.isEqual(libraryType, 'show')) { if (_.isEqual(libraryType, 'show')) {
sortItems.appendChild(addDropdownItem('titleSort')); sortItems.appendChild(addDropdownItem('titleSort'));
sortItems.appendChild(addDropdownItem('title')); sortItems.appendChild(addDropdownItem('title'));
@ -853,6 +914,10 @@ class PlexMeetsHomeAssistantEditor extends HTMLElement {
this.config.sort = 'titleSort:asc'; this.config.sort = 'titleSort:asc';
} }
if (!config.displayType) {
this.config.displayType = '';
}
if (!_.isNil(config.playTrailer)) { if (!_.isNil(config.playTrailer)) {
this.config.playTrailer = config.playTrailer; this.config.playTrailer = config.playTrailer;
} else { } else {

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

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

Loading…
Cancel
Save