diff --git a/app/public/manifest.json b/app/public/manifest.json index 6ff410f..372bcb7 100644 --- a/app/public/manifest.json +++ b/app/public/manifest.json @@ -16,7 +16,8 @@ "https://*.disneyplus.com/*", "https://*.youtube.com/*", "https://play.hbonow.com/*", - "https://play.hbomax.com/*" + "https://play.hbomax.com/*", + "https://*.peacocktv.com/*" ], "content_security_policy": "script-src 'self' https://www.gstatic.com/ https://*.firebaseio.com https://www.googleapis.com; object-src 'self'", "content_scripts": [ @@ -28,7 +29,8 @@ "https://*.disneyplus.com/*", "https://*.youtube.com/*", "https://play.hbonow.com/*", - "https://play.hbomax.com/*" + "https://play.hbomax.com/*", + "https://*.peacocktv.com/*" ], "run_at": "document_idle", "js": ["/static/js/content.js"], diff --git a/app/src/Api.js b/app/src/Api.js index d88a715..3ea51c4 100644 --- a/app/src/Api.js +++ b/app/src/Api.js @@ -36,6 +36,7 @@ export const PLAYER_SOURCE = { YOUTUBE: 'youtube.', HBONOW: 'hbonow.', HBOMAX: 'hbomax.', + PEACOCK: 'peacocktv.', LOCAL: 'localhost', }; @@ -48,6 +49,7 @@ export const getPlayerSource = () => { if (HREF.includes(PLAYER_SOURCE.YOUTUBE)) return PLAYER_SOURCE.YOUTUBE; if (HREF.includes(PLAYER_SOURCE.HBONOW)) return PLAYER_SOURCE.HBONOW; if (HREF.includes(PLAYER_SOURCE.HBOMAX)) return PLAYER_SOURCE.HBOMAX; + if (HREF.includes(PLAYER_SOURCE.PEACOCK)) return PLAYER_SOURCE.PEACOCK; if (HREF.includes(PLAYER_SOURCE.LOCAL)) return PLAYER_SOURCE.LOCAL; }; diff --git a/app/src/ClickSimulator.js b/app/src/ClickSimulator.js new file mode 100644 index 0000000..1a5c83a --- /dev/null +++ b/app/src/ClickSimulator.js @@ -0,0 +1,95 @@ +/************************************************************************ +Copyright (C) Ayushya Amitabh - All Rights Reserved +Unauthorized copying of this file, via any medium is strictly prohibited +Proprietary and confidential +Written by Ayushya Amitabh , 2020 +https://www.chromewatchparty.com/copyright +========================================================================= +ALL CONTENT ON IN WATCH PARTY'S CHROME EXTENSION APP, UNLESS OTHERWISE +CITED ARE THE SOLE INTELECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE +COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION. + +Netflix logo is a trademark and intellectual property of Netflix, Inc. +Disney+ logo is a trademark and intellectual property of The Walt Disney Company +Prime logo is a trademark and intellectual property of Amazon.com, Inc. +YouTube logo is a trademark and intellectual property of Google, Inc. +Hulu logo is a trademark and intellectual property of Hulu, LLC. +HBO Now and HBO Max logos are trademark and intellectual property of WarnerMedia Direct,LLC. +************************************************************************/ + +/************************************************************************ + THE CODE BELOW WAS WRITTEN BY USER + https://stackoverflow.com/users/68808/tweezz + ON STACKOVERFLOW, WHICH CAN BE FOUND AT + https://stackoverflow.com/questions/6157929/how-to-simulate-a-mouse-click-using-javascript +************************************************************************/ + +export default function simulate(element, eventName) { + var options = extend(defaultOptions, arguments[2] || {}); + var oEvent, + eventType = null; + + for (var name in eventMatchers) { + if (eventMatchers[name].test(eventName)) { + eventType = name; + break; + } + } + + if (!eventType) throw new SyntaxError('Only HTMLEvents and MouseEvents interfaces are supported'); + + if (document.createEvent) { + oEvent = document.createEvent(eventType); + if (eventType == 'HTMLEvents') { + oEvent.initEvent(eventName, options.bubbles, options.cancelable); + } else { + oEvent.initMouseEvent( + eventName, + options.bubbles, + options.cancelable, + document.defaultView, + options.button, + options.pointerX, + options.pointerY, + options.pointerX, + options.pointerY, + options.ctrlKey, + options.altKey, + options.shiftKey, + options.metaKey, + options.button, + element + ); + } + element.dispatchEvent(oEvent); + } else { + options.clientX = options.pointerX; + options.clientY = options.pointerY; + var evt = document.createEventObject(); + oEvent = extend(evt, options); + element.fireEvent('on' + eventName, oEvent); + } + return element; +} + +function extend(destination, source) { + for (var property in source) destination[property] = source[property]; + return destination; +} + +const eventMatchers = { + HTMLEvents: /^(?:load|unload|abort|error|select|change|submit|reset|focus|blur|resize|scroll)$/, + MouseEvents: /^(?:click|dblclick|mouse(?:down|up|over|move|out))$/, +}; + +const defaultOptions = { + pointerX: 0, + pointerY: 0, + button: 0, + ctrlKey: false, + altKey: false, + shiftKey: false, + metaKey: false, + bubbles: true, + cancelable: true, +}; diff --git a/app/src/VideoListener.js b/app/src/VideoListener.js index 87ea709..adb1e3c 100644 --- a/app/src/VideoListener.js +++ b/app/src/VideoListener.js @@ -17,6 +17,7 @@ Hulu logo is a trademark and intellectual property of Hulu, LLC. HBO Now and HBO Max logos are trademark and intellectual property of WarnerMedia Direct,LLC. ************************************************************************/ import { PLAYER_STATUS, getPlayerSource, PLAYER_SOURCE, LocalData } from './Api'; +import simulate from './ClickSimulator'; const templateListener = (video) => console.log('MISSING VIDEO LISTENER'); @@ -103,6 +104,15 @@ export default class VideoListener { case PLAYER_SOURCE.HBONOW: this.video.element.currentTime = serverPlayer.time; break; + case PLAYER_SOURCE.PEACOCK: + this.video.element.pause(); + const sliderHead = document.body.querySelector( + '.playback-scrubber-bar .rc-slider-handle' + ); + sliderHead.left = + (serverPlayer.time / sliderHead.getAttribute('aria-valueMax')) * 100 + '%'; + simulate(sliderHead, 'mousedown'); + simulate(sliderHead, 'mouseup'); default: break; } @@ -198,6 +208,20 @@ export default class VideoListener { const hboshow = document.querySelector('#hboUpperTitle').innerText; const hboepisode = document.querySelector('#hboLowerTitle').innerText; return hboshow === '' && hboepisode === '' ? null : hboshow + '\n' + hboepisode; + case PLAYER_SOURCE.PEACOCK: + try { + const peacockshow = document.querySelector( + '.item.playback-metadata__container-episode-metadata-info' + ).innerText; + const peacockepisode = document.querySelector('.item.playback-metadata__container-title') + .innerText; + return peacockshow === '' && peacockepisode === '' + ? null + : peacockshow + '\n' + peacockepisode; + } catch (err) { + // PREVIEW VIDEO, NO NEED TO GET NAME + return null; + } default: break; } @@ -352,6 +376,32 @@ export default class VideoListener { ); } break; + case PLAYER_SOURCE.PEACOCK: + const peacockVideoElement = document.querySelector( + '.video-player-component.playback-component video' + ); + if (peacockVideoElement) { + this.firstTimeSync(peacockVideoElement); + } else { + setInterval( + this.video.element + ? null + : () => { + var pve = document.querySelector( + '.video-player-component.playback-component video' + ); + if ( + pve !== null && + pve !== undefined && + (this.video.element !== pve || this.video.element === null) + ) { + this.firstTimeSync(pve); + } + }, + 1000 + ); + } + break; case PLAYER_SOURCE.LOCAL: const localVideoElement = document.getElementsByTagName('video')[0]; if (localVideoElement) { diff --git a/app/src/index.css b/app/src/index.css index 6439c95..4fc6d4a 100644 --- a/app/src/index.css +++ b/app/src/index.css @@ -111,6 +111,21 @@ body.amazon-prime textarea:focus { border: none !important; box-shadow: none !important; } +/* PEACOCK STYLING FIX */ +body.peacock.visible .header-buttons { + max-width: calc(100% - calc(var(--party-width) + 50px)); +} +body.peacock.visible #mount { + position: relative; +} +body.peacock.visible .playback-overlay__container.vod { + position: absolute; + max-width: 100%; +} +body.peacock.visible .playback-header__container { + position: relative; + max-width: 100%; +} #party-loading { position: absolute; width: 100%; diff --git a/app/src/index.js b/app/src/index.js index b2bab9b..a7c8e6b 100644 --- a/app/src/index.js +++ b/app/src/index.js @@ -79,6 +79,9 @@ switch (getPlayerSource()) { document.head.appendChild(hboClickInjectScript); document.body.classList.add('hbo'); break; + case PLAYER_SOURCE.PEACOCK: + document.body.classList.add('peacock'); + break; case PLAYER_SOURCE.LOCAL: document.body.classList.add('local'); break;