You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
PlexMeetsHomeAssistant/src/editor.ts

953 lines
33 KiB

/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-env browser */
import _ from 'lodash';
3 years ago
import { HomeAssistant } from 'custom-card-helpers';
import Plex from './modules/Plex';
3 years ago
import { fetchEntityRegistry } from './modules/utils';
class PlexMeetsHomeAssistantEditor extends HTMLElement {
content: any;
plexPort: number | false = false;
plexProtocol: 'http' | 'https' = 'http';
plex: Plex | undefined;
config: Record<string, any> = {};
ip: any = document.createElement('paper-input');
token: any = document.createElement('paper-input');
port: any = document.createElement('paper-input');
3 years ago
maxCount: any = document.createElement('paper-input');
maxRows: any = document.createElement('paper-input');
displayTitleMain: any = document.createElement('paper-dropdown-menu');
displaySubtitleMain: any = document.createElement('paper-dropdown-menu');
useHorizontalScroll: any = document.createElement('paper-dropdown-menu');
minWidth: any = document.createElement('paper-input');
minEpisodeWidth: any = document.createElement('paper-input');
minExpandedWidth: any = document.createElement('paper-input');
minExpandedHeight: any = document.createElement('paper-input');
fontSize1: any = document.createElement('paper-input');
fontSize2: any = document.createElement('paper-input');
fontSize3: any = document.createElement('paper-input');
fontSize4: any = document.createElement('paper-input');
cardTitle: any = document.createElement('paper-input');
libraryName: any = document.createElement('paper-dropdown-menu');
3 years ago
protocol: any = document.createElement('paper-dropdown-menu');
3 years ago
tabs: any = document.createElement('paper-tabs');
3 years ago
sort: any = document.createElement('paper-dropdown-menu');
sortOrder: any = document.createElement('paper-dropdown-menu');
3 years ago
playTrailer: any = document.createElement('paper-dropdown-menu');
3 years ago
showExtras: any = document.createElement('paper-dropdown-menu');
3 years ago
showSearch: any = document.createElement('paper-dropdown-menu');
3 years ago
runBefore: any = document.createElement('paper-dropdown-menu');
runAfter: any = document.createElement('paper-dropdown-menu');
3 years ago
entitiesSection: any = document.createElement('div');
3 years ago
devicesTabs = 0;
3 years ago
hassObj: HomeAssistant | undefined;
entities: Array<any> = [];
3 years ago
scriptEntities: Array<string> = [];
3 years ago
sections: Array<Record<string, any>> = [];
collections: Array<Record<string, any>> = [];
playlists: Array<Record<string, any>> = [];
3 years ago
clients: Record<string, any> = {};
3 years ago
entitiesRegistry: false | Array<Record<string, any>> = false;
plexValidSection = document.createElement('div');
3 years ago
loaded = false;
livetv: Record<string, any> = {};
fireEvent = (
node: HTMLElement,
type: string,
detail: Record<string, any>,
options: Record<string, any> = {}
): Event => {
// eslint-disable-next-line no-param-reassign
detail = detail === null || detail === undefined ? {} : detail;
const event: any = new Event(type, {
bubbles: options.bubbles === undefined ? true : options.bubbles,
cancelable: Boolean(options.cancelable),
composed: options.composed === undefined ? true : options.composed
});
event.detail = detail;
node.dispatchEvent(event);
return event;
};
3 years ago
valueUpdated = (): void => {
const originalConfig = _.clone(this.config);
this.config.protocol = this.protocol.value;
this.config.ip = this.ip.value.replace(/^https?\:\/\//i, '').replace(/\/$/, '');
this.config.token = this.token.value;
this.config.port = this.port.value;
3 years ago
if (this.loaded) {
if (!this.config.entity) {
this.config.entity = [];
3 years ago
}
3 years ago
if (!_.isEmpty(this.libraryName.value)) {
this.config.libraryName = this.libraryName.value;
let sortOrderValue = '';
if (_.isEqual(this.sortOrder.value, 'Ascending')) {
sortOrderValue = 'asc';
} else if (_.isEqual(this.sortOrder.value, 'Descending')) {
sortOrderValue = 'desc';
}
if (!_.isEmpty(sortOrderValue) && !_.isEmpty(this.sort.value)) {
this.config.sort = `${this.sort.value}:${sortOrderValue}`;
} else {
this.config.sort = ``;
}
3 years ago
3 years ago
if (_.isEmpty(this.maxCount.value)) {
this.config.maxCount = '';
} else {
this.config.maxCount = this.maxCount.value;
}
3 years ago
if (_.isEmpty(this.maxRows.value)) {
this.config.maxRows = '';
} else {
this.config.maxRows = this.maxRows.value;
}
if (_.isEmpty(this.useHorizontalScroll.value)) {
this.config.useHorizontalScroll = 'No';
} else {
this.config.useHorizontalScroll = this.useHorizontalScroll.value;
}
if (_.isEmpty(this.displayTitleMain.value)) {
this.config.displayTitleMain = 'Yes';
} else {
this.config.displayTitleMain = this.displayTitleMain.value;
}
if (_.isEmpty(this.displaySubtitleMain.value)) {
this.config.displaySubtitleMain = 'Yes';
} else {
this.config.displaySubtitleMain = this.displaySubtitleMain.value;
}
if (_.isEmpty(this.minWidth.value)) {
this.config.minWidth = '';
} else {
this.config.minWidth = this.minWidth.value;
}
if (_.isEmpty(this.minEpisodeWidth.value)) {
this.config.minEpisodeWidth = '';
} else {
this.config.minEpisodeWidth = this.minEpisodeWidth.value;
}
if (_.isEmpty(this.minExpandedWidth.value)) {
this.config.minExpandedWidth = '';
} else {
this.config.minExpandedWidth = this.minExpandedWidth.value;
}
if (_.isEmpty(this.fontSize1.value)) {
this.config.fontSize1 = '';
} else {
this.config.fontSize1 = this.fontSize1.value;
}
if (_.isEmpty(this.fontSize2.value)) {
this.config.fontSize2 = '';
} else {
this.config.fontSize2 = this.fontSize2.value;
}
if (_.isEmpty(this.fontSize3.value)) {
this.config.fontSize3 = '';
} else {
this.config.fontSize3 = this.fontSize3.value;
}
if (_.isEmpty(this.fontSize4.value)) {
this.config.fontSize4 = '';
} else {
this.config.fontSize4 = this.fontSize4.value;
}
if (_.isEmpty(this.minExpandedHeight.value)) {
this.config.minExpandedHeight = '';
} else {
this.config.minExpandedHeight = this.minExpandedHeight.value;
}
if (_.isEmpty(this.cardTitle.value)) {
this.config.title = '';
} else {
this.config.title = this.cardTitle.value;
}
3 years ago
if (!_.isEmpty(this.entities)) {
this.config.entity = [];
_.forEach(this.entities, entity => {
if (!_.isEmpty(entity.value) && !_.includes(this.config.entity, entity.value)) {
this.config.entity.push(entity.value);
}
});
}
if (_.isEqual(this.playTrailer.value, 'Yes')) {
this.config.playTrailer = true;
} else if (_.isEqual(this.playTrailer.value, 'No')) {
this.config.playTrailer = false;
} else if (_.isEqual(this.playTrailer.value, 'Muted')) {
this.config.playTrailer = 'muted';
}
if (_.isEqual(this.showExtras.value, 'Yes')) {
this.config.showExtras = true;
} else if (_.isEqual(this.showExtras.value, 'No')) {
this.config.showExtras = false;
}
if (_.isEqual(this.showSearch.value, 'Yes')) {
this.config.showSearch = true;
} else if (_.isEqual(this.showSearch.value, 'No')) {
this.config.showSearch = false;
}
this.config.runBefore = this.runBefore.value;
this.config.runAfter = this.runAfter.value;
3 years ago
}
}
if (!_.isEqual(this.config, originalConfig)) {
this.fireEvent(this, 'config-changed', { config: this.config });
3 years ago
}
};
render = async (): Promise<void> => {
const addDropdownItem = (text: string, disabled = false): HTMLElement => {
3 years ago
const libraryItem: any = document.createElement('paper-item');
libraryItem.innerHTML = text.replace(/ /g, '&nbsp;');
libraryItem.label = text;
if (disabled) {
libraryItem.disabled = true;
}
3 years ago
return libraryItem;
};
3 years ago
const createEntitiesDropdown = (selected: string, changeHandler: Function): HTMLElement | false => {
if (this.entitiesRegistry) {
const entitiesDropDown: any = document.createElement('paper-dropdown-menu');
const entities: any = document.createElement('paper-listbox');
3 years ago
entities.appendChild(addDropdownItem(''));
3 years ago
const addedEntityStrings: Array<string> = [];
3 years ago
_.forEach(this.entitiesRegistry, entityRegistry => {
if (
_.isEqual(entityRegistry.platform, 'cast') ||
_.isEqual(entityRegistry.platform, 'kodi') ||
_.isEqual(entityRegistry.platform, 'androidtv')
) {
3 years ago
const entityName = `${entityRegistry.platform} | ${entityRegistry.entity_id}`;
entities.appendChild(addDropdownItem(entityName));
addedEntityStrings.push(entityName);
3 years ago
}
});
3 years ago
_.forEach(this.clients, value => {
const entityName = `plexPlayer | ${value.name} | ${value.address} | ${value.machineIdentifier}`;
entities.appendChild(addDropdownItem(entityName));
addedEntityStrings.push(entityName);
});
if (_.isArray(this.config.entity)) {
_.forEach(this.config.entity, value => {
if (!_.includes(addedEntityStrings, value)) {
entities.appendChild(addDropdownItem(value));
addedEntityStrings.push(value);
}
});
}
3 years ago
entities.slot = 'dropdown-content';
entitiesDropDown.label = 'Entity';
entitiesDropDown.value = selected;
entitiesDropDown.appendChild(entities);
entitiesDropDown.style.width = '100%';
entitiesDropDown.className = 'entitiesDropDown';
entitiesDropDown.addEventListener('value-changed', changeHandler);
this.entities.push(entitiesDropDown);
return entitiesDropDown;
}
return false;
3 years ago
};
if (this.content) this.content.remove();
3 years ago
if (this.hassObj && !this.entitiesRegistry) {
3 years ago
_.forOwn(this.hassObj.states, (value, key) => {
if (_.startsWith(key, 'script.')) {
this.scriptEntities.push(key);
}
});
3 years ago
this.entitiesRegistry = await fetchEntityRegistry(this.hassObj.connection);
3 years ago
}
this.entities = [];
this.content = document.createElement('div');
3 years ago
const plexTitle = document.createElement('h2');
plexTitle.innerHTML = 'Plex Configuration';
3 years ago
plexTitle.style.margin = '0px';
plexTitle.style.padding = '0px';
3 years ago
this.content.appendChild(plexTitle);
3 years ago
this.protocol.innerHTML = '';
const protocolItems: any = document.createElement('paper-listbox');
// eslint-disable-next-line no-restricted-globals
const pageProtocol = location.protocol;
if (_.isEqual(pageProtocol, 'http:')) {
protocolItems.appendChild(addDropdownItem('http'));
}
3 years ago
protocolItems.appendChild(addDropdownItem('https'));
protocolItems.slot = 'dropdown-content';
this.protocol.label = 'Plex Protocol';
this.protocol.appendChild(protocolItems);
this.protocol.style.width = '100%';
this.protocol.addEventListener('value-changed', this.valueUpdated);
if (_.isEmpty(this.config.protocol)) {
if (_.isEqual(pageProtocol, 'http:')) {
this.protocol.value = 'http';
} else {
this.protocol.value = 'https';
}
3 years ago
} else {
this.protocol.value = this.config.protocol;
}
this.content.appendChild(this.protocol);
this.ip.label = 'Plex IP Address / Hostname';
if (this.config.ip) {
this.ip.value = this.config.ip.replace(/^https?\:\/\//i, '').replace(/\/$/, '');
} else {
this.ip.value = this.config.ip;
}
this.ip.addEventListener('change', this.valueUpdated);
this.content.appendChild(this.ip);
this.port.label = 'Plex Port (Optional)';
this.port.value = this.config.port;
this.port.type = 'number';
this.port.addEventListener('change', this.valueUpdated);
this.content.appendChild(this.port);
3 years ago
3 years ago
this.token.label = 'Plex Token';
this.token.value = this.config.token;
this.token.addEventListener('change', this.valueUpdated);
this.content.appendChild(this.token);
3 years ago
this.libraryName.innerHTML = '';
3 years ago
const libraryItems: any = document.createElement('paper-listbox');
libraryItems.appendChild(addDropdownItem('Smart Libraries', true));
3 years ago
libraryItems.appendChild(addDropdownItem('Continue Watching'));
libraryItems.appendChild(addDropdownItem('Deck'));
libraryItems.appendChild(addDropdownItem('Recently Added'));
libraryItems.appendChild(addDropdownItem('Watch Next'));
3 years ago
libraryItems.slot = 'dropdown-content';
this.libraryName.label = 'Plex Library';
this.libraryName.disabled = true;
this.libraryName.appendChild(libraryItems);
this.libraryName.style.width = '100%';
this.libraryName.addEventListener('value-changed', this.valueUpdated);
const warningLibrary = document.createElement('div');
warningLibrary.style.color = 'red';
this.content.appendChild(this.libraryName);
this.content.appendChild(warningLibrary);
3 years ago
3 years ago
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
);
3 years ago
this.sections = await this.plex.getSections();
this.livetv = await this.plex.getLiveTV();
this.collections = await this.plex.getCollections();
this.playlists = await this.plex.getPlaylists();
3 years ago
this.clients = await this.plex.getClients();
3 years ago
this.plexValidSection.style.display = 'none';
3 years ago
this.plexValidSection.innerHTML = '';
3 years ago
let hasUIConfig = true;
let canConvert = true;
if (_.isArray(this.config.entity)) {
// eslint-disable-next-line consistent-return
_.forEach(this.config.entity, entity => {
if (_.isObjectLike(entity)) {
canConvert = !_.includes(_.keys(this.config.entity), 'plexPlayer');
hasUIConfig = false;
return false;
}
});
} else if (_.isObjectLike(this.config.entity)) {
canConvert = !_.includes(_.keys(this.config.entity), 'plexPlayer');
hasUIConfig = false;
if (canConvert) {
const convertedEntities: Array<string> = [];
hasUIConfig = true;
if (_.isObjectLike(this.config.entity)) {
_.forOwn(this.config.entity, value => {
if (_.isString(value)) {
convertedEntities.push(value);
} else if (_.isArray(value)) {
_.forEach(value, valueStr => {
convertedEntities.push(valueStr);
});
}
});
}
this.config.entity = convertedEntities;
}
}
const devicesTitle = document.createElement('h2');
devicesTitle.innerHTML = `Devices Configuration`;
devicesTitle.style.lineHeight = '29px';
devicesTitle.style.marginBottom = '0px';
devicesTitle.style.marginTop = '20px';
if (hasUIConfig) {
const addDeviceButton = document.createElement('button');
addDeviceButton.style.float = 'right';
addDeviceButton.style.fontSize = '20px';
addDeviceButton.style.cursor = 'pointer';
addDeviceButton.innerHTML = '+';
addDeviceButton.addEventListener('click', () => {
const entitiesDropdown = createEntitiesDropdown('', this.valueUpdated);
if (entitiesDropdown) {
this.entitiesSection.appendChild(entitiesDropdown);
}
});
devicesTitle.appendChild(addDeviceButton);
}
this.plexValidSection.appendChild(devicesTitle);
this.entitiesSection.innerHTML = '';
this.plexValidSection.appendChild(this.entitiesSection);
if (hasUIConfig) {
if (_.isString(this.config.entity)) {
this.config.entity = [this.config.entity];
}
if (_.isArray(this.config.entity)) {
_.forEach(this.config.entity, entity => {
if (_.isString(entity)) {
const entitiesDropdown = createEntitiesDropdown(entity, this.valueUpdated);
if (entitiesDropdown) {
this.entitiesSection.appendChild(entitiesDropdown);
}
}
});
}
} else {
const entitiesUINotAvailable = document.createElement('div');
entitiesUINotAvailable.innerHTML =
3 years ago
'Devices configuration is not available when using plexPlayer client device.<br/>You can edit any other settings through UI and use <b>Show code editor</b> to edit entities.<br/><br/>If you are not using server settings for plexPlayer with <b>identifier</b> and <b>server</b> key, you can migrate your settings to UI by removing plexPlayer section and readd through UI.';
3 years ago
this.plexValidSection.appendChild(entitiesUINotAvailable);
}
3 years ago
const viewTitle = document.createElement('h2');
viewTitle.innerHTML = `View Configuration`;
viewTitle.style.lineHeight = '29px';
viewTitle.style.marginBottom = '0px';
viewTitle.style.marginTop = '20px';
this.plexValidSection.appendChild(viewTitle);
this.cardTitle.label = 'Card title (Optional)';
this.cardTitle.value = this.config.title;
this.cardTitle.addEventListener('change', this.valueUpdated);
this.plexValidSection.appendChild(this.cardTitle);
this.maxCount.label = 'Maximum number of items to display (Optional)';
3 years ago
this.maxCount.value = this.config.maxCount;
this.maxCount.type = 'number';
this.maxCount.addEventListener('change', this.valueUpdated);
this.plexValidSection.appendChild(this.maxCount);
this.useHorizontalScroll.innerHTML = '';
const useHorizontalScrollItems: any = document.createElement('paper-listbox');
useHorizontalScrollItems.appendChild(addDropdownItem('Yes'));
useHorizontalScrollItems.appendChild(addDropdownItem('No'));
useHorizontalScrollItems.slot = 'dropdown-content';
this.useHorizontalScroll.label = 'Use horizontal scroll';
this.useHorizontalScroll.appendChild(useHorizontalScrollItems);
this.useHorizontalScroll.style.width = '100%';
this.useHorizontalScroll.addEventListener('value-changed', this.valueUpdated);
if (_.isEmpty(this.config.useHorizontalScroll)) {
this.useHorizontalScroll.value = 'No';
} else {
this.useHorizontalScroll.value = this.config.useHorizontalScroll;
}
this.plexValidSection.appendChild(this.useHorizontalScroll);
this.maxRows.label = 'Maximum number of rows to display (Optional)';
this.maxRows.value = this.config.maxRows;
this.maxRows.type = 'number';
this.maxRows.addEventListener('change', this.valueUpdated);
this.plexValidSection.appendChild(this.maxRows);
3 years ago
this.sort.innerHTML = '';
3 years ago
3 years ago
const sortItems: any = document.createElement('paper-listbox');
sortItems.slot = 'dropdown-content';
this.sort.label = 'Sort';
this.sort.appendChild(sortItems);
this.sort.style.width = '100%';
this.sort.addEventListener('value-changed', this.valueUpdated);
this.plexValidSection.appendChild(this.sort);
this.sortOrder.innerHTML = '';
const sortOrderItems: any = document.createElement('paper-listbox');
3 years ago
sortOrderItems.appendChild(addDropdownItem('Ascending'));
sortOrderItems.appendChild(addDropdownItem('Descending'));
3 years ago
sortOrderItems.slot = 'dropdown-content';
this.sortOrder.label = 'Sort Order';
this.sortOrder.appendChild(sortOrderItems);
this.sortOrder.style.width = '100%';
this.sortOrder.addEventListener('value-changed', this.valueUpdated);
if (_.isEmpty(this.config.sort)) {
3 years ago
this.sortOrder.value = 'Ascending';
3 years ago
} else {
const sortOrder = this.config.sort.split(':')[1];
if (_.isEmpty(sortOrder)) {
3 years ago
this.sortOrder.value = 'Ascending';
} else if (_.isEqual(sortOrder, 'asc')) {
this.sortOrder.value = 'Ascending';
} else if (_.isEqual(sortOrder, 'desc')) {
this.sortOrder.value = 'Descending';
3 years ago
}
}
this.plexValidSection.appendChild(this.sortOrder);
3 years ago
this.playTrailer.innerHTML = '';
const playTrailerItems: any = document.createElement('paper-listbox');
playTrailerItems.appendChild(addDropdownItem('Yes'));
playTrailerItems.appendChild(addDropdownItem('Muted'));
playTrailerItems.appendChild(addDropdownItem('No'));
playTrailerItems.slot = 'dropdown-content';
this.playTrailer.label = 'Play Trailer';
this.playTrailer.appendChild(playTrailerItems);
this.playTrailer.style.width = '100%';
this.playTrailer.addEventListener('value-changed', this.valueUpdated);
let playTrailerValue = 'Yes';
if (_.isEqual(this.config.playTrailer, 'muted')) {
playTrailerValue = 'Muted';
} else if (!this.config.playTrailer) {
playTrailerValue = 'No';
}
this.playTrailer.value = playTrailerValue;
this.plexValidSection.appendChild(this.playTrailer);
3 years ago
this.showExtras.innerHTML = '';
const showExtrasItems: any = document.createElement('paper-listbox');
showExtrasItems.appendChild(addDropdownItem('Yes'));
showExtrasItems.appendChild(addDropdownItem('No'));
showExtrasItems.slot = 'dropdown-content';
this.showExtras.label = 'Show Extras';
this.showExtras.appendChild(showExtrasItems);
this.showExtras.style.width = '100%';
this.showExtras.addEventListener('value-changed', this.valueUpdated);
let showExtrasValue = 'Yes';
if (!this.config.showExtras) {
showExtrasValue = 'No';
}
this.showExtras.value = showExtrasValue;
this.plexValidSection.appendChild(this.showExtras);
3 years ago
this.showSearch.innerHTML = '';
const showSearchItems: any = document.createElement('paper-listbox');
showSearchItems.appendChild(addDropdownItem('Yes'));
showSearchItems.appendChild(addDropdownItem('No'));
showSearchItems.slot = 'dropdown-content';
this.showSearch.label = 'Show Search';
this.showSearch.appendChild(showSearchItems);
this.showSearch.style.width = '100%';
this.showSearch.addEventListener('value-changed', this.valueUpdated);
let showSearchValue = 'Yes';
if (!this.config.showSearch) {
showSearchValue = 'No';
}
this.showSearch.value = showSearchValue;
this.plexValidSection.appendChild(this.showSearch);
3 years ago
this.runBefore.innerHTML = '';
const runBeforeItems: any = document.createElement('paper-listbox');
runBeforeItems.appendChild(addDropdownItem(''));
_.forEach(this.scriptEntities, entity => {
runBeforeItems.appendChild(addDropdownItem(entity));
});
runBeforeItems.slot = 'dropdown-content';
this.runBefore.label = 'Script to execute before starting the media (Optional)';
3 years ago
this.runBefore.appendChild(runBeforeItems);
this.runBefore.style.width = '100%';
this.runBefore.addEventListener('value-changed', this.valueUpdated);
this.runBefore.value = this.config.runBefore;
this.plexValidSection.appendChild(this.runBefore);
this.runAfter.innerHTML = '';
const runAfterItems: any = document.createElement('paper-listbox');
runAfterItems.appendChild(addDropdownItem(''));
_.forEach(this.scriptEntities, entity => {
runAfterItems.appendChild(addDropdownItem(entity));
});
runAfterItems.slot = 'dropdown-content';
this.runAfter.label = 'Script to execute after starting the media (Optional)';
3 years ago
this.runAfter.appendChild(runAfterItems);
this.runAfter.style.width = '100%';
this.runAfter.addEventListener('value-changed', this.valueUpdated);
this.runAfter.value = this.config.runAfter;
this.plexValidSection.appendChild(this.runAfter);
const styleTitle = document.createElement('h2');
styleTitle.innerHTML = `Style Configuration`;
styleTitle.style.lineHeight = '29px';
styleTitle.style.marginBottom = '0px';
styleTitle.style.marginTop = '20px';
this.plexValidSection.appendChild(styleTitle);
this.minWidth.label = 'Minimum width of the card (Optional)';
this.minWidth.value = this.config.minWidth;
this.minWidth.type = 'number';
this.minWidth.addEventListener('change', this.valueUpdated);
this.plexValidSection.appendChild(this.minWidth);
this.minExpandedWidth.label = 'Expanded width of the card (Optional)';
this.minExpandedWidth.value = this.config.minExpandedWidth;
this.minExpandedWidth.type = 'number';
this.minExpandedWidth.addEventListener('change', this.valueUpdated);
this.plexValidSection.appendChild(this.minExpandedWidth);
this.minExpandedHeight.label = 'Expanded height of the card (Optional)';
this.minExpandedHeight.value = this.config.minExpandedHeight;
this.minExpandedHeight.type = 'number';
this.minExpandedHeight.addEventListener('change', this.valueUpdated);
this.plexValidSection.appendChild(this.minExpandedHeight);
this.minEpisodeWidth.label = 'Minimum width of the episode card (Optional)';
this.minEpisodeWidth.value = this.config.minEpisodeWidth;
this.minEpisodeWidth.type = 'number';
this.minEpisodeWidth.addEventListener('change', this.valueUpdated);
this.plexValidSection.appendChild(this.minEpisodeWidth);
this.displayTitleMain.innerHTML = '';
const displayTitleMainItems: any = document.createElement('paper-listbox');
displayTitleMainItems.appendChild(addDropdownItem('Yes'));
displayTitleMainItems.appendChild(addDropdownItem('No'));
displayTitleMainItems.slot = 'dropdown-content';
this.displayTitleMain.label = 'Display title under poster';
this.displayTitleMain.appendChild(displayTitleMainItems);
this.displayTitleMain.style.width = '100%';
this.displayTitleMain.addEventListener('value-changed', this.valueUpdated);
if (_.isEmpty(this.config.displayTitleMain)) {
this.displayTitleMain.value = 'Yes';
} else {
this.displayTitleMain.value = this.config.displayTitleMain;
}
this.plexValidSection.appendChild(this.displayTitleMain);
this.fontSize1.label = 'Font size used in titles under cards (Optional)';
this.fontSize1.value = this.config.fontSize1;
this.fontSize1.type = 'number';
this.fontSize1.addEventListener('change', this.valueUpdated);
this.plexValidSection.appendChild(this.fontSize1);
this.displaySubtitleMain.innerHTML = '';
const displaySubtitleMainItems: any = document.createElement('paper-listbox');
displaySubtitleMainItems.appendChild(addDropdownItem('Yes'));
displaySubtitleMainItems.appendChild(addDropdownItem('No'));
displaySubtitleMainItems.slot = 'dropdown-content';
this.displaySubtitleMain.label = 'Display sub-title under poster';
this.displaySubtitleMain.appendChild(displaySubtitleMainItems);
this.displaySubtitleMain.style.width = '100%';
this.displaySubtitleMain.addEventListener('value-changed', this.valueUpdated);
if (_.isEmpty(this.config.displaySubtitleMain)) {
this.displaySubtitleMain.value = 'Yes';
} else {
this.displaySubtitleMain.value = this.config.displaySubtitleMain;
}
this.plexValidSection.appendChild(this.displaySubtitleMain);
this.fontSize2.label = 'Font size used in sub-titles under cards (Optional)';
this.fontSize2.value = this.config.fontSize2;
this.fontSize2.type = 'number';
this.fontSize2.addEventListener('change', this.valueUpdated);
this.plexValidSection.appendChild(this.fontSize2);
this.fontSize3.label = 'Font size used in title of the opened content (Optional)';
this.fontSize3.value = this.config.fontSize3;
this.fontSize3.type = 'number';
this.fontSize3.addEventListener('change', this.valueUpdated);
this.plexValidSection.appendChild(this.fontSize3);
this.fontSize4.label =
'Font size used in sub-titles, to-view count and description of the opened content (Optional)';
this.fontSize4.value = this.config.fontSize4;
this.fontSize4.type = 'number';
this.fontSize4.addEventListener('change', this.valueUpdated);
this.plexValidSection.appendChild(this.fontSize4);
if (!_.isEmpty(this.livetv)) {
libraryItems.appendChild(addDropdownItem('Live TV', true));
_.forEach(_.keys(this.livetv), (livetv: string) => {
if (_.isEqual(this.config.libraryName, livetv)) {
warningLibrary.innerHTML = `Warning: ${this.config.libraryName} play action currently only supported with Kodi.<br/>You might also need custom build of kodi-media-sensors, see <a href="https://github.com/JurajNyiri/PlexMeetsHomeAssistant/blob/main/DETAILED_CONFIGURATION.md#kodi" target="_blank">detailed configuration</a> for more information.`;
}
libraryItems.appendChild(addDropdownItem(livetv));
});
}
3 years ago
if (!_.isEmpty(this.sections)) {
libraryItems.appendChild(addDropdownItem('Libraries', true));
3 years ago
_.forEach(this.sections, (section: Record<string, any>) => {
libraryItems.appendChild(addDropdownItem(section.title));
});
if (!_.isEmpty(this.collections)) {
libraryItems.appendChild(addDropdownItem('Collections', true));
_.forEach(this.collections, (collection: Record<string, any>) => {
libraryItems.appendChild(addDropdownItem(collection.title));
});
}
if (!_.isEmpty(this.playlists)) {
libraryItems.appendChild(addDropdownItem('Playlists', true));
_.forEach(this.playlists, (playlist: Record<string, any>) => {
libraryItems.appendChild(addDropdownItem(playlist.title));
});
}
3 years ago
this.libraryName.disabled = false;
this.libraryName.value = this.config.libraryName;
3 years ago
let libraryType = '';
3 years ago
// eslint-disable-next-line consistent-return
3 years ago
_.forEach(this.sections, section => {
if (_.isEqual(section.title, this.libraryName.value)) {
libraryType = section.type;
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';
} else {
this.sort.style.display = 'none';
this.sortOrder.style.display = 'none';
this.config.sort = '';
}
if (_.isEmpty(this.config.sort)) {
this.sort.value = '';
this.sortOrder.value = '';
} else {
// eslint-disable-next-line prefer-destructuring
this.sort.value = this.config.sort.split(':')[0];
const sortOrder = this.config.sort.split(':')[1];
if (_.isEmpty(sortOrder)) {
this.sortOrder.value = 'Ascending';
} else if (_.isEqual(sortOrder, 'asc')) {
this.sortOrder.value = 'Ascending';
} else if (_.isEqual(sortOrder, 'desc')) {
this.sortOrder.value = 'Descending';
}
}
3 years ago
this.plexValidSection.style.display = 'block';
}
3 years ago
this.loaded = true;
3 years ago
this.content.appendChild(this.plexValidSection);
};
setConfig = (config: Record<string, any>): void => {
this.config = JSON.parse(JSON.stringify(config));
3 years ago
if (config.port && !_.isEqual(config.port, '')) {
this.plexPort = config.port;
3 years ago
} else {
this.plexPort = false;
}
// eslint-disable-next-line no-restricted-globals
const pageProtocol = location.protocol;
if (config.protocol) {
this.plexProtocol = config.protocol;
} else if (_.isEqual(pageProtocol, 'http:')) {
3 years ago
this.config.protocol = 'http';
} else {
this.config.protocol = 'https';
}
3 years ago
if (!config.sort) {
this.config.sort = 'titleSort:asc';
}
3 years ago
if (!_.isNil(config.playTrailer)) {
this.config.playTrailer = config.playTrailer;
} else {
this.config.playTrailer = true;
}
3 years ago
if (!_.isNil(config.showExtras)) {
this.config.showExtras = config.showExtras;
} else {
this.config.showExtras = true;
}
3 years ago
if (!_.isNil(config.showSearch)) {
this.config.showSearch = config.showSearch;
} else {
this.config.showSearch = true;
}
3 years ago
if (!_.isNil(config.runBefore)) {
this.config.runBefore = config.runBefore;
}
if (!_.isNil(config.runAfter)) {
this.config.runAfter = config.runAfter;
}
if (!_.isNil(config.title)) {
this.config.title = config.title;
}
if (_.isNumber(this.config.maxCount)) {
this.config.maxCount = `${this.config.maxCount}`;
}
if (_.isNumber(this.config.maxRows)) {
this.config.maxRows = `${this.config.maxRows}`;
}
if (!_.isNil(this.config.useHorizontalScroll)) {
this.config.useHorizontalScroll = `${this.config.useHorizontalScroll}`;
}
if (!_.isNil(this.config.displayTitleMain)) {
this.config.displayTitleMain = `${this.config.displayTitleMain}`;
}
if (!_.isNil(this.config.displaySubtitleMain)) {
this.config.displaySubtitleMain = `${this.config.displaySubtitleMain}`;
}
if (_.isNumber(this.config.minWidth)) {
this.config.minWidth = `${this.config.minWidth}`;
}
if (_.isNumber(this.config.minEpisodeWidth)) {
this.config.minEpisodeWidth = `${this.config.minEpisodeWidth}`;
}
if (_.isNumber(this.config.minExpandedWidth)) {
this.config.minExpandedWidth = `${this.config.minExpandedWidth}`;
}
if (_.isNumber(this.config.fontSize1)) {
this.config.fontSize1 = `${this.config.fontSize1}`;
}
if (_.isNumber(this.config.fontSize2)) {
this.config.fontSize2 = `${this.config.fontSize2}`;
}
if (_.isNumber(this.config.fontSize3)) {
this.config.fontSize3 = `${this.config.fontSize3}`;
}
if (_.isNumber(this.config.fontSize4)) {
this.config.fontSize4 = `${this.config.fontSize4}`;
}
if (_.isNumber(this.config.minExpandedHeight)) {
this.config.minExpandedHeight = `${this.config.minExpandedHeight}`;
}
this.render();
};
configChanged = (newConfig: any): void => {
const event: any = new Event('config-changed', {
bubbles: true,
composed: true
});
event.detail = { config: newConfig };
this.dispatchEvent(event);
};
3 years ago
set hass(hass: HomeAssistant) {
this.hassObj = hass;
}
}
export default PlexMeetsHomeAssistantEditor;