diff --git a/DETAILED_CONFIGURATION.md b/DETAILED_CONFIGURATION.md index b95ee0f..adeced6 100644 --- a/DETAILED_CONFIGURATION.md +++ b/DETAILED_CONFIGURATION.md @@ -52,6 +52,8 @@ You can also use Live TV library by specifying its name, usually "Live TV & DVR" **useHorizontalScroll:** _Optional_ Specify whether to use horizontal infinite scroll. Possible values: On, Off. Default: Off +**useShuffle:** _Optional_ Specify whether to use shuffle on music. Possible values: On, Off. Default: Off + **displayTitleMain:** _Optional_ Specify whether to display title under poster. Possible values: On, Off. Default: Off **displaySubtitleMain:** _Optional_ Specify whether to display subtitle under poster. Possible values: On, Off. Default: Off diff --git a/dist/plex-meets-homeassistant.js b/dist/plex-meets-homeassistant.js index 0f0e1d1..0c89c30 100644 --- a/dist/plex-meets-homeassistant.js +++ b/dist/plex-meets-homeassistant.js @@ -19418,7 +19418,7 @@ const isScrolledIntoView = (elem) => { }; class PlayController { - constructor(card, hass, plex, entity, runBefore, runAfter, libraryName, entityRegistry) { + constructor(card, hass, plex, entity, runBefore, runAfter, libraryName, entityRegistry, shuffle) { this.playButtons = []; this.readyPlayersForType = {}; this.entityStates = {}; @@ -19429,6 +19429,7 @@ class PlayController { this.playActionButton = document.createElement('button'); this.playActionClickFunction = false; this.entityRegistry = []; + this.shuffle = false; this.getKodiSearchResults = async () => { return JSON.parse((await getState(this.hass, 'sensor.kodi_media_sensor_search')).attributes.data); }; @@ -19538,7 +19539,7 @@ class PlayController { library_name: libraryName, // eslint-disable-next-line @typescript-eslint/camelcase artist_name: processData.title, - shuffle: 1 + shuffle: this.shuffle ? 1 : 0 })}`); break; case 'album': @@ -19549,7 +19550,7 @@ class PlayController { artist_name: processData.parentTitle, // eslint-disable-next-line @typescript-eslint/camelcase album_name: processData.title, - shuffle: 1 + shuffle: this.shuffle ? 1 : 0 })}`); break; case 'track': @@ -19562,7 +19563,7 @@ class PlayController { album_name: processData.parentTitle, // eslint-disable-next-line @typescript-eslint/camelcase track_name: processData.title, - shuffle: 1 + shuffle: this.shuffle ? 1 : 0 })}`); break; case 'movie': @@ -19598,8 +19599,11 @@ class PlayController { this.playViaCast(entity.value, processData.Media[0].Part[0].key); } } + else if (!lodash.isNil(lodash.get(processData, 'Media[0].Part[0].key'))) { + this.playViaCast(entity.value, lodash.get(processData, 'Media[0].Part[0].key')); + } else { - this.playViaCast(entity.value, processData.Media[0].Part[0].key); + throw Error(`No service available to play ${processData.title}!`); } break; default: @@ -20140,6 +20144,7 @@ class PlayController { this.hass = hass; this.plex = plex; this.entity = entity; + this.shuffle = shuffle; this.libraryName = libraryName; if (!lodash.isEmpty(runBefore) && this.hass.states[runBefore]) { this.runBefore = runBefore.split('.'); @@ -20168,6 +20173,7 @@ class PlexMeetsHomeAssistantEditor extends HTMLElement { this.displayTitleMain = document.createElement('paper-dropdown-menu'); this.displaySubtitleMain = document.createElement('paper-dropdown-menu'); this.useHorizontalScroll = document.createElement('paper-dropdown-menu'); + this.useShuffle = document.createElement('paper-dropdown-menu'); this.minWidth = document.createElement('paper-input'); this.minEpisodeWidth = document.createElement('paper-input'); this.minExpandedWidth = document.createElement('paper-input'); @@ -20256,6 +20262,12 @@ class PlexMeetsHomeAssistantEditor extends HTMLElement { else { this.config.useHorizontalScroll = this.useHorizontalScroll.value; } + if (lodash.isEmpty(this.useShuffle.value)) { + this.config.useShuffle = 'No'; + } + else { + this.config.useShuffle = this.useShuffle.value; + } if (lodash.isEmpty(this.displayTitleMain.value)) { this.config.displayTitleMain = 'Yes'; } @@ -20495,6 +20507,27 @@ class PlexMeetsHomeAssistantEditor extends HTMLElement { 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.sections = await this.plex.getSections(); + lodash.forEach(this.sections, section => { + if (lodash.isEqual(section.title, this.config.libraryName) && lodash.isEqual(section.type, 'artist')) { + this.useShuffle.innerHTML = ''; + const useShuffleItems = document.createElement('paper-listbox'); + useShuffleItems.appendChild(addDropdownItem('Yes')); + useShuffleItems.appendChild(addDropdownItem('No')); + useShuffleItems.slot = 'dropdown-content'; + this.useShuffle.label = 'Use shuffle when playing'; + this.useShuffle.appendChild(useShuffleItems); + this.useShuffle.style.width = '100%'; + this.useShuffle.addEventListener('value-changed', this.valueUpdated); + if (lodash.isEmpty(this.config.useShuffle)) { + this.useShuffle.value = 'No'; + } + else { + this.useShuffle.value = this.config.useShuffle; + } + this.content.appendChild(this.useShuffle); + return false; + } + }); this.livetv = await this.plex.getLiveTV(); this.collections = await this.plex.getCollections(); this.playlists = await this.plex.getPlaylists(); @@ -21002,6 +21035,9 @@ class PlexMeetsHomeAssistantEditor extends HTMLElement { if (!lodash.isNil(this.config.useHorizontalScroll)) { this.config.useHorizontalScroll = `${this.config.useHorizontalScroll}`; } + if (!lodash.isNil(this.config.useShuffle)) { + this.config.useShuffle = `${this.config.useShuffle}`; + } if (!lodash.isNil(this.config.displayTitleMain)) { this.config.displayTitleMain = `${this.config.displayTitleMain}`; } @@ -21855,6 +21891,7 @@ class PlexMeetsHomeAssistant extends HTMLElement { this.plexProtocol = 'http'; this.displayType = false; this.useHorizontalScroll = false; + this.useShuffle = false; this.displayTitleMain = true; this.displaySubtitleMain = true; this.plexPort = false; @@ -22077,7 +22114,7 @@ class PlexMeetsHomeAssistant extends HTMLElement { this.renderPage(); try { if (this.plex && this.hassObj) { - this.playController = new PlayController(this, this.hassObj, this.plex, entity, this.runBefore, this.runAfter, this.config.libraryName, this.entityRegistry); + this.playController = new PlayController(this, this.hassObj, this.plex, entity, this.runBefore, this.runAfter, this.config.libraryName, this.entityRegistry, this.useShuffle); if (this.playController) { await this.playController.init(); } @@ -23691,6 +23728,9 @@ class PlexMeetsHomeAssistant extends HTMLElement { if (config.useHorizontalScroll && lodash.isEqual(config.useHorizontalScroll, 'Yes')) { this.useHorizontalScroll = true; } + if (config.useShuffle && lodash.isEqual(config.useShuffle, 'Yes')) { + this.useShuffle = true; + } if (config.displayTitleMain && lodash.isEqual(config.displayTitleMain, 'No')) { this.displayTitleMain = false; } diff --git a/src/editor.ts b/src/editor.ts index 8d5fb66..6fba84b 100644 --- a/src/editor.ts +++ b/src/editor.ts @@ -32,6 +32,8 @@ class PlexMeetsHomeAssistantEditor extends HTMLElement { useHorizontalScroll: any = document.createElement('paper-dropdown-menu'); + useShuffle: any = document.createElement('paper-dropdown-menu'); + minWidth: any = document.createElement('paper-input'); minEpisodeWidth: any = document.createElement('paper-input'); @@ -161,6 +163,12 @@ class PlexMeetsHomeAssistantEditor extends HTMLElement { this.config.useHorizontalScroll = this.useHorizontalScroll.value; } + if (_.isEmpty(this.useShuffle.value)) { + this.config.useShuffle = 'No'; + } else { + this.config.useShuffle = this.useShuffle.value; + } + if (_.isEmpty(this.displayTitleMain.value)) { this.config.displayTitleMain = 'Yes'; } else { @@ -418,6 +426,26 @@ class PlexMeetsHomeAssistantEditor extends HTMLElement { ); this.sections = await this.plex.getSections(); + _.forEach(this.sections, section => { + if (_.isEqual(section.title, this.config.libraryName) && _.isEqual(section.type, 'artist')) { + this.useShuffle.innerHTML = ''; + const useShuffleItems: any = document.createElement('paper-listbox'); + useShuffleItems.appendChild(addDropdownItem('Yes')); + useShuffleItems.appendChild(addDropdownItem('No')); + useShuffleItems.slot = 'dropdown-content'; + this.useShuffle.label = 'Use shuffle when playing'; + this.useShuffle.appendChild(useShuffleItems); + this.useShuffle.style.width = '100%'; + this.useShuffle.addEventListener('value-changed', this.valueUpdated); + if (_.isEmpty(this.config.useShuffle)) { + this.useShuffle.value = 'No'; + } else { + this.useShuffle.value = this.config.useShuffle; + } + this.content.appendChild(this.useShuffle); + return false; + } + }); this.livetv = await this.plex.getLiveTV(); this.collections = await this.plex.getCollections(); this.playlists = await this.plex.getPlaylists(); @@ -954,6 +982,10 @@ class PlexMeetsHomeAssistantEditor extends HTMLElement { this.config.useHorizontalScroll = `${this.config.useHorizontalScroll}`; } + if (!_.isNil(this.config.useShuffle)) { + this.config.useShuffle = `${this.config.useShuffle}`; + } + if (!_.isNil(this.config.displayTitleMain)) { this.config.displayTitleMain = `${this.config.displayTitleMain}`; } diff --git a/src/modules/PlayController.ts b/src/modules/PlayController.ts index bca777b..a8ef869 100644 --- a/src/modules/PlayController.ts +++ b/src/modules/PlayController.ts @@ -40,6 +40,8 @@ class PlayController { entityRegistry: Array> = []; + shuffle = false; + constructor( card: any, hass: HomeAssistant, @@ -48,13 +50,15 @@ class PlayController { runBefore: string, runAfter: string, libraryName: string, - entityRegistry: Array> + entityRegistry: Array>, + shuffle: boolean ) { this.entityRegistry = entityRegistry; this.card = card; this.hass = hass; this.plex = plex; this.entity = entity; + this.shuffle = shuffle; this.libraryName = libraryName; if (!_.isEmpty(runBefore) && this.hass.states[runBefore]) { this.runBefore = runBefore.split('.'); @@ -186,7 +190,7 @@ class PlayController { library_name: libraryName, // eslint-disable-next-line @typescript-eslint/camelcase artist_name: processData.title, - shuffle: 1 + shuffle: this.shuffle ? 1 : 0 })}` ); break; @@ -201,7 +205,7 @@ class PlayController { artist_name: processData.parentTitle, // eslint-disable-next-line @typescript-eslint/camelcase album_name: processData.title, - shuffle: 1 + shuffle: this.shuffle ? 1 : 0 })}` ); break; @@ -218,7 +222,7 @@ class PlayController { album_name: processData.parentTitle, // eslint-disable-next-line @typescript-eslint/camelcase track_name: processData.title, - shuffle: 1 + shuffle: this.shuffle ? 1 : 0 })}` ); break; @@ -260,8 +264,10 @@ class PlayController { console.log(err); this.playViaCast(entity.value, processData.Media[0].Part[0].key); } + } else if (!_.isNil(_.get(processData, 'Media[0].Part[0].key'))) { + this.playViaCast(entity.value, _.get(processData, 'Media[0].Part[0].key')); } else { - this.playViaCast(entity.value, processData.Media[0].Part[0].key); + throw Error(`No service available to play ${processData.title}!`); } break; default: diff --git a/src/plex-meets-homeassistant.ts b/src/plex-meets-homeassistant.ts index e940291..c1abe84 100644 --- a/src/plex-meets-homeassistant.ts +++ b/src/plex-meets-homeassistant.ts @@ -41,6 +41,8 @@ class PlexMeetsHomeAssistant extends HTMLElement { useHorizontalScroll = false; + useShuffle = false; + displayTitleMain = true; displaySubtitleMain = true; @@ -379,7 +381,8 @@ class PlexMeetsHomeAssistant extends HTMLElement { this.runBefore, this.runAfter, this.config.libraryName, - this.entityRegistry + this.entityRegistry, + this.useShuffle ); if (this.playController) { await this.playController.init(); @@ -2145,6 +2148,9 @@ class PlexMeetsHomeAssistant extends HTMLElement { if (config.useHorizontalScroll && _.isEqual(config.useHorizontalScroll, 'Yes')) { this.useHorizontalScroll = true; } + if (config.useShuffle && _.isEqual(config.useShuffle, 'Yes')) { + this.useShuffle = true; + } if (config.displayTitleMain && _.isEqual(config.displayTitleMain, 'No')) { this.displayTitleMain = false; }