From 8aef416eda8cd16f5e10b0704f4bfe2eabc4c775 Mon Sep 17 00:00:00 2001 From: Ayushya Amitabh Date: Sun, 3 May 2020 16:02:04 -0400 Subject: [PATCH] time sync --- functions/index.js | 5 +- src/Api.js | 4 +- src/App.js | 3 +- src/Chat.js | 32 +++++----- src/VideoListener.js | 136 ++++++++++++++++++++----------------------- src/index.css | 28 ++++++--- 6 files changed, 100 insertions(+), 108 deletions(-) diff --git a/functions/index.js b/functions/index.js index 4bdb634..159fc49 100644 --- a/functions/index.js +++ b/functions/index.js @@ -461,10 +461,9 @@ exports.scheduledCleanUp = functions.pubsub.schedule('every 60 minutes').onRun(a roomRef .get() .then(async (roomSnap) => { - const roomData = roomSnap.data(); if ( - timeDiff(roomData.createdAt, startedTime) >= 24 || - timeDiff(roomData.updatedAt, startedTime) >= 12 + timeDiff(roomSnap.createTime.toDate(), startedTime) >= 24 || + timeDiff(roomSnap.updateTime.toDate(), startedTime) >= 12 ) await cleanUpRoom(roomSnap.id); console.info(`Deleted room ${roomSnap.id} from auto cleanup`); diff --git a/src/Api.js b/src/Api.js index 6a668ba..f804536 100644 --- a/src/Api.js +++ b/src/Api.js @@ -2,8 +2,8 @@ const API_HOST = window.location.href.startsWith('http://localhost') ? 'http://localhost:5001/watch-party-crx/us-central1/widgets' - : 'http://localhost:5001/watch-party-crx/us-central1/widgets'; -// : 'https://us-central1-watch-party-crx.cloudfunctions.net/widgets'; + : // : 'http://localhost:5001/watch-party-crx/us-central1/widgets'; + 'https://us-central1-watch-party-crx.cloudfunctions.net/widgets'; export const PLAYER_STATUS = { PLAYING: 'PLAYING', diff --git a/src/App.js b/src/App.js index f32dd12..d22f32c 100644 --- a/src/App.js +++ b/src/App.js @@ -7,7 +7,6 @@ import firebase from 'firebase/app'; import 'firebase/firestore'; import Inactive from './Inactive'; import { getUserUid } from './Api'; -import Chat from './Chat'; const darkTheme = createMuiTheme({ palette: { @@ -20,7 +19,7 @@ const darkTheme = createMuiTheme({ const Routes = (props) => ( - + ); diff --git a/src/Chat.js b/src/Chat.js index 9bac938..539dea7 100644 --- a/src/Chat.js +++ b/src/Chat.js @@ -54,6 +54,7 @@ export default class Chat extends Component { this.gifClick = this.gifClick.bind(this); } componentDidMount() { + // EVENT CAPTURE FOR ENTER TO SEND window.onkeypress = (ev) => { if (ev.code === 'Enter') { if (ev.target === document.getElementById('chat-message-box-input')) { @@ -65,11 +66,18 @@ export default class Chat extends Component { } } }; + + // VIDEO LISTENER START + this.mVideoListener.start(); + + // CHROME FIREBASE FIRESTORE LISTENER this.port = chrome.runtime.connect({ name: window.localStorage.getItem('watchPartyRoomId') }); + // Initialize listener this.port.postMessage({ type: 'INIT', roomId: window.localStorage.getItem('watchPartyRoomId'), }); + // Listener this.port.onMessage.addListener((response) => { if (response.isError === true) { this.props.notify('Uh oh. Got lost from the party.'); @@ -77,31 +85,17 @@ export default class Chat extends Component { return; } this.setState(response); - if (response.player && this.state.localPlayer.status !== response.player.status) { - if (response.player.source !== getPlayerSource()) { - this.props.updateLoading(true); - this.props.notify('This party is for a different website'); - goTo(Create, this.props); - this.props.updateLoading(false); - } else { - if (this.mVideoListener.isUpdating === false) - this.mVideoListener.doUpdate(response.player); - } - } + if (response.player) this.mVideoListener.doUpdate(response.player); const pcc = document.getElementsByClassName('thread-container')[0]; if (pcc) pcc.scrollTop = pcc.scrollHeight; }); - this.mVideoListener.start(); + + // DONE WITH MOUNTING TASKS this.props.updateLoading(false); } videoEventListener(video) { this.setState({ localPlayer: video }); - if ( - this.state.player.status !== video.status && - video.showName && - video.status !== PLAYER_STATUS.NOT_PLAYING - ) - this.syncPlayer(video); + this.syncPlayer(video); } syncPlayer(video) { const { status, showName, time, source, element } = video; @@ -190,7 +184,7 @@ export default class Chat extends Component { }); } sendMessageInvoker(overrideMessage) { - if (overrideMessage) console.log(overrideMessage); + if (overrideMessage) this.sendMessage(overrideMessage); else { const trim = this.state.newMessage.replace(/^\s+|\s+$/g, ''); if (trim !== '') this.sendMessage(trim); diff --git a/src/VideoListener.js b/src/VideoListener.js index 780f1ca..c121f68 100644 --- a/src/VideoListener.js +++ b/src/VideoListener.js @@ -16,62 +16,53 @@ export default class VideoListener { this.firstTimeSync = this.firstTimeSync.bind(this); this.doUpdate = this.doUpdate.bind(this); this.start = this.start.bind(this); - this.getDisneyTitle = this.getDisneyTitle.bind(this); - this.isUpdating = false; } updateStatus(newStatus) { - if (this.isUpdating === false && newStatus.status !== this.video.status) { - this.isUpdating = true; - this.video = Object.assign({}, this.video, newStatus); + const oldVideo = this.video; + this.video = Object.assign({}, this.video, newStatus); + if (oldVideo.status !== this.video.status || Math.abs(this.video.time - oldVideo.time) > 1) this.listener(this.video); - this.isUpdating = false; - } else return; } doUpdate(serverPlayer) { - if (this.video.element && this.video.time !== serverPlayer.time) { - switch (this.video.source) { - case PLAYER_SOURCE.NETFLIX: - window.postMessage({ type: 'SEEK', time: serverPlayer.time * 1000 }, '*'); - break; - case PLAYER_SOURCE.AMAZON: - this.video.element.play(); - this.video.element.currentTime = serverPlayer.time; - break; - default: - break; + // SEEK + if (serverPlayer.updatedBy !== window.localStorage.getItem('watchPartyUserUid')) { + if (this.video.element && Math.abs(this.video.time - serverPlayer.time) > 1) { + switch (this.video.source) { + case PLAYER_SOURCE.NETFLIX: + window.postMessage({ type: 'SEEK', time: serverPlayer.time * 1000 }, '*'); + break; + case PLAYER_SOURCE.AMAZON: + this.video.element.play(); + this.video.element.currentTime = serverPlayer.time; + break; + default: + break; + } } - } - - if (this.video.element && this.video.status !== serverPlayer.status) { - switch (serverPlayer.status) { - case PLAYER_STATUS.PAUSED: - this.video.element.pause(); - break; - case PLAYER_STATUS.NOT_PLAYING: - this.video.element.pause(); - break; - case PLAYER_STATUS.PLAYING: - this.video.element.play(); - break; - default: - break; + // PLAY OR PAUSE + if (this.video.element) { + switch (serverPlayer.status) { + case PLAYER_STATUS.PAUSED: + this.video.element.pause(); + break; + case PLAYER_STATUS.NOT_PLAYING: + this.video.element.pause(); + break; + case PLAYER_STATUS.PLAYING: + this.video.element.play(); + break; + default: + break; + } } } } - getDisneyTitle() { - return new Promise((resolve) => { - this.video.element.click(); - setTimeout( - () => - resolve([ - document.getElementsByClassName('title-field')[0].innerHTML, - document.getElementsByClassName('subtitle-field')[0].innerHTML, - ]), - 50 - ); + timeout(n) { + return new Promise((resolve, reject) => { + setTimeout(resolve, n); }); } - getShowName() { + async getShowName() { switch (this.video.source) { case PLAYER_SOURCE.NETFLIX: const titleContainerParent = document.querySelector( @@ -98,20 +89,22 @@ export default class VideoListener { const hepisode = document.querySelector('.metadata-area__third-line').innerHTML; return hshow === '' && hepisode === '' ? null : hshow + '\n' + hepisode; case PLAYER_SOURCE.DISNEY: - this.getDisneyTitle().then((r) => { - const dshow = r[0]; - const depisode = r[1]; - return dshow === '' && depisode === '' ? null : dshow + '\n' + depisode; - }); - break; + this.video.element.click(); + await this.timeout(200); + const dshow = document.querySelector('.title-field').innerHTML; + const depisode = document.querySelector('.subtitle-field').innerHTML; + return dshow === '' && depisode === '' ? null : dshow + '\n' + depisode; default: break; } } - firstTimeSync(videoElement) { + async firstTimeSync(videoElement) { + console.log('INSIDE FIRST TIME SYNC', videoElement); this.updateStatus({ element: videoElement, - showName: this.getShowName(), + }); + this.updateStatus({ + showName: await this.getShowName(), }); if (videoElement.paused) { this.updateStatus({ @@ -125,18 +118,19 @@ export default class VideoListener { status: PLAYER_STATUS.PLAYING, }); } - videoElement.onplaying = (ev) => { + videoElement.onplay = async (ev) => { + console.log(ev); this.updateStatus({ status: PLAYER_STATUS.PLAYING, time: videoElement.currentTime, - showName: this.getShowName(), + showName: await this.getShowName(), }); }; - videoElement.onpause = (ev) => + videoElement.onpause = async (ev) => this.updateStatus({ status: PLAYER_STATUS.PAUSED, time: videoElement.currentTime, - showName: this.getShowName(), + showName: await this.getShowName(), }); videoElement.onended = (ev) => { this.updateStatus({ status: PLAYER_STATUS.NOT_PLAYING, showName: '', time: 0 }); @@ -193,24 +187,20 @@ export default class VideoListener { } break; case PLAYER_SOURCE.DISNEY: - const wrapper = document.getElementById('hudson-wrapper'); - if (wrapper) { - const container = wrapper.querySelector('.hudson-container'); - if (container) { - const videoElement = container.querySelector('video'); - if (videoElement) { - this.firstTimeSync(videoElement); - } - } + const disneyVideoElement = document.querySelector('video.btm-media-client-element'); + if (disneyVideoElement) { + this.firstTimeSync(disneyVideoElement); } else { - document.addEventListener('DOMNodeInserted', () => { - const wrapper = document.getElementById('hudson-wrapper'); - if (wrapper) { - const container = wrapper.querySelector('.hudson-container'); - if (container) { - const videoElement = container.querySelector('video'); + document.addEventListener('DOMNodeInserted', (e) => { + if (e.target && e.target.classList) { + if (e.target.classList.contains('btm-media-player')) { + const videoElement = document.querySelector('video.btm-media-client-element'); if (videoElement) { - if (!this.video.element) this.firstTimeSync(videoElement); + console.log(videoElement, this.video.element); + if (!this.video.element || this.video.element !== videoElement) { + console.log('FIRST TIME SYNC', videoElement); + this.firstTimeSync(videoElement); + } } } } diff --git a/src/index.css b/src/index.css index f439aca..ff81b5b 100644 --- a/src/index.css +++ b/src/index.css @@ -1,13 +1,18 @@ +:root { + --party-width: 22rem; + --neg-party-width: -22rem; + --body-width: calc(100% - var(--party-width)); +} body { margin: 0 !important; background-color: black; transition: max-width ease-in-out 0.35s; } body.visible { - width: 75%; + width: var(--body-width); } body.visible .watch-party-fab { - right: 25% !important; + right: var(--party-width) !important; transform: translateX(50%); top: 1.5rem; } @@ -17,21 +22,26 @@ body.visible .party-notification-container { body.netflix.visible .AkiraPlayer, /* NETFLIX */ body.hulu.visible .Player__container,/* HULU */ -body.amazon-prime.visible #dv-web-player.dv-player-fullscreen /* AMAZON PRIME */ { - max-width: 75% !important; +body.amazon-prime.visible #dv-web-player.dv-player-fullscreen, /* AMAZON PRIME */ +body.disney.visible #hudson-wrapper /* DISNEY */ { + max-width: var(--body-width) !important; } /* HULU MINIMIZED VIDEO */ body.hulu.visible #__player__ .Player__container.Player__container--modal { - right: calc(25% + 2rem) !important; + right: calc(var(--party-width) + 2rem) !important; z-index: 99999 !important; } /* HULU, DISNEY & AMAZON PRIME FIX */ body.disney #party-routes-wrapper, body.hulu #party-routes-wrapper, body.amazon-prime #party-routes-wrapper { - width: 25% !important; + width: var(--party-width) !important; height: 100% !important; } +/* DISNEY FULL SCREEN VIDEO FIX */ +body.disney #hudson-wrapper { + left: 0; +} /* AMAZON STYLING FIX */ body.amazon-prime input, body.amazon-prime textarea { @@ -94,8 +104,8 @@ body.amazon-prime textarea:focus { position: fixed; background-color: rgb(27, 27, 27); bottom: 0; - width: calc(25% - 2rem); - right: -25%; + width: calc(var(--party-width) - 2rem); + right: var(--neg-party-width); transition: all ease-in-out 0.3s; height: calc(100% - 2rem); padding: 1rem; @@ -112,7 +122,7 @@ body.amazon-prime textarea:focus { display: none !important; bottom: 0.8rem !important; right: 1rem !important; - width: calc(25% - 2rem) !important; + width: calc(var(--party-width) - 2rem) !important; } .party-notification-container .MuiPaper-root { border-radius: 26px !important;