adding time sync

This commit is contained in:
Ayushya Amitabh
2020-04-28 21:20:14 -04:00
parent bab143ace0
commit a169fde183
9 changed files with 97 additions and 9 deletions
+1 -1
View File
@@ -385,7 +385,7 @@ const updatePlayer = async (req, res) => {
uid: '<system>', uid: '<system>',
name: '', name: '',
text: `${userName} changed show to \n${player.showName}`, text: `${userName} changed show to \n${player.showName}`,
time: new Date().toISOString(), time: new Date(),
}); });
} }
if (roomData.status !== player.status) { if (roomData.status !== player.status) {
+3 -2
View File
@@ -108,11 +108,12 @@ chrome.runtime.onConnect.addListener((port) => {
.collection('rooms') .collection('rooms')
.doc(roomId) .doc(roomId)
.collection('messages') .collection('messages')
.orderBy('time')
.onSnapshot( .onSnapshot(
(snap) => { (snap) => {
if (snap) if (snap)
port.postMessage({ messages: snap.docs.map((v) => ({ ...v.data(), id: v.id })) }); port.postMessage({
messages: snap.docs.map((v) => ({ ...v.data(), id: v.id })),
});
}, },
(err) => { (err) => {
port.postMessage({ isError: true, ...err }); port.postMessage({ isError: true, ...err });
+12 -1
View File
@@ -6,7 +6,12 @@
"background": { "background": {
"page": "popup.html" "page": "popup.html"
}, },
"permissions": ["https://*.hulu.com/*", "https://*.netflix.com/*", "https://*.amazon.com/*"], "permissions": [
"https://*.hulu.com/*",
"https://*.netflix.com/*",
"https://*.amazon.com/*",
"https://*.disneyplus.com/*"
],
"content_security_policy": "script-src 'self' https://www.gstatic.com/ https://*.firebaseio.com https://www.googleapis.com; object-src 'self'", "content_security_policy": "script-src 'self' https://www.gstatic.com/ https://*.firebaseio.com https://www.googleapis.com; object-src 'self'",
"content_scripts": [ "content_scripts": [
{ {
@@ -26,6 +31,12 @@
"run_at": "document_idle", "run_at": "document_idle",
"js": ["/static/js/content.js"], "js": ["/static/js/content.js"],
"css": ["/static/css/app.css"] "css": ["/static/css/app.css"]
},
{
"matches": ["https://*.disneyplus.com/*"],
"run_at": "document_idle",
"js": ["/static/js/content.js"],
"css": ["/static/css/app.css"]
} }
], ],
"web_accessible_resources": ["android-icon-192x192.png"], "web_accessible_resources": ["android-icon-192x192.png"],
+2
View File
@@ -14,6 +14,7 @@ export const PLAYER_SOURCE = {
NETFLIX: 'https://www.netflix.', NETFLIX: 'https://www.netflix.',
AMAZON: 'https://www.amazon.', AMAZON: 'https://www.amazon.',
HULU: 'https://www.hulu.', HULU: 'https://www.hulu.',
DISNEY: 'https://www.disneyplus.',
LOCAL: 'http://localhost', LOCAL: 'http://localhost',
}; };
@@ -22,6 +23,7 @@ export const getPlayerSource = () => {
if (HREF.startsWith(PLAYER_SOURCE.NETFLIX)) return PLAYER_SOURCE.NETFLIX; if (HREF.startsWith(PLAYER_SOURCE.NETFLIX)) return PLAYER_SOURCE.NETFLIX;
if (HREF.startsWith(PLAYER_SOURCE.HULU)) return PLAYER_SOURCE.HULU; if (HREF.startsWith(PLAYER_SOURCE.HULU)) return PLAYER_SOURCE.HULU;
if (HREF.startsWith(PLAYER_SOURCE.AMAZON)) return PLAYER_SOURCE.AMAZON; if (HREF.startsWith(PLAYER_SOURCE.AMAZON)) return PLAYER_SOURCE.AMAZON;
if (HREF.startsWith(PLAYER_SOURCE.DISNEY)) return PLAYER_SOURCE.DISNEY;
if (HREF.startsWith(PLAYER_SOURCE.LOCAL)) return PLAYER_SOURCE.LOCAL; if (HREF.startsWith(PLAYER_SOURCE.LOCAL)) return PLAYER_SOURCE.LOCAL;
}; };
+5 -2
View File
@@ -115,6 +115,7 @@ export default class Chat extends Component {
showName, showName,
time, time,
source, source,
updatedBy: window.localStorage.getItem('watchPartyUserUid'),
}, },
}).catch((err) => { }).catch((err) => {
this.props.updateLoading(false); this.props.updateLoading(false);
@@ -235,13 +236,15 @@ export default class Chat extends Component {
</Button> </Button>
{admin && ( {admin && (
<Button onClick={this.endParty} startIcon={<Delete />}> <Button onClick={this.endParty} startIcon={<Delete />}>
<span className="party-control-button-text">End Party</span> {/* <span className="party-control-button-text">End Party</span> */}
</Button> </Button>
)} )}
</ButtonGroup> </ButtonGroup>
</div> </div>
<div className="thread-container"> <div className="thread-container">
<Thread messages={messages} /> <Thread
messages={messages.sort((a, b) => new Date(b).getTime() - new Date(a).getTime())}
/>
</div> </div>
<TextField <TextField
multiline multiline
+2 -1
View File
@@ -157,7 +157,8 @@ const Create = (props) => {
value={joinName} value={joinName}
className="card-field addFocus" className="card-field addFocus"
onChange={(e) => setJoinName(e.target.value)} onChange={(e) => setJoinName(e.target.value)}
label="Party Name" label="Party Code"
helperText="Ask your party leader for this code"
/> />
<Button <Button
onClick={() => joinRoom({ joinName, name, props })} onClick={() => joinRoom({ joinName, name, props })}
+64
View File
@@ -16,6 +16,7 @@ export default class VideoListener {
this.firstTimeSync = this.firstTimeSync.bind(this); this.firstTimeSync = this.firstTimeSync.bind(this);
this.doUpdate = this.doUpdate.bind(this); this.doUpdate = this.doUpdate.bind(this);
this.start = this.start.bind(this); this.start = this.start.bind(this);
this.getDisneyTitle = this.getDisneyTitle.bind(this);
this.isUpdating = false; this.isUpdating = false;
} }
updateStatus(newStatus) { updateStatus(newStatus) {
@@ -27,6 +28,20 @@ export default class VideoListener {
} else return; } else return;
} }
doUpdate(serverPlayer) { 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;
}
}
if (this.video.element && this.video.status !== serverPlayer.status) { if (this.video.element && this.video.status !== serverPlayer.status) {
switch (serverPlayer.status) { switch (serverPlayer.status) {
case PLAYER_STATUS.PAUSED: case PLAYER_STATUS.PAUSED:
@@ -43,6 +58,19 @@ export default class VideoListener {
} }
} }
} }
getDisneyTitle() {
return new Promise((resolve) => {
this.video.element.click();
setTimeout(
() =>
resolve([
document.getElementsByClassName('title-field')[0].innerHTML,
document.getElementsByClassName('subtitle-field')[0].innerHTML,
]),
50
);
});
}
getShowName() { getShowName() {
switch (this.video.source) { switch (this.video.source) {
case PLAYER_SOURCE.NETFLIX: case PLAYER_SOURCE.NETFLIX:
@@ -69,6 +97,13 @@ export default class VideoListener {
const hshow = document.querySelector('.metadata-area__second-line').innerHTML; const hshow = document.querySelector('.metadata-area__second-line').innerHTML;
const hepisode = document.querySelector('.metadata-area__third-line').innerHTML; const hepisode = document.querySelector('.metadata-area__third-line').innerHTML;
return hshow === '' && hepisode === '' ? null : hshow + '\n' + hepisode; 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;
default: default:
break; break;
} }
@@ -111,6 +146,10 @@ export default class VideoListener {
this.updateStatus({ source: getPlayerSource(), showName: this.getShowName() }); this.updateStatus({ source: getPlayerSource(), showName: this.getShowName() });
switch (this.video.source) { switch (this.video.source) {
case PLAYER_SOURCE.NETFLIX: case PLAYER_SOURCE.NETFLIX:
const seekInject = `window.seekScriptLoaded=!0;var getVideoPlayer=function(){var e=window.netflix.appContext.state.playerApp.getAPI().videoPlayer,t=e.getAllPlayerSessionIds()[0];return e.getVideoPlayerBySessionId(t)},seekInteraction=function(e){if(e.source==window){if(e.data.type&&"SEEK"==e.data.type)getVideoPlayer().seek(e.data.time);e.data.type&&"teardown"==e.data.type&&(window.removeEventListener("message",seekInteraction,!1),window.seekScriptLoaded=!1)}};window.addEventListener("message",seekInteraction,!1);`;
const seekInjectScript = document.createElement('script');
seekInjectScript.text = seekInject;
document.head.appendChild(seekInjectScript);
if (document.getElementsByClassName('AkiraPlayer')[0]) { if (document.getElementsByClassName('AkiraPlayer')[0]) {
const videoElement = document const videoElement = document
.getElementsByClassName('AkiraPlayer')[0] .getElementsByClassName('AkiraPlayer')[0]
@@ -153,6 +192,31 @@ export default class VideoListener {
} }
} }
break; 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);
}
}
} 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');
if (videoElement) {
if (!this.video.element) this.firstTimeSync(videoElement);
}
}
}
});
}
break;
case PLAYER_SOURCE.LOCAL: case PLAYER_SOURCE.LOCAL:
const localVideoElement = document.getElementsByTagName('video')[0]; const localVideoElement = document.getElementsByTagName('video')[0];
if (localVideoElement) { if (localVideoElement) {
+3 -2
View File
@@ -25,7 +25,8 @@ body.hulu.visible #__player__ .Player__container.Player__container--modal {
right: calc(25% + 2rem) !important; right: calc(25% + 2rem) !important;
z-index: 99999 !important; z-index: 99999 !important;
} }
/* HULU & AMAZON PRIME FIX */ /* HULU, DISNEY & AMAZON PRIME FIX */
body.disney #party-routes-wrapper,
body.hulu #party-routes-wrapper, body.hulu #party-routes-wrapper,
body.amazon-prime #party-routes-wrapper { body.amazon-prime #party-routes-wrapper {
width: 25% !important; width: 25% !important;
@@ -204,7 +205,7 @@ body.amazon-prime textarea:focus {
} }
.room-title, .room-title,
.brand-title { .brand-title {
padding-left: 3.5rem !important; padding-left: 1rem !important;
} }
.thread-container::-webkit-scrollbar { .thread-container::-webkit-scrollbar {
width: 5px; width: 5px;
+5
View File
@@ -18,6 +18,8 @@ const firebaseConfig = {
firebase.initializeApp(firebaseConfig); firebase.initializeApp(firebaseConfig);
if (window.netflix) console.log('Netflix found');
const PartyWrapper = document.createElement('div'); const PartyWrapper = document.createElement('div');
PartyWrapper.id = 'party_wrapper'; PartyWrapper.id = 'party_wrapper';
document.body.appendChild(PartyWrapper); document.body.appendChild(PartyWrapper);
@@ -44,6 +46,9 @@ switch (getPlayerSource()) {
case PLAYER_SOURCE.AMAZON: case PLAYER_SOURCE.AMAZON:
document.body.classList.add('amazon-prime'); document.body.classList.add('amazon-prime');
break; break;
case PLAYER_SOURCE.DISNEY:
document.body.classList.add('disney');
break;
case PLAYER_SOURCE.LOCAL: case PLAYER_SOURCE.LOCAL:
const VideoPlayer = document.createElement('video'); const VideoPlayer = document.createElement('video');
VideoPlayer.autoplay = true; VideoPlayer.autoplay = true;