From 75257220cd8cf53dccc7aecaca23b1e7565262b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juraj=20Nyi=CC=81ri?= Date: Sun, 4 Jul 2021 16:23:59 +0200 Subject: [PATCH 1/6] Add: clickHandler supporting hold and click actions --- dist/plex-meets-homeassistant.js | 49 +++++++++++++++++++++++++++++- src/modules/PlayController.ts | 1 + src/modules/utils.ts | 52 +++++++++++++++++++++++++++++++- src/plex-meets-homeassistant.ts | 21 +++++++++---- 4 files changed, 115 insertions(+), 8 deletions(-) diff --git a/dist/plex-meets-homeassistant.js b/dist/plex-meets-homeassistant.js index eebd9ca..ab331bf 100644 --- a/dist/plex-meets-homeassistant.js +++ b/dist/plex-meets-homeassistant.js @@ -18893,6 +18893,7 @@ class PlayController { return foundResult; }; this.play = async (data, instantPlay = false) => { + console.log(data); if (lodash.isArray(this.runBefore)) { await this.hass.callService(this.runBefore[0], this.runBefore[1], {}); } @@ -19205,7 +19206,49 @@ const findTrailerURL = (movieData) => { } return foundURL; }; +const clickHandler = (elem, clickFunction, holdFunction) => { + let longpress = false; + let presstimer = null; + const cancel = (e) => { + e.stopPropagation(); + if (presstimer !== null) { + clearTimeout(presstimer); + presstimer = null; + } + }; + const click = (e) => { + e.stopPropagation(); + if (presstimer !== null) { + clearTimeout(presstimer); + presstimer = null; + } + if (longpress) { + return false; + } + clickFunction(e); + return true; + }; + const start = (e) => { + e.stopPropagation(); + if (e.type === 'click' && e.button !== 0) { + return; + } + longpress = false; + presstimer = setTimeout(() => { + holdFunction(e); + longpress = true; + }, 1000); + }; + elem.addEventListener('mousedown', start); + elem.addEventListener('touchstart', start); + elem.addEventListener('click', click); + elem.addEventListener('mouseout', cancel); + elem.addEventListener('touchend', cancel); + elem.addEventListener('touchleave', cancel); + elem.addEventListener('touchcancel', cancel); +}; const createEpisodesView = (playController, plex, data) => { + console.log(data); const episodeContainer = document.createElement('div'); episodeContainer.className = 'episodeContainer'; episodeContainer.style.width = `${CSS_STYLE.episodeWidth}px`; @@ -21140,11 +21183,15 @@ class PlexMeetsHomeAssistant extends HTMLElement { interactiveArea.append(playButton); } movieElem.append(interactiveArea); - playButton.addEventListener('click', event => { + clickHandler(playButton, (event) => { + console.log('click'); event.stopPropagation(); if (this.hassObj && this.playController) { this.playController.play(data, true); } + }, (event) => { + console.log('hold'); + event.stopPropagation(); }); const titleElem = document.createElement('div'); if (lodash.isEqual(data.type, 'episode')) { diff --git a/src/modules/PlayController.ts b/src/modules/PlayController.ts index 2cc78e2..47899df 100644 --- a/src/modules/PlayController.ts +++ b/src/modules/PlayController.ts @@ -96,6 +96,7 @@ class PlayController { }; play = async (data: Record, instantPlay = false): Promise => { + console.log(data); if (_.isArray(this.runBefore)) { await this.hass.callService(this.runBefore[0], this.runBefore[1], {}); } diff --git a/src/modules/utils.ts b/src/modules/utils.ts index d467e48..3089a0e 100644 --- a/src/modules/utils.ts +++ b/src/modules/utils.ts @@ -104,8 +104,57 @@ const findTrailerURL = (movieData: Record): string => { } return foundURL; }; +const clickHandler = (elem: HTMLButtonElement, clickFunction: Function, holdFunction: Function): void => { + let longpress = false; + let presstimer: any = null; + + const cancel = (e: any): void => { + e.stopPropagation(); + if (presstimer !== null) { + clearTimeout(presstimer); + presstimer = null; + } + }; + + const click = (e: any): boolean => { + e.stopPropagation(); + if (presstimer !== null) { + clearTimeout(presstimer); + presstimer = null; + } + + if (longpress) { + return false; + } + + clickFunction(e); + return true; + }; + + const start = (e: any): void => { + e.stopPropagation(); + if (e.type === 'click' && e.button !== 0) { + return; + } + + longpress = false; + + presstimer = setTimeout(() => { + holdFunction(e); + longpress = true; + }, 1000); + }; + elem.addEventListener('mousedown', start); + elem.addEventListener('touchstart', start); + elem.addEventListener('click', click); + elem.addEventListener('mouseout', cancel); + elem.addEventListener('touchend', cancel); + elem.addEventListener('touchleave', cancel); + elem.addEventListener('touchcancel', cancel); +}; const createEpisodesView = (playController: PlayController, plex: Plex, data: Record): HTMLElement => { + console.log(data); const episodeContainer = document.createElement('div'); episodeContainer.className = 'episodeContainer'; episodeContainer.style.width = `${CSS_STYLE.episodeWidth}px`; @@ -206,5 +255,6 @@ export { hasEpisodes, getOldPlexServerErrorMessage, getWidth, - getDetailsBottom + getDetailsBottom, + clickHandler }; diff --git a/src/plex-meets-homeassistant.ts b/src/plex-meets-homeassistant.ts index b9a0b0b..dc93f8a 100644 --- a/src/plex-meets-homeassistant.ts +++ b/src/plex-meets-homeassistant.ts @@ -15,7 +15,8 @@ import { isVideoFullScreen, hasEpisodes, getOldPlexServerErrorMessage, - getDetailsBottom + getDetailsBottom, + clickHandler } from './modules/utils'; import style from './modules/style'; @@ -1362,13 +1363,21 @@ class PlexMeetsHomeAssistant extends HTMLElement { movieElem.append(interactiveArea); - playButton.addEventListener('click', event => { - event.stopPropagation(); + clickHandler( + playButton, + (event: any): void => { + console.log('click'); + event.stopPropagation(); - if (this.hassObj && this.playController) { - this.playController.play(data, true); + if (this.hassObj && this.playController) { + this.playController.play(data, true); + } + }, + (event: any): void => { + console.log('hold'); + event.stopPropagation(); } - }); + ); const titleElem = document.createElement('div'); if (_.isEqual(data.type, 'episode')) { From a41077987333cc890518444084175f5abea734e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juraj=20Nyi=CC=81ri?= Date: Sun, 4 Jul 2021 19:51:47 +0200 Subject: [PATCH 2/6] Add: WIP Support for client servers for plexPlayer --- dist/plex-meets-homeassistant.js | 68 ++++++++++++++++++++++++++---- src/modules/PlayController.ts | 72 ++++++++++++++++++++++++++++++-- src/plex-meets-homeassistant.ts | 18 ++++---- 3 files changed, 138 insertions(+), 20 deletions(-) diff --git a/dist/plex-meets-homeassistant.js b/dist/plex-meets-homeassistant.js index ab331bf..25fa417 100644 --- a/dist/plex-meets-homeassistant.js +++ b/dist/plex-meets-homeassistant.js @@ -19062,9 +19062,59 @@ class PlayController { }); return service; }; - this.getPlexPlayerMachineIdentifier = (entityName) => { + this.init = async () => { + if (!lodash.isNil(this.entity.plexPlayer)) { + if (lodash.isArray(this.entity.plexPlayer)) { + for (let i = 0; i < this.entity.plexPlayer.length; i += 1) { + if (lodash.isObjectLike(this.entity.plexPlayer[i]) && !lodash.isNil(this.entity.plexPlayer[i].server)) { + let port = false; + if (!lodash.isNil(this.entity.plexPlayer[i].server.port)) { + port = this.entity.plexPlayer[i].server.port; + } + let protocol = 'http'; + if (!lodash.isNil(this.entity.plexPlayer[i].server.protocol)) { + protocol = this.entity.plexPlayer[i].server.protocol; + } + // eslint-disable-next-line no-param-reassign + this.entity.plexPlayer[i].plex = new Plex(this.entity.plexPlayer[i].server.ip, port, this.entity.plexPlayer[i].server.token, protocol); + // eslint-disable-next-line no-await-in-loop + await this.entity.plexPlayer[i].plex.getClients(); + } + } + } + else if (!lodash.isNil(this.entity.plexPlayer.server) && + !lodash.isNil(this.entity.plexPlayer.server.ip) && + !lodash.isNil(this.entity.plexPlayer.server.token)) { + let port = false; + if (!lodash.isNil(this.entity.plexPlayer.server.port)) { + port = this.entity.plexPlayer.server.port; + } + let protocol = 'http'; + if (!lodash.isNil(this.entity.plexPlayer.server.protocol)) { + protocol = this.entity.plexPlayer.server.protocol; + } + // eslint-disable-next-line no-param-reassign + this.entity.plexPlayer.plex = new Plex(this.entity.plexPlayer.server.ip, port, this.entity.plexPlayer.server.token, protocol); + // eslint-disable-next-line no-await-in-loop + await this.entity.plexPlayer.plex.getClients(); + } + } + }; + this.getPlexPlayerMachineIdentifier = (entity) => { let machineIdentifier = ''; - lodash.forEach(this.plex.clients, plexClient => { + let { plex } = this; + let entityName = ''; + if (lodash.isString(entity)) { + entityName = entity; + } + else if (lodash.isObjectLike(entity) && !lodash.isNil(entity.identifier)) { + entityName = entity.identifier; + if (!lodash.isNil(entity.plex) && entity.plex) { + plex = entity.plex; + } + } + console.log(plex.clients); + lodash.forEach(plex.clients, plexClient => { if (lodash.isEqual(plexClient.machineIdentifier, entityName) || lodash.isEqual(plexClient.product, entityName) || lodash.isEqual(plexClient.name, entityName) || @@ -19079,9 +19129,9 @@ class PlayController { this.isPlaySupported = (data) => { return !lodash.isEmpty(this.getPlayService(data)); }; - this.isPlexPlayerSupported = (entityName) => { + this.isPlexPlayerSupported = (entity) => { let found = false; - if (this.getPlexPlayerMachineIdentifier(entityName)) { + if (this.getPlexPlayerMachineIdentifier(entity)) { found = true; } return found || !lodash.isEqual(this.runBefore, false); @@ -20136,6 +20186,13 @@ class PlexMeetsHomeAssistant extends HTMLElement { } this.renderNewElementsIfNeeded(); }); + if (this.hassObj && this.plex) { + const entityConfig = JSON.parse(JSON.stringify(this.config.entity)); // todo: find a nicer solution + this.playController = new PlayController(this.hassObj, this.plex, entityConfig, this.runBefore, this.runAfter); + if (this.playController) { + await this.playController.init(); + } + } if (this.card) { this.previousPageWidth = this.card.offsetWidth; } @@ -21287,9 +21344,6 @@ class PlexMeetsHomeAssistant extends HTMLElement { } set hass(hass) { this.hassObj = hass; - if (this.plex) { - this.playController = new PlayController(this.hassObj, this.plex, this.config.entity, this.runBefore, this.runAfter); - } if (!this.content) { this.error = ''; if (!this.loading) { diff --git a/src/modules/PlayController.ts b/src/modules/PlayController.ts index 47899df..790122e 100644 --- a/src/modules/PlayController.ts +++ b/src/modules/PlayController.ts @@ -285,9 +285,72 @@ class PlayController { return service; }; - private getPlexPlayerMachineIdentifier = (entityName: string): string => { + init = async (): Promise => { + if (!_.isNil(this.entity.plexPlayer)) { + if (_.isArray(this.entity.plexPlayer)) { + for (let i = 0; i < this.entity.plexPlayer.length; i += 1) { + if (_.isObjectLike(this.entity.plexPlayer[i]) && !_.isNil(this.entity.plexPlayer[i].server)) { + let port: number | false = false; + if (!_.isNil(this.entity.plexPlayer[i].server.port)) { + port = this.entity.plexPlayer[i].server.port; + } + let protocol: 'http' | 'https' = 'http'; + if (!_.isNil(this.entity.plexPlayer[i].server.protocol)) { + protocol = this.entity.plexPlayer[i].server.protocol; + } + // eslint-disable-next-line no-param-reassign + this.entity.plexPlayer[i].plex = new Plex( + this.entity.plexPlayer[i].server.ip, + port, + this.entity.plexPlayer[i].server.token, + protocol + ); + // eslint-disable-next-line no-await-in-loop + await this.entity.plexPlayer[i].plex.getClients(); + } + } + } else if ( + !_.isNil(this.entity.plexPlayer.server) && + !_.isNil(this.entity.plexPlayer.server.ip) && + !_.isNil(this.entity.plexPlayer.server.token) + ) { + let port: number | false = false; + if (!_.isNil(this.entity.plexPlayer.server.port)) { + port = this.entity.plexPlayer.server.port; + } + let protocol: 'http' | 'https' = 'http'; + if (!_.isNil(this.entity.plexPlayer.server.protocol)) { + protocol = this.entity.plexPlayer.server.protocol; + } + // eslint-disable-next-line no-param-reassign + this.entity.plexPlayer.plex = new Plex( + this.entity.plexPlayer.server.ip, + port, + this.entity.plexPlayer.server.token, + protocol + ); + // eslint-disable-next-line no-await-in-loop + await this.entity.plexPlayer.plex.getClients(); + } + } + }; + + private getPlexPlayerMachineIdentifier = (entity: string | Record): string => { let machineIdentifier = ''; - _.forEach(this.plex.clients, plexClient => { + + let { plex } = this; + let entityName = ''; + if (_.isString(entity)) { + entityName = entity; + } else if (_.isObjectLike(entity) && !_.isNil(entity.identifier)) { + entityName = entity.identifier; + if (!_.isNil(entity.plex) && entity.plex) { + plex = entity.plex; + } + } + + console.log(plex.clients); + _.forEach(plex.clients, plexClient => { if ( _.isEqual(plexClient.machineIdentifier, entityName) || _.isEqual(plexClient.product, entityName) || @@ -306,11 +369,12 @@ class PlayController { return !_.isEmpty(this.getPlayService(data)); }; - private isPlexPlayerSupported = (entityName: string): boolean => { + private isPlexPlayerSupported = (entity: string | Record): boolean => { let found = false; - if (this.getPlexPlayerMachineIdentifier(entityName)) { + if (this.getPlexPlayerMachineIdentifier(entity)) { found = true; } + return found || !_.isEqual(this.runBefore, false); }; diff --git a/src/plex-meets-homeassistant.ts b/src/plex-meets-homeassistant.ts index dc93f8a..6565c84 100644 --- a/src/plex-meets-homeassistant.ts +++ b/src/plex-meets-homeassistant.ts @@ -117,15 +117,6 @@ class PlexMeetsHomeAssistant extends HTMLElement { set hass(hass: HomeAssistant) { this.hassObj = hass; - if (this.plex) { - this.playController = new PlayController( - this.hassObj, - this.plex, - this.config.entity, - this.runBefore, - this.runAfter - ); - } if (!this.content) { this.error = ''; @@ -211,6 +202,15 @@ class PlexMeetsHomeAssistant extends HTMLElement { } this.renderNewElementsIfNeeded(); }); + + if (this.hassObj && this.plex) { + const entityConfig: Record = JSON.parse(JSON.stringify(this.config.entity)); // todo: find a nicer solution + this.playController = new PlayController(this.hassObj, this.plex, entityConfig, this.runBefore, this.runAfter); + if (this.playController) { + await this.playController.init(); + } + } + if (this.card) { this.previousPageWidth = this.card.offsetWidth; } From d199719708becf013c7091b59f7ba3727b02e2cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juraj=20Nyi=CC=81ri?= Date: Sun, 4 Jul 2021 20:28:31 +0200 Subject: [PATCH 3/6] Add: Ability to play media from shared servers via plexPlayer --- dist/plex-meets-homeassistant.js | 49 +++++++++++++++++++++----------- src/modules/PlayController.ts | 42 +++++++++++++++++---------- src/modules/Plex.ts | 2 +- src/plex-meets-homeassistant.ts | 21 ++++++++------ 4 files changed, 73 insertions(+), 41 deletions(-) diff --git a/dist/plex-meets-homeassistant.js b/dist/plex-meets-homeassistant.js index 25fa417..4dae8b5 100644 --- a/dist/plex-meets-homeassistant.js +++ b/dist/plex-meets-homeassistant.js @@ -18672,7 +18672,7 @@ class Plex { constructor(ip, port = false, token, protocol = 'http', sort = 'titleSort:asc') { this.serverInfo = {}; this.clients = []; - this.requestTimeout = 5000; + this.requestTimeout = 10000; this.sections = []; this.init = async () => { await this.getClients(); @@ -18893,7 +18893,6 @@ class PlayController { return foundResult; }; this.play = async (data, instantPlay = false) => { - console.log(data); if (lodash.isArray(this.runBefore)) { await this.hass.callService(this.runBefore[0], this.runBefore[1], {}); } @@ -18918,13 +18917,13 @@ class PlayController { await this.hass.callService(this.runAfter[0], this.runAfter[1], {}); } }; - this.plexPlayerCreateQueue = async (movieID) => { - const url = `${this.plex.protocol}://${this.plex.ip}:${this.plex.port}/playQueues?type=video&shuffle=0&repeat=0&continuous=1&own=1&uri=server://${await this.plex.getServerID()}/com.plexapp.plugins.library/library/metadata/${movieID}`; + this.plexPlayerCreateQueue = async (movieID, plex) => { + const url = `${plex.getBasicURL()}/playQueues?type=video&shuffle=0&repeat=0&continuous=1&own=1&uri=server://${await plex.getServerID()}/com.plexapp.plugins.library/library/metadata/${movieID}`; const plexResponse = await axios({ method: 'post', url, headers: { - 'X-Plex-Token': this.plex.token, + 'X-Plex-Token': plex.token, 'X-Plex-Client-Identifier': 'PlexMeetsHomeAssistant' } }); @@ -18936,10 +18935,27 @@ class PlayController { playQueueSelectedMetadataItemID: plexResponse.data.MediaContainer.playQueueSelectedMetadataItemID }; }; - this.playViaPlexPlayer = async (entityName, movieID) => { - const machineID = this.getPlexPlayerMachineIdentifier(entityName); - const { playQueueID, playQueueSelectedMetadataItemID } = await this.plexPlayerCreateQueue(movieID); - const url = `${this.plex.protocol}://${this.plex.ip}:${this.plex.port}/player/playback/playMedia?address=${this.plex.ip}&commandID=1&containerKey=/playQueues/${playQueueID}?window=100%26own=1&key=/library/metadata/${playQueueSelectedMetadataItemID}&machineIdentifier=${await this.plex.getServerID()}&offset=0&port=${this.plex.port}&token=${this.plex.token}&type=video&protocol=${this.plex.protocol}`; + this.playViaPlexPlayer = async (entity, movieID) => { + const machineID = this.getPlexPlayerMachineIdentifier(entity); + let { plex } = this; + if (lodash.isObject(entity) && !lodash.isNil(entity.plex)) { + plex = entity.plex; + } + const { playQueueID, playQueueSelectedMetadataItemID } = await this.plexPlayerCreateQueue(movieID, this.plex); + let url = plex.getBasicURL(); + url += `/player/playback/playMedia`; + url += `?type=video`; + url += `&commandID=1`; + url += `&providerIdentifier=com.plexapp.plugins.library`; + url += `&containerKey=/playQueues/${playQueueID}`; + url += `&key=/library/metadata/${playQueueSelectedMetadataItemID}`; + url += `&offset=0`; + url += `&machineIdentifier=${await this.plex.getServerID()}`; + url += `&protocol=${this.plex.protocol}`; + url += `&address=${this.plex.ip}`; + url += `&port=${this.plex.port}`; + url += `&token=${this.plex.token}`; + url = plex.authorizeURL(url); try { const plexResponse = await axios({ method: 'post', @@ -19113,7 +19129,6 @@ class PlayController { plex = entity.plex; } } - console.log(plex.clients); lodash.forEach(plex.clients, plexClient => { if (lodash.isEqual(plexClient.machineIdentifier, entityName) || lodash.isEqual(plexClient.product, entityName) || @@ -20186,13 +20201,6 @@ class PlexMeetsHomeAssistant extends HTMLElement { } this.renderNewElementsIfNeeded(); }); - if (this.hassObj && this.plex) { - const entityConfig = JSON.parse(JSON.stringify(this.config.entity)); // todo: find a nicer solution - this.playController = new PlayController(this.hassObj, this.plex, entityConfig, this.runBefore, this.runAfter); - if (this.playController) { - await this.playController.init(); - } - } if (this.card) { this.previousPageWidth = this.card.offsetWidth; } @@ -20200,6 +20208,13 @@ class PlexMeetsHomeAssistant extends HTMLElement { this.renderPage(); try { if (this.plex) { + if (this.hassObj) { + const entityConfig = JSON.parse(JSON.stringify(this.config.entity)); // todo: find a nicer solution + this.playController = new PlayController(this.hassObj, this.plex, entityConfig, this.runBefore, this.runAfter); + if (this.playController) { + await this.playController.init(); + } + } await this.plex.init(); try { const onDeck = await this.plex.getOnDeck(); diff --git a/src/modules/PlayController.ts b/src/modules/PlayController.ts index 790122e..d1b2f97 100644 --- a/src/modules/PlayController.ts +++ b/src/modules/PlayController.ts @@ -96,7 +96,6 @@ class PlayController { }; play = async (data: Record, instantPlay = false): Promise => { - console.log(data); if (_.isArray(this.runBefore)) { await this.hass.callService(this.runBefore[0], this.runBefore[1], {}); } @@ -122,19 +121,18 @@ class PlayController { } }; - private plexPlayerCreateQueue = async (movieID: number): Promise> => { - const url = `${this.plex.protocol}://${this.plex.ip}:${ - this.plex.port - }/playQueues?type=video&shuffle=0&repeat=0&continuous=1&own=1&uri=server://${await this.plex.getServerID()}/com.plexapp.plugins.library/library/metadata/${movieID}`; + private plexPlayerCreateQueue = async (movieID: number, plex: Plex): Promise> => { + const url = `${plex.getBasicURL()}/playQueues?type=video&shuffle=0&repeat=0&continuous=1&own=1&uri=server://${await plex.getServerID()}/com.plexapp.plugins.library/library/metadata/${movieID}`; const plexResponse = await axios({ method: 'post', url, headers: { - 'X-Plex-Token': this.plex.token, + 'X-Plex-Token': plex.token, 'X-Plex-Client-Identifier': 'PlexMeetsHomeAssistant' } }); + if (plexResponse.status !== 200) { throw Error('Error reaching Plex to generate queue'); } @@ -144,15 +142,30 @@ class PlayController { }; }; - private playViaPlexPlayer = async (entityName: string, movieID: number): Promise => { - const machineID = this.getPlexPlayerMachineIdentifier(entityName); - const { playQueueID, playQueueSelectedMetadataItemID } = await this.plexPlayerCreateQueue(movieID); + private playViaPlexPlayer = async (entity: string | Record, movieID: number): Promise => { + const machineID = this.getPlexPlayerMachineIdentifier(entity); + let { plex } = this; + if (_.isObject(entity) && !_.isNil(entity.plex)) { + plex = entity.plex; + } + const { playQueueID, playQueueSelectedMetadataItemID } = await this.plexPlayerCreateQueue(movieID, this.plex); + + let url = plex.getBasicURL(); + url += `/player/playback/playMedia`; + url += `?type=video`; + url += `&commandID=1`; + url += `&providerIdentifier=com.plexapp.plugins.library`; + url += `&containerKey=/playQueues/${playQueueID}`; + url += `&key=/library/metadata/${playQueueSelectedMetadataItemID}`; + url += `&offset=0`; + url += `&machineIdentifier=${await this.plex.getServerID()}`; + url += `&protocol=${this.plex.protocol}`; + url += `&address=${this.plex.ip}`; + url += `&port=${this.plex.port}`; + url += `&token=${this.plex.token}`; + + url = plex.authorizeURL(url); - const url = `${this.plex.protocol}://${this.plex.ip}:${this.plex.port}/player/playback/playMedia?address=${ - this.plex.ip - }&commandID=1&containerKey=/playQueues/${playQueueID}?window=100%26own=1&key=/library/metadata/${playQueueSelectedMetadataItemID}&machineIdentifier=${await this.plex.getServerID()}&offset=0&port=${ - this.plex.port - }&token=${this.plex.token}&type=video&protocol=${this.plex.protocol}`; try { const plexResponse = await axios({ method: 'post', @@ -349,7 +362,6 @@ class PlayController { } } - console.log(plex.clients); _.forEach(plex.clients, plexClient => { if ( _.isEqual(plexClient.machineIdentifier, entityName) || diff --git a/src/modules/Plex.ts b/src/modules/Plex.ts index 9116f9e..2bdea2f 100644 --- a/src/modules/Plex.ts +++ b/src/modules/Plex.ts @@ -15,7 +15,7 @@ class Plex { clients: Array> = []; - requestTimeout = 5000; + requestTimeout = 10000; sort: string; diff --git a/src/plex-meets-homeassistant.ts b/src/plex-meets-homeassistant.ts index 6565c84..aa58265 100644 --- a/src/plex-meets-homeassistant.ts +++ b/src/plex-meets-homeassistant.ts @@ -203,14 +203,6 @@ class PlexMeetsHomeAssistant extends HTMLElement { this.renderNewElementsIfNeeded(); }); - if (this.hassObj && this.plex) { - const entityConfig: Record = JSON.parse(JSON.stringify(this.config.entity)); // todo: find a nicer solution - this.playController = new PlayController(this.hassObj, this.plex, entityConfig, this.runBefore, this.runAfter); - if (this.playController) { - await this.playController.init(); - } - } - if (this.card) { this.previousPageWidth = this.card.offsetWidth; } @@ -219,6 +211,19 @@ class PlexMeetsHomeAssistant extends HTMLElement { this.renderPage(); try { if (this.plex) { + if (this.hassObj) { + const entityConfig: Record = JSON.parse(JSON.stringify(this.config.entity)); // todo: find a nicer solution + this.playController = new PlayController( + this.hassObj, + this.plex, + entityConfig, + this.runBefore, + this.runAfter + ); + if (this.playController) { + await this.playController.init(); + } + } await this.plex.init(); try { From af874b1c6b9e2f8d214977afaaf2157c9361e6ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juraj=20Nyi=CC=81ri?= Date: Sun, 4 Jul 2021 20:52:37 +0200 Subject: [PATCH 4/6] Add: Readme instructions about shared Plex servers --- README.md | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 69 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 29ad131..8e8a3eb 100644 --- a/README.md +++ b/README.md @@ -140,7 +140,9 @@ Play button is only visible if all the conditions inside Availability section of - Provided entity ID needs to have attributes - Provided entity ID needs to have attribute adb_response -**Supported play types**: +**Supported**: + +✅ Shared Plex servers ✅ Movies @@ -180,7 +182,9 @@ Play button is only visible if all the conditions inside Availability section of - State of both entities cannot be 'unavailable' - State of kodi cannot be 'off' -**Supported play types**: +**Supported**: + +✅ Shared Plex servers _\*if content available in kodi_ ✅ Movies @@ -204,7 +208,9 @@ Play button is only visible if all the conditions inside Availability section of - Media player entity cannot be `unavailable` -**Supported play types**: +**Supported**: + +✅ Shared Plex servers ✅ Movies @@ -263,7 +269,9 @@ entity: - Plex needs to run on the defined device -**Supported play types**: +**Supported**: + +✅ Shared Plex servers _\*requires additional configuration, see below_ ✅ Movies @@ -273,6 +281,63 @@ entity: ✅ Episodes +**Shared Plex servers configuration** + +plexPlayer can be configured in multiple ways, achieving the same thing: + +``` +entity: + plexPlayer: TV 2020 +``` + +``` +entity: + plexPlayer: + - TV 2020 +``` + +``` +entity: + plexPlayer: + identifier: TV 2020 +``` + +``` +entity: + plexPlayer: + - identifier: TV 2020 +``` + +As can be seen from the last two examples, it is possible to configure it as an object having key "identifier". + +That is useful, if you want to stream media from shared or remote Plex server. Add information about your local Plex server which sees your device on which you wish to play content. This is done by including a new key, "server" having additional keys: + +Example 1: + +``` +entity: + plexPlayer: + - identifier: TV 2020 + server: + ip: 192.168.13.37 # Mandatory + token: QWdsqEXAMPLETOKENqwerty # Mandatory + port: 32400 + protocol: http +``` + +Example 2: + +``` +entity: + plexPlayer: + - identifier: TV 2020 + server: + ip: 192.168.13.37 # Mandatory + token: QWdsqEXAMPLETOKENqwerty # Mandatory + port: 32400 + protocol: http +``` + ## Sorting You can use _:desc_ or _:asc_ after every value to change the order from ascending to descending. For example, titlesort would become titleSort:asc, or titleSort:desc. From 95409b93a93b281ff76356d5d54dadb59023c701 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juraj=20Nyi=CC=81ri?= Date: Sun, 4 Jul 2021 20:55:10 +0200 Subject: [PATCH 5/6] Fix: Readme example 2 for shared plex server configuration for plexPlayer --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 8e8a3eb..30a85c4 100644 --- a/README.md +++ b/README.md @@ -330,12 +330,12 @@ Example 2: ``` entity: plexPlayer: - - identifier: TV 2020 - server: - ip: 192.168.13.37 # Mandatory - token: QWdsqEXAMPLETOKENqwerty # Mandatory - port: 32400 - protocol: http + identifier: TV 2020 + server: + ip: 192.168.13.37 # Mandatory + token: QWdsqEXAMPLETOKENqwerty # Mandatory + port: 32400 + protocol: http ``` ## Sorting From 532a217981a4386541b3c6981a4a35fcacb65f5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juraj=20Nyi=CC=81ri?= Date: Sun, 4 Jul 2021 20:57:42 +0200 Subject: [PATCH 6/6] Remove: Left over console logs --- dist/plex-meets-homeassistant.js | 4 +--- src/modules/utils.ts | 1 - src/plex-meets-homeassistant.ts | 3 +-- 3 files changed, 2 insertions(+), 6 deletions(-) diff --git a/dist/plex-meets-homeassistant.js b/dist/plex-meets-homeassistant.js index 4dae8b5..3843c15 100644 --- a/dist/plex-meets-homeassistant.js +++ b/dist/plex-meets-homeassistant.js @@ -19313,7 +19313,6 @@ const clickHandler = (elem, clickFunction, holdFunction) => { elem.addEventListener('touchcancel', cancel); }; const createEpisodesView = (playController, plex, data) => { - console.log(data); const episodeContainer = document.createElement('div'); episodeContainer.className = 'episodeContainer'; episodeContainer.style.width = `${CSS_STYLE.episodeWidth}px`; @@ -21256,13 +21255,12 @@ class PlexMeetsHomeAssistant extends HTMLElement { } movieElem.append(interactiveArea); clickHandler(playButton, (event) => { - console.log('click'); event.stopPropagation(); if (this.hassObj && this.playController) { this.playController.play(data, true); } }, (event) => { - console.log('hold'); + console.log('Play version... will be here!'); event.stopPropagation(); }); const titleElem = document.createElement('div'); diff --git a/src/modules/utils.ts b/src/modules/utils.ts index 3089a0e..a767206 100644 --- a/src/modules/utils.ts +++ b/src/modules/utils.ts @@ -154,7 +154,6 @@ const clickHandler = (elem: HTMLButtonElement, clickFunction: Function, holdFunc }; const createEpisodesView = (playController: PlayController, plex: Plex, data: Record): HTMLElement => { - console.log(data); const episodeContainer = document.createElement('div'); episodeContainer.className = 'episodeContainer'; episodeContainer.style.width = `${CSS_STYLE.episodeWidth}px`; diff --git a/src/plex-meets-homeassistant.ts b/src/plex-meets-homeassistant.ts index aa58265..bc89eba 100644 --- a/src/plex-meets-homeassistant.ts +++ b/src/plex-meets-homeassistant.ts @@ -1371,7 +1371,6 @@ class PlexMeetsHomeAssistant extends HTMLElement { clickHandler( playButton, (event: any): void => { - console.log('click'); event.stopPropagation(); if (this.hassObj && this.playController) { @@ -1379,7 +1378,7 @@ class PlexMeetsHomeAssistant extends HTMLElement { } }, (event: any): void => { - console.log('hold'); + console.log('Play version... will be here!'); event.stopPropagation(); } );