@ -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,8 +23077,56 @@ 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 ` ;
}
}
if ( lodash . isEqual ( lodash . get ( childrenData [ 0 ] , 'type' ) , 'track' ) ) {
if ( this . episodesElem ) {
this . episodesElemHidden = false ;
this . episodesElem . style . display = 'block' ;
this . episodesElem . innerHTML = '' ;
this . episodesElem . style . transition = ` 0s ` ;
this . episodesElem . style . top = ` ${ top + 2000 } px ` ;
const tableView = document . createElement ( 'table' ) ;
tableView . style . width = 'calc(100% - 10px)' ;
tableView . style . border = 'none' ;
tableView . cellSpacing = '0' ;
tableView . cellPadding = '0' ;
if ( lodash . isEqual ( data . type , 'album' ) ) {
this . episodesElem . append ( tableView ) ;
}
let isEven = false ;
lodash . forEach ( childrenData , childData => {
if ( this . episodesElem && this . playController && this . plex ) {
if ( lodash . isEqual ( childData . type , 'track' ) ) {
tableView . append ( createTrackView ( this . playController , this . plex , childData , this . fontSize1 , this . fontSize2 , isEven ) ) ;
isEven = ! isEven ;
}
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 ` ;
}
this . resizeBackground ( ) ;
}
} , 200 ) ;
clearInterval ( this . episodesElemFreshlyLoadedTimeout ) ;
this . episodesElemFreshlyLoadedTimeout = setTimeout ( ( ) => {
this . episodesElemFreshlyLoaded = false ;
} , 700 ) ;
}
}
else {
lodash . forEach ( childrenData , childData => {
lodash . forEach ( childrenData , childData => {
if ( this . seasonsElem && this . plex ) {
if ( this . seasonsElem && this . plex ) {
console . log ( childData ) ;
this . seasonsElemHidden = false ;
this . seasonsElemHidden = false ;
const seasonContainer = document . createElement ( 'div' ) ;
const seasonContainer = document . createElement ( 'div' ) ;
seasonContainer . className = 'seasonContainer' ;
seasonContainer . className = 'seasonContainer' ;
@ -23235,6 +23350,7 @@ class PlexMeetsHomeAssistant extends HTMLElement {
}
}
} , 200 ) ;
} , 200 ) ;
}
}
}
else {
else {
this . episodesElemFreshlyLoaded = true ;
this . episodesElemFreshlyLoaded = true ;
if ( this . episodesElem ) {
if ( this . episodesElem ) {
@ -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 ;
}
}