v1.7.8/release

- Video Listener Optimizations
- Auto Leave Fix
- Edge support
- Admin Dashboard Update
- Vimeo & Dailymotion
This commit is contained in:
2020-11-16 23:06:44 -05:00
parent cfe42bd4aa
commit 16a11f7163
66 changed files with 2559 additions and 1114 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "watch-party-crx",
"version": "1.7.7",
"version": "1.7.8",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
+118 -112
View File
@@ -15,29 +15,29 @@ COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
let CHROME_OR_BROWSER = chrome || browser;
let currentUser;
let BASE_URL = 'chromewatchparty';
let BASE_URL = "chromewatchparty";
try {
if (browser) {
BASE_URL = 'firefoxwatchparty';
console.info('FIREFOX ENV');
BASE_URL = "firefoxwatchparty";
console.info("FIREFOX ENV");
}
} catch (err) {
console.info('CHROME ENV');
console.info("CHROME ENV");
}
const APP_VERSION = '1.7.8';
const APP_VERSION_STRING = APP_VERSION.replace(/\./g, '');
const APP_VERSION = "1.7.8";
const APP_VERSION_STRING = APP_VERSION.replace(/\./g, "");
const firebaseConfig = {
apiKey: 'AIzaSyCJLuYpzXLDRmu2ttzFuSGmYcpFxqToWFU',
authDomain: 'watch-party-crx.firebaseapp.com',
databaseURL: 'https://watch-party-crx.firebaseio.com',
projectId: 'watch-party-crx',
storageBucket: 'watch-party-crx.appspot.com',
messagingSenderId: '712242707190',
appId: '1:712242707190:web:65fa7f772e30da364b0ad7',
measurementId: 'G-EZS4PEVG4T',
apiKey: "AIzaSyCJLuYpzXLDRmu2ttzFuSGmYcpFxqToWFU",
authDomain: "watch-party-crx.firebaseapp.com",
databaseURL: "https://watch-party-crx.firebaseio.com",
projectId: "watch-party-crx",
storageBucket: "watch-party-crx.appspot.com",
messagingSenderId: "712242707190",
appId: "1:712242707190:web:65fa7f772e30da364b0ad7",
measurementId: "G-EZS4PEVG4T",
};
firebase.initializeApp(firebaseConfig);
@@ -72,8 +72,8 @@ const fetcher = async (request, sendResponse) => {
method,
headers: {
Authorization: `Token ${idToken}:${firebase.auth().currentUser.uid}`,
'Access-Control-Allow-Origin': '*',
'Keep-Alive': true,
"Access-Control-Allow-Origin": "*",
"Keep-Alive": true,
},
...request,
})
@@ -95,141 +95,145 @@ const fetcher = async (request, sendResponse) => {
};
const getActiveParties = () =>
window.localStorage.getItem('activeParties')
? JSON.parse(window.localStorage.getItem('activeParties'))
window.localStorage.getItem("activeParties")
? JSON.parse(window.localStorage.getItem("activeParties"))
: {};
const updateActiveParties = (partyName, doDelete = false) => {
var activeParties = getActiveParties();
if (activeParties[partyName] && doDelete === true) {
if (new Date().getTime() - activeParties[partyName].activeAt > 60000) {
fetcher(
{
url: `https://api.chromewatchparty.com/leave/${partyName}/users/${activeParties[partyName].uid}`,
method: 'DELETE',
},
(v) => console.info('[AUTO-LEAVE]', v)
);
delete activeParties[partyName];
}
} else {
if (partyName) {
activeParties[partyName] = {
activeAt: new Date().getTime(),
uid: currentUser.uid,
};
if (partyName !== "WATCH_PARTY_STATUS") {
var activeParties = getActiveParties();
if (activeParties[partyName] && doDelete === true) {
if (
Math.round(performance.now() - activeParties[partyName].activeAt) >
60000
) {
fetcher(
{
url: `https://api.chromewatchparty.com/leave/${partyName}/users/${activeParties[partyName].uid}`,
method: "DELETE",
},
(v) => console.info("[AUTO-LEAVE]", v)
);
delete activeParties[partyName];
}
} else {
if (partyName) {
activeParties[partyName] = {
activeAt: performance.now(),
uid: currentUser.uid,
};
}
}
window.localStorage.setItem("activeParties", JSON.stringify(activeParties));
}
window.localStorage.setItem('activeParties', JSON.stringify(activeParties));
};
const waitAndLeaveParty = (partyName) => {
updateActiveParties(partyName);
setTimeout(() => updateActiveParties(partyName, true), 90000);
};
CHROME_OR_BROWSER.runtime.onInstalled.addListener((details) => {
if (details.reason) {
if (details.reason === 'install') {
if (window.localStorage.getItem('watchPartyVersion')) {
if (window.localStorage.getItem('watchPartyVersion') !== APP_VERSION) {
if (window.localStorage.getItem('showChangelog') === 'true') {
if (details.reason === "install") {
if (window.localStorage.getItem("watchPartyVersion")) {
if (window.localStorage.getItem("watchPartyVersion") !== APP_VERSION) {
if (window.localStorage.getItem("showChangelog") === "true") {
CHROME_OR_BROWSER.tabs.create({
url: `http://www.${BASE_URL}.com/changes/v${APP_VERSION}`,
active: true,
});
}
window.localStorage.setItem('watchPartyVersion', APP_VERSION);
window.localStorage.setItem("watchPartyVersion", APP_VERSION);
}
} else {
CHROME_OR_BROWSER.tabs.create({
url: `https://www.${BASE_URL}.com/welcome`,
active: true,
});
window.localStorage.setItem('watchPartyVersion', APP_VERSION);
window.localStorage.setItem("watchPartyVersion", APP_VERSION);
}
} else if (details.reason === 'update') {
if (window.localStorage.getItem('watchPartyVersion')) {
if (window.localStorage.getItem('watchPartyVersion') !== APP_VERSION) {
if (window.localStorage.getItem('showChangelog') === 'true') {
} else if (details.reason === "update") {
if (window.localStorage.getItem("watchPartyVersion")) {
if (window.localStorage.getItem("watchPartyVersion") !== APP_VERSION) {
if (window.localStorage.getItem("showChangelog") === "true") {
CHROME_OR_BROWSER.tabs.create({
url: `http://www.${BASE_URL}.com/changes/v${APP_VERSION}`,
active: true,
});
}
window.localStorage.setItem('watchPartyVersion', APP_VERSION);
window.localStorage.setItem("watchPartyVersion", APP_VERSION);
}
} else {
if (window.localStorage.getItem('showChangelog') === 'true') {
if (window.localStorage.getItem("showChangelog") === "true") {
CHROME_OR_BROWSER.tabs.create({
url: `http://www.${BASE_URL}.com/changes/v${APP_VERSION}`,
active: true,
});
}
window.localStorage.setItem('watchPartyVersion', APP_VERSION);
window.localStorage.setItem("watchPartyVersion", APP_VERSION);
}
}
}
});
CHROME_OR_BROWSER.runtime.onMessage.addListener((request, sender, sendResponse) => {
const { type } = request;
switch (type) {
case 'API_CALL':
fetcher(request, sendResponse);
break;
case 'GET_AUTH':
sendResponse({ uid: currentUser.uid });
break;
case 'GET_PARTIES':
sendResponse(
window.localStorage.getItem('parties')
? JSON.parse(window.localStorage.getItem('parties'))
: []
);
break;
case 'EMPTY_PARTIES':
window.localStorage.removeItem('parties');
break;
case 'IS_HIDDEN':
sendResponse(
window.localStorage.getItem('showWPButton')
? JSON.parse(window.localStorage.getItem('showWPButton'))
: true
);
break;
case 'GET_TUTORIAL':
sendResponse(
window.localStorage.getItem('tutorialComplete')
? JSON.parse(window.localStorage.getItem('tutorialComplete'))
: false
);
break;
case 'SET_TUTORIAL':
window.localStorage.setItem('tutorialComplete', request.status);
break;
default:
console.warn('Unknown message type: <', type, '>');
break;
CHROME_OR_BROWSER.runtime.onMessage.addListener(
(request, sender, sendResponse) => {
const { type } = request;
switch (type) {
case "API_CALL":
fetcher(request, sendResponse);
break;
case "GET_AUTH":
sendResponse({ uid: currentUser.uid });
break;
case "GET_PARTIES":
sendResponse(
window.localStorage.getItem("parties")
? JSON.parse(window.localStorage.getItem("parties"))
: []
);
break;
case "EMPTY_PARTIES":
window.localStorage.removeItem("parties");
break;
case "IS_HIDDEN":
sendResponse(
window.localStorage.getItem("showWPButton")
? JSON.parse(window.localStorage.getItem("showWPButton"))
: true
);
break;
case "GET_TUTORIAL":
sendResponse(
window.localStorage.getItem("tutorialComplete")
? JSON.parse(window.localStorage.getItem("tutorialComplete"))
: false
);
break;
case "SET_TUTORIAL":
window.localStorage.setItem("tutorialComplete", request.status);
break;
default:
console.warn("Unknown message type: <", type, ">");
break;
}
return true;
}
return true;
});
);
CHROME_OR_BROWSER.runtime.onConnect.addListener((port) => {
port.onDisconnect.addListener(() => {
updateActiveParties(port.name);
port.roomListener && port.roomListener();
port.userListener && port.userListener();
port.statusListener && port.statusListener();
port.messageListener && port.messageListener();
waitAndLeaveParty(port.partyName, port.uid);
setTimeout(() => updateActiveParties(port.name, true), 60000);
});
updateActiveParties(port.name);
port.onMessage.addListener((request) => {
const { type, roomId, roomPin } = request;
if (type === 'INIT') {
if (type === "INIT") {
port.partyName = roomId;
updateActiveParties(roomId);
port.roomListener = firebase
.firestore()
.collection('rooms')
.collection("rooms")
.doc(roomId)
.onSnapshot(
(snap) => {
@@ -243,14 +247,16 @@ CHROME_OR_BROWSER.runtime.onConnect.addListener((port) => {
);
port.userListener = firebase
.firestore()
.collection('rooms')
.collection("rooms")
.doc(roomId)
.collection('users')
.collection("users")
.onSnapshot(
(snap) => {
if (snap) {
const isAdmin = snap.docs
.filter((user) => user.id === firebase.auth().currentUser.uid)[0]
.filter(
(user) => user.id === firebase.auth().currentUser.uid
)[0]
.data().admin;
const users = snap.docs.map((userSnap) => userSnap.data().name);
port.postMessage({ admin: isAdmin, users });
@@ -262,10 +268,10 @@ CHROME_OR_BROWSER.runtime.onConnect.addListener((port) => {
);
port.messageListener = firebase
.firestore()
.collection('rooms')
.collection("rooms")
.doc(roomId)
.collection('messages')
.orderBy('time')
.collection("messages")
.orderBy("time")
.onSnapshot(
(snap) => {
if (snap) {
@@ -279,18 +285,18 @@ CHROME_OR_BROWSER.runtime.onConnect.addListener((port) => {
port.postMessage({ isError: true, ...err });
}
);
if (window.localStorage.getItem('parties')) {
var existing = JSON.parse(window.localStorage.getItem('parties'));
if (window.localStorage.getItem("parties")) {
var existing = JSON.parse(window.localStorage.getItem("parties"));
if (!(existing.filter((i) => i.name === roomId).length > 0)) {
existing.push({
name: roomId,
pin: roomPin,
});
window.localStorage.setItem('parties', JSON.stringify(existing));
window.localStorage.setItem("parties", JSON.stringify(existing));
}
} else {
window.localStorage.setItem(
'parties',
"parties",
JSON.stringify([
{
name: roomId,
@@ -299,11 +305,11 @@ CHROME_OR_BROWSER.runtime.onConnect.addListener((port) => {
])
);
}
} else if (type === 'STATUS') {
} else if (type === "STATUS") {
port.statusListener = firebase
.firestore()
.collection('server')
.doc('status')
.collection("server")
.doc("status")
.onSnapshot(
(statusSnap) => {
port.postMessage({
+7 -1
View File
@@ -44,6 +44,9 @@
"https://*.roosterteeth.com/*",
"https://*.stan.com.au/*",
"https://*.hotstar.com/*",
"https://*.airtelxstream.in/*",
"https://*.vimeo.com/*",
"https://*.dailymotion.com/*",
"https://api.giphy.com/*",
"https://*.voxeet.com/*"
],
@@ -83,7 +86,10 @@
"https://*.funimation.com/*",
"https://*.roosterteeth.com/*",
"https://*.stan.com.au/*",
"https://*.hotstar.com/*"
"https://*.hotstar.com/*",
"https://*.airtelxstream.in/*",
"https://*.vimeo.com/*",
"https://*.dailymotion.com/*"
],
"run_at": "document_idle",
"js": ["/static/js/content.js"],
+80 -52
View File
@@ -14,33 +14,36 @@ COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
let CHROME_OR_BROWSER = chrome || browser;
const API_HOST = 'https://api.chromewatchparty.com';
const API_HOST = "https://api.chromewatchparty.com";
export const PLAYER_STATUS = {
PLAYING: 'PLAYING',
PAUSED: 'PAUSED',
NOT_PLAYING: 'NOT_PLAYING',
PLAYING: "PLAYING",
PAUSED: "PAUSED",
NOT_PLAYING: "NOT_PLAYING",
};
export const PLAYER_SOURCE = {
NETFLIX: 'netflix.',
AMAZON: 'amazon.',
PRIMEVIDEO: 'primevideo.',
HULU: 'hulu.',
DISNEY: 'disneyplus.',
YOUTUBE: 'youtube.',
HBONOW: 'hbonow.',
HBOMAX: 'hbomax.',
PEACOCK: 'peacocktv.',
GOOGLEPLAY: 'play.google.',
CRUNCHYROLL: 'crunchyroll.',
APPLE: 'tv.apple.',
VIKI: 'viki.',
FUNIMATION: 'funimation.',
ROOSTERTEETH: 'roosterteeth.',
STAN: 'stan.',
HOTSTAR: 'hotstar.',
LOCAL: 'localhost',
NETFLIX: "netflix.",
AMAZON: "amazon.",
PRIMEVIDEO: "primevideo.",
HULU: "hulu.",
DISNEY: "disneyplus.",
YOUTUBE: "youtube.",
HBONOW: "hbonow.",
HBOMAX: "hbomax.",
PEACOCK: "peacocktv.",
GOOGLEPLAY: "play.google.",
CRUNCHYROLL: "crunchyroll.",
APPLE: "tv.apple.",
VIKI: "viki.",
FUNIMATION: "funimation.",
ROOSTERTEETH: "roosterteeth.",
STAN: "stan.",
HOTSTAR: "hotstar.",
AIRTEL: "airtelxstream.",
VIMEO: "vimeo.",
DAILYMOTION: "dailymotion.",
LOCAL: "localhost",
};
export const getPlayerSource = () => {
@@ -55,13 +58,19 @@ export const getPlayerSource = () => {
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.GOOGLEPLAY)) return PLAYER_SOURCE.GOOGLEPLAY;
if (HREF.includes(PLAYER_SOURCE.CRUNCHYROLL)) return PLAYER_SOURCE.CRUNCHYROLL;
if (HREF.includes(PLAYER_SOURCE.CRUNCHYROLL))
return PLAYER_SOURCE.CRUNCHYROLL;
if (HREF.includes(PLAYER_SOURCE.APPLE)) return PLAYER_SOURCE.APPLE;
if (HREF.includes(PLAYER_SOURCE.VIKI)) return PLAYER_SOURCE.VIKI;
if (HREF.includes(PLAYER_SOURCE.FUNIMATION)) return PLAYER_SOURCE.FUNIMATION;
if (HREF.includes(PLAYER_SOURCE.ROOSTERTEETH)) return PLAYER_SOURCE.ROOSTERTEETH;
if (HREF.includes(PLAYER_SOURCE.ROOSTERTEETH))
return PLAYER_SOURCE.ROOSTERTEETH;
if (HREF.includes(PLAYER_SOURCE.STAN)) return PLAYER_SOURCE.STAN;
if (HREF.includes(PLAYER_SOURCE.HOTSTAR)) return PLAYER_SOURCE.HOTSTAR;
if (HREF.includes(PLAYER_SOURCE.AIRTEL)) return PLAYER_SOURCE.AIRTEL;
if (HREF.includes(PLAYER_SOURCE.VIMEO)) return PLAYER_SOURCE.VIMEO;
if (HREF.includes(PLAYER_SOURCE.DAILYMOTION))
return PLAYER_SOURCE.DAILYMOTION;
if (HREF.includes(PLAYER_SOURCE.LOCAL)) return PLAYER_SOURCE.LOCAL;
};
@@ -69,7 +78,7 @@ export const getShowWPButton = () =>
new Promise((resolve, reject) => {
CHROME_OR_BROWSER.runtime.sendMessage(
{
type: 'IS_HIDDEN',
type: "IS_HIDDEN",
},
(response) => {
resolve(response);
@@ -81,7 +90,7 @@ export const getTutorialStatus = () =>
new Promise((resolve, reject) => {
CHROME_OR_BROWSER.runtime.sendMessage(
{
type: 'GET_TUTORIAL',
type: "GET_TUTORIAL",
},
(response) => {
resolve(response);
@@ -93,7 +102,7 @@ export const setTutorialStatus = (status) =>
new Promise((resolve, reject) => {
CHROME_OR_BROWSER.runtime.sendMessage(
{
type: 'SET_TUTORIAL',
type: "SET_TUTORIAL",
status,
},
(response) => {
@@ -103,28 +112,31 @@ export const setTutorialStatus = (status) =>
});
export const LocalData = () => {
return window.localStorage.getItem('WatchParty')
? JSON.parse(window.localStorage.getItem('WatchParty'))
return window.localStorage.getItem("WatchParty")
? JSON.parse(window.localStorage.getItem("WatchParty"))
: {};
};
export const updateLocalData = (data) => {
window.localStorage.setItem('WatchParty', JSON.stringify(Object.assign({}, LocalData(), data)));
window.localStorage.setItem(
"WatchParty",
JSON.stringify(Object.assign({}, LocalData(), data))
);
};
export const removeLocalData = (key) => {
var data = LocalData();
delete data[key];
window.localStorage.setItem('WatchParty', JSON.stringify(data));
window.localStorage.setItem("WatchParty", JSON.stringify(data));
};
export const emptyLocalData = () => {
window.localStorage.removeItem('WatchParty');
window.localStorage.removeItem("WatchParty");
};
export const scrollThread = () => {
setTimeout(function () {
const pcc = document.querySelector('.thread-wrapper');
const pcc = document.querySelector(".thread-wrapper");
if (pcc) pcc.scrollTop = pcc.scrollHeight;
}, 250);
};
@@ -133,7 +145,7 @@ export const getUserUid = async () => {
return new Promise((resolve, reject) => {
CHROME_OR_BROWSER.runtime.sendMessage(
{
type: 'GET_AUTH',
type: "GET_AUTH",
},
(response) => {
const { uid } = response;
@@ -149,7 +161,7 @@ export const fetcher = async ({ endpoint, method, ...args }) => {
return new Promise((resolve, reject) =>
CHROME_OR_BROWSER.runtime.sendMessage(
{
type: 'API_CALL',
type: "API_CALL",
url,
method,
...args,
@@ -166,9 +178,9 @@ export const webhookFetcher = async ({ endpoint, ...args }) => {
return new Promise((resolve, reject) =>
CHROME_OR_BROWSER.runtime.sendMessage(
{
type: 'API_CALL',
type: "API_CALL",
url: endpoint,
method: 'POST',
method: "POST",
...args,
},
(response) => {
@@ -181,24 +193,24 @@ export const webhookFetcher = async ({ endpoint, ...args }) => {
export const CreateRoomApi = async (data) => {
return fetcher({
endpoint: 'create',
method: 'POST',
endpoint: "create",
method: "POST",
body: JSON.stringify(data),
});
};
export const JoinRoomApi = async (data) => {
return fetcher({
endpoint: 'join',
method: 'POST',
endpoint: "join",
method: "POST",
body: JSON.stringify(data),
});
};
export const SendMessageApi = async (data) => {
return fetcher({
endpoint: 'message',
method: 'POST',
endpoint: "message",
method: "POST",
body: JSON.stringify(data),
});
};
@@ -206,21 +218,21 @@ export const SendMessageApi = async (data) => {
export const LeaveRoomApi = async (data) => {
return fetcher({
endpoint: `leave/${data.partyName}/users/${data.userUid}`,
method: 'DELETE',
method: "DELETE",
});
};
export const DeleteRoomApi = async (data) => {
return fetcher({
endpoint: `delete/${data.partyName}`,
method: 'DELETE',
method: "DELETE",
});
};
export const UpdatePlayerApi = async (data) => {
return fetcher({
endpoint: 'updatePlayer',
method: 'POST',
endpoint: "updatePlayer",
method: "POST",
body: JSON.stringify(data),
});
};
@@ -228,21 +240,21 @@ export const UpdatePlayerApi = async (data) => {
export const GetVoxeetTokenApi = async (data) => {
return fetcher({
endpoint: `validator/${data.partyName}`,
method: 'GET',
method: "GET",
});
};
export const GetRefreshedVoxeetTokenApi = async (data) => {
return fetcher({
endpoint: `refresher/${data.token}`,
method: 'GET',
method: "GET",
});
};
export const UpdateVoxeetApi = async (data) => {
return fetcher({
endpoint: 'updateVoxeet',
method: 'POST',
endpoint: "updateVoxeet",
method: "POST",
body: JSON.stringify(data),
});
};
@@ -250,6 +262,22 @@ export const UpdateVoxeetApi = async (data) => {
export const UpdateAdminOnly = async (data) => {
return fetcher({
endpoint: `updateAdminOnly/${data.partyName}/${data.adminOnly}`,
method: 'PUT',
method: "PUT",
});
};
export const UpdateDailymotionVariables = () => {
if (getPlayerSource() === PLAYER_SOURCE.DAILYMOTION) {
const placeholder = document.getElementById("watching-player-placeholder");
if (placeholder) {
document.documentElement.style.setProperty(
"--dailymotion-player-height",
`${placeholder.offsetHeight}px`
);
document.documentElement.style.setProperty(
"--dailymotion-player-left",
`${placeholder.getBoundingClientRect().left}px`
);
}
}
};
+77 -43
View File
@@ -12,32 +12,39 @@ COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
/*global chrome*/
/*global browser*/
import React, { useState, useEffect } from 'react';
import Router from 'route-lite';
import { Fab, createMuiTheme, ThemeProvider, Snackbar, Tooltip } from '@material-ui/core';
import Create from './Create';
import Loading from './Loading';
import Inactive from './Inactive';
import React, { useState, useEffect } from "react";
import Router from "route-lite";
import {
Fab,
createMuiTheme,
ThemeProvider,
Snackbar,
Tooltip,
} from "@material-ui/core";
import Create from "./Create";
import Loading from "./Loading";
import Inactive from "./Inactive";
import {
getUserUid,
getPlayerSource,
PLAYER_SOURCE,
getShowWPButton,
getTutorialStatus,
} from './Api';
import Tutorial from './Tutorial';
UpdateDailymotionVariables,
} from "./Api";
import Tutorial from "./Tutorial";
const APP_VERSION = '1.7.8';
const APP_VERSION_STRING = APP_VERSION.replace(/\./g, '');
const APP_VERSION = "1.7.8";
const APP_VERSION_STRING = APP_VERSION.replace(/\./g, "");
const darkTheme = createMuiTheme({
palette: {
type: 'dark',
type: "dark",
primary: {
main: '#FF0000',
main: "#FF0000",
},
secondary: {
main: '#beff94',
main: "#beff94",
},
},
});
@@ -50,40 +57,51 @@ const Routes = (props) => (
const resetResize = () => {
const checkedX = 425;
document.documentElement.style.setProperty('--party-width', `${checkedX}px`);
document.documentElement.style.setProperty('--neg-party-width', `-${checkedX}px`);
document.documentElement.style.setProperty("--party-width", `${checkedX}px`);
document.documentElement.style.setProperty(
"--neg-party-width",
`-${checkedX}px`
);
UpdateDailymotionVariables();
};
const doResize = (ev) => {
const checkedX =
window.innerWidth -
Math.min(window.innerWidth - 300, Math.max(window.innerWidth * 0.5, ev.clientX));
document.documentElement.style.setProperty('--party-width', `${checkedX}px`);
document.documentElement.style.setProperty('--neg-party-width', `-${checkedX}px`);
Math.min(
window.innerWidth - 300,
Math.max(window.innerWidth * 0.5, ev.clientX)
);
document.documentElement.style.setProperty("--party-width", `${checkedX}px`);
document.documentElement.style.setProperty(
"--neg-party-width",
`-${checkedX}px`
);
};
const stopResize = (ev) => {
document.documentElement.removeEventListener('mousemove', doResize, false);
document.documentElement.removeEventListener('mouseup', stopResize, false);
document.documentElement.removeEventListener("mousemove", doResize, false);
document.documentElement.removeEventListener("mouseup", stopResize, false);
UpdateDailymotionVariables();
};
const startResize = (ev) => {
ev.preventDefault();
ev.stopPropagation();
document.documentElement.addEventListener('mousemove', doResize, false);
document.documentElement.addEventListener('mouseup', stopResize, false);
document.documentElement.addEventListener("mousemove", doResize, false);
document.documentElement.addEventListener("mouseup", stopResize, false);
};
let CHROME_OR_BROWSER = chrome || browser;
let port;
const App = () => {
const closedNotification = { open: false, message: '' };
const closedNotification = { open: false, message: "" };
const [tutorialComponent, setTutorialComponent] = useState(null);
const [showFab, setShowFab] = useState(false);
const [tutorialComplete, setTutorialComplete] = useState(false);
const [status, setStatus] = useState({ active: false, message: '' });
const [status, setStatus] = useState({ active: false, message: "" });
const [visible, setVisible] = useState(false);
const [loading, setLoading] = useState(false);
const [notification, setNotification] = useState(closedNotification);
@@ -93,7 +111,7 @@ const App = () => {
getUserUid();
port = CHROME_OR_BROWSER.runtime.connect({ name: `WATCH_PARTY_STATUS` });
port.postMessage({
type: 'STATUS',
type: "STATUS",
});
port.onMessage.addListener((response) => {
setStatus(response.status);
@@ -102,10 +120,14 @@ const App = () => {
getShowWPButton().then((showWPButton) => {
setShowFab(showWPButton);
if (showWPButton === true) {
document.querySelector('.watch-party-fab').classList.remove('watch-party-fab-hidden');
document
.querySelector(".watch-party-fab")
.classList.remove("watch-party-fab-hidden");
document.querySelector(
'.watch-party-fab'
).style.backgroundImage = `url("${CHROME_OR_BROWSER.extension.getURL('wp192.png')}")`;
".watch-party-fab"
).style.backgroundImage = `url("${CHROME_OR_BROWSER.extension.getURL(
"wp192.png"
)}")`;
}
});
}, []);
@@ -113,23 +135,28 @@ const App = () => {
getTutorialStatus().then((v) => setTutorialComplete(v));
// HANDLE VISIBILITY STYLING
const PartyRoutesWrapper = document.getElementById('party-routes-wrapper');
const PartyRoutesWrapper = document.getElementById("party-routes-wrapper");
if (visible) {
document.body.classList.add('visible');
PartyRoutesWrapper && PartyRoutesWrapper.classList.add('visible');
document.body.classList.add("visible");
PartyRoutesWrapper && PartyRoutesWrapper.classList.add("visible");
if (getPlayerSource() === PLAYER_SOURCE.APPLE) {
const appleTvPlayer = document.querySelector('apple-tv-plus-player');
const takeoverContainer = appleTvPlayer.shadowRoot.querySelector('.takeover.container.show');
if (takeoverContainer) takeoverContainer.style.maxWidth = 'var(--body-width)';
const appleTvPlayer = document.querySelector("apple-tv-plus-player");
const takeoverContainer = appleTvPlayer.shadowRoot.querySelector(
".takeover.container.show"
);
if (takeoverContainer)
takeoverContainer.style.maxWidth = "var(--body-width)";
}
} else {
if (getPlayerSource() === PLAYER_SOURCE.APPLE) {
const appleTvPlayer = document.querySelector('apple-tv-plus-player');
const takeoverContainer = appleTvPlayer.shadowRoot.querySelector('.takeover.container.show');
if (takeoverContainer) takeoverContainer.style.maxWidth = 'none';
const appleTvPlayer = document.querySelector("apple-tv-plus-player");
const takeoverContainer = appleTvPlayer.shadowRoot.querySelector(
".takeover.container.show"
);
if (takeoverContainer) takeoverContainer.style.maxWidth = "none";
}
document.body.classList.remove('visible');
PartyRoutesWrapper && PartyRoutesWrapper.classList.remove('visible');
document.body.classList.remove("visible");
PartyRoutesWrapper && PartyRoutesWrapper.classList.remove("visible");
}
// HANDLE FULLSCREEN EVENT
@@ -142,11 +169,13 @@ const App = () => {
setTutorialComplete(false);
};
UpdateDailymotionVariables();
return (
<ThemeProvider theme={darkTheme}>
<Snackbar
className="party-notification-container"
anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}
anchorOrigin={{ vertical: "bottom", horizontal: "right" }}
open={notification.open}
onClose={() => setNotification(closedNotification)}
message={notification.message}
@@ -166,12 +195,17 @@ const App = () => {
title="Resize Sidebar / Double Click To Reset"
aria-label="Resize Sidebar / Double Click To Reset"
>
<div onDoubleClick={resetResize} onMouseDown={startResize} id="party-width-dragger">
<div
onDoubleClick={resetResize}
onMouseDown={startResize}
id="party-width-dragger"
>
||
</div>
</Tooltip>
{loading && <Loading />}
{status[APP_VERSION_STRING] && status[APP_VERSION_STRING].active === true ? (
{status[APP_VERSION_STRING] &&
status[APP_VERSION_STRING].active === true ? (
<Routes
showFab={showFab}
resetTutorial={resetTutorial}
@@ -192,7 +226,7 @@ const App = () => {
status={
status[APP_VERSION_STRING]
? status[APP_VERSION_STRING].message
: 'Connecting to server...'
: "Connecting to server..."
}
/>
)}
+48 -40
View File
@@ -9,14 +9,14 @@ ALL CONTENT ON WATCH PARTY'S WEBSITE OR IN WATCH PARTY'S CHROME EXTENSION APP, U
CITED ARE THE SOLE INTELLECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE
COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
************************************************************************/
import VoxeetSDK from '@voxeet/voxeet-web-sdk';
import VoxeetSDK from "@voxeet/voxeet-web-sdk";
import {
GetVoxeetTokenApi,
GetRefreshedVoxeetTokenApi,
LocalData,
UpdateVoxeetApi,
updateLocalData,
} from './Api';
} from "./Api";
export default class CallManager {
constructor(listener, notify) {
@@ -38,7 +38,7 @@ export default class CallManager {
if (onCall === true) this.leaveCall();
else this.boot(conference, useVideo);
} catch (e) {
this.notify('Uh oh something went wrong, try rejoining the call.');
this.notify("Uh oh something went wrong, try rejoining the call.");
}
}
toggleMute(muted) {
@@ -48,9 +48,11 @@ export default class CallManager {
}
toggleVideo(useVideo) {
if (useVideo === true) {
VoxeetSDK.conference.startVideo(VoxeetSDK.session.participant).then(() => {
this.listener({ usingVideo: useVideo });
});
VoxeetSDK.conference
.startVideo(VoxeetSDK.session.participant)
.then(() => {
this.listener({ usingVideo: useVideo });
});
} else {
VoxeetSDK.conference.stopVideo(VoxeetSDK.session.participant).then(() => {
this.listener({ usingVideo: useVideo });
@@ -65,14 +67,14 @@ export default class CallManager {
.fetch(conference._id)
.then((c) => this.joinCall(c, useVideo))
.catch((err) => {
console.error('Failed to fetch conference', err);
console.error("Failed to fetch conference", err);
this.startCall(useVideo);
});
} else if (opened && !conference) {
this.startCall(useVideo);
} else {
this.listener({ onCall: false, muted: false, callActionPending: false });
console.error('Unable to open Voxeet Session');
console.error("Unable to open Voxeet Session");
}
}
async startCall(useVideo) {
@@ -103,7 +105,7 @@ export default class CallManager {
callActionPending: false,
usingVideo: false,
});
console.error('Update Voxeet API Error', err);
console.error("Update Voxeet API Error", err);
return false;
}
});
@@ -116,11 +118,11 @@ export default class CallManager {
callActionPending: false,
usingVideo: false,
});
console.error('Failed to update party Voxeet');
console.error("Failed to update party Voxeet");
}
});
} else {
this.notify('Ask your party admin to start the call.');
this.notify("Ask your party admin to start the call.");
this.leaveCall();
}
}
@@ -135,8 +137,8 @@ export default class CallManager {
callActionPending: false,
usingVideo: false,
});
this.notify('Unable to join call. Try again in a moment.');
console.error('Error joining call', e);
this.notify("Unable to join call. Try again in a moment.");
console.error("Error joining call", e);
return false;
});
if (joined === true) {
@@ -168,19 +170,23 @@ export default class CallManager {
});
return true;
} catch (error) {
console.error('Error Opening Voxeet Session', error);
console.error("Error Opening Voxeet Session", error);
}
console.error('Session not initialized');
console.error("Session not initialized");
return false;
}
return true;
}
async initialize() {
VoxeetSDK.conference.on('joined', () => {
this.listener({ onCall: true, callActionPending: false, usingVideo: this.__useVideo });
VoxeetSDK.conference.on("joined", () => {
this.listener({
onCall: true,
callActionPending: false,
usingVideo: this.__useVideo,
});
});
VoxeetSDK.conference.on('left', () => {
VoxeetSDK.conference.on("left", () => {
this.listener({
onCall: false,
callActionPending: false,
@@ -189,34 +195,34 @@ export default class CallManager {
});
});
VoxeetSDK.conference.on('streamAdded', (participant, stream) => {
VoxeetSDK.conference.on("streamAdded", (participant, stream) => {
this.listener({ callActionPending: true });
const vid = 'video#' + CSS.escape(participant.id);
const vid = "video#" + CSS.escape(participant.id);
if (!document.querySelector(vid)) {
const vidNode = document.createElement('video');
const vidNode = document.createElement("video");
vidNode.id = participant.id;
vidNode.muted = true;
vidNode.srcObject = stream;
vidNode.onloadedmetadata = vidNode.play;
const vidContainerNode = document.createElement('div');
vidContainerNode.classList.add('vxt-video');
vidContainerNode.setAttribute('data-id', participant.id);
vidContainerNode.setAttribute('data-name', participant.info.name || '');
const vidContainerNode = document.createElement("div");
vidContainerNode.classList.add("vxt-video");
vidContainerNode.setAttribute("data-id", participant.id);
vidContainerNode.setAttribute("data-name", participant.info.name || "");
vidContainerNode.appendChild(vidNode);
if (participant.info.externalId !== LocalData().userUid) {
const volSliderNode = document.createElement('input');
volSliderNode.setAttribute('type', 'range');
volSliderNode.min = '0';
volSliderNode.max = '1';
volSliderNode.value = '1';
volSliderNode.step = '0.1';
volSliderNode.id = 'vxt-slider-' + participant.id;
volSliderNode.classList.add('vxt-slider');
const volSliderNode = document.createElement("input");
volSliderNode.setAttribute("type", "range");
volSliderNode.min = "0";
volSliderNode.max = "1";
volSliderNode.value = "1";
volSliderNode.step = "0.1";
volSliderNode.id = "vxt-slider-" + participant.id;
volSliderNode.classList.add("vxt-slider");
volSliderNode.onchange = (e) => {
const v = e.target.value;
const audioOuts = document.querySelectorAll('audio.vxt-audio');
const audioOuts = document.querySelectorAll("audio.vxt-audio");
if (audioOuts.length > 0) {
audioOuts.forEach((el) => {
if (el.id === `audio-${participant.id}`) {
@@ -228,14 +234,16 @@ export default class CallManager {
vidContainerNode.appendChild(volSliderNode);
}
document.querySelector('.vxt-video-container').appendChild(vidContainerNode);
document
.querySelector(".vxt-video-container")
.appendChild(vidContainerNode);
}
this.listener({ callActionPending: false });
});
VoxeetSDK.conference.on('streamRemoved', (participant, stream) => {
VoxeetSDK.conference.on("streamRemoved", (participant, stream) => {
const vcid = ".vxt-video[data-id='" + CSS.escape(participant.id) + "']";
const vid = 'video#' + CSS.escape(participant.id);
const vid = "video#" + CSS.escape(participant.id);
if (document.querySelector(vcid)) {
document
.querySelector(vid)
@@ -262,11 +270,11 @@ export default class CallManager {
this.updateTokens(access_token, refresh_token);
await VoxeetSDK.initializeToken(access_token, refresh_token);
} else {
console.error('Get Voxeet Token API Result Error', tokenResult);
console.error("Get Voxeet Token API Result Error", tokenResult);
}
})
.catch((err) => {
console.error('Get Voxeet Token API error', err);
console.error("Get Voxeet Token API error", err);
});
} else {
await VoxeetSDK.initializeToken(this.__accessToken, this.__refreshToken);
@@ -282,7 +290,7 @@ export default class CallManager {
resolve(access_token);
})
.catch((err) => {
console.error('Get Voxeet Token API error', err);
console.error("Get Voxeet Token API error", err);
reject(err);
});
});
+269 -144
View File
@@ -12,7 +12,7 @@ COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
/*global chrome*/
/*global browser*/
import React, { Component } from 'react';
import React, { Component } from "react";
import {
Typography,
TextField,
@@ -35,8 +35,8 @@ import {
MenuItem,
FormControl,
InputLabel,
} from '@material-ui/core';
import Thread from './Thread';
} from "@material-ui/core";
import Thread from "./Thread";
import {
SendMessageApi,
LeaveRoomApi,
@@ -50,7 +50,7 @@ import {
removeLocalData,
PLAYER_SOURCE,
getPlayerSource,
} from './Api';
} from "./Api";
import {
Send,
ExitToApp as Exit,
@@ -72,13 +72,13 @@ import {
CancelRounded,
VideocamRounded,
VideocamOffRounded,
} from '@material-ui/icons';
import Create from './Create';
import { goTo } from 'route-lite';
import CallManager from './CallManager';
import VideoListener from './VideoListener';
import ReactGiphySearchbox from 'react-giphy-searchbox';
import VoxeetSDK from '@voxeet/voxeet-web-sdk';
} from "@material-ui/icons";
import Create from "./Create";
import { goTo } from "route-lite";
import CallManager from "./CallManager";
import VideoListener from "./VideoListener";
import ReactGiphySearchbox from "react-giphy-searchbox";
import VoxeetSDK from "@voxeet/voxeet-web-sdk";
let CHROME_OR_BROWSER = chrome || browser;
@@ -86,9 +86,9 @@ export default class Chat extends Component {
constructor(props) {
super(props);
this.state = {
name: '',
name: "",
messages: [],
newMessage: '',
newMessage: "",
admin: null,
adminOnly: false,
adminModeUpdate: false,
@@ -99,21 +99,27 @@ export default class Chat extends Component {
callActionPending: false,
menuPopover: true,
allowChatNotification:
LocalData().allowChatNotification !== undefined ? LocalData().allowChatNotification : true,
LocalData().allowChatNotification !== undefined
? LocalData().allowChatNotification
: true,
isFullscreen: document.fullscreen,
allowAutoRejoin:
LocalData().allowAutoRejoin !== undefined ? LocalData().allowAutoRejoin : true,
LocalData().allowAutoRejoin !== undefined
? LocalData().allowAutoRejoin
: true,
allowAutoFollow:
LocalData().allowAutoFollow !== undefined ? LocalData().allowAutoFollow : false,
LocalData().allowAutoFollow !== undefined
? LocalData().allowAutoFollow
: false,
replyTo: null,
sendingMessages: [],
usingVideo: false,
audioInputs: [],
selectedAudioInput: '',
selectedAudioInput: "",
audioOutputs: [],
selectedAudioOutput: '',
selectedAudioOutput: "",
videoInputs: [],
selectedVideoInput: '',
selectedVideoInput: "",
};
this.port = null;
this.gifClick = this.gifClick.bind(this);
@@ -137,15 +143,21 @@ export default class Chat extends Component {
);
this.updateAllowAutoRejoin = this.updateAllowAutoRejoin.bind(this);
this.updateAllowAutoFollow = this.updateAllowAutoFollow.bind(this);
this.updateAllowChatNotification = this.updateAllowChatNotification.bind(this);
this.mCallManager = new CallManager(this.callEventListener, this.props.notify);
this.updateAllowChatNotification = this.updateAllowChatNotification.bind(
this
);
this.mCallManager = new CallManager(
this.callEventListener,
this.props.notify
);
}
componentDidMount() {
// EVENT CAPTURE FOR ENTER TO SEND
window.onkeypress = (ev) => {
if (ev.code === 'Enter') {
if (ev.target === document.getElementById('chat-message-box-input')) {
if (ev.shiftKey === false && this.state.gif === true) ev.preventDefault();
if (ev.code === "Enter") {
if (ev.target === document.getElementById("chat-message-box-input")) {
if (ev.shiftKey === false && this.state.gif === true)
ev.preventDefault();
if (ev.shiftKey === false && this.state.gif === false) {
ev.preventDefault();
this.sendMessageInvoker();
@@ -155,12 +167,15 @@ export default class Chat extends Component {
};
// FULLSCREEN LISTENER
document.addEventListener('fullscreenchange', (ev) => {
document.addEventListener("fullscreenchange", (ev) => {
this.setState({ isFullscreen: document.fullscreen });
});
// ACTIVE TRACKER
if (LocalData().allowAutoRejoin === undefined || LocalData().allowAutoRejoin === null) {
if (
LocalData().allowAutoRejoin === undefined ||
LocalData().allowAutoRejoin === null
) {
updateLocalData({ allowAutoRejoin: this.state.allowAutoRejoin });
}
if (this.state.allowAutoRejoin === true) {
@@ -176,23 +191,25 @@ export default class Chat extends Component {
this.mVideoListener.start();
// CHROME FIREBASE FIRESTORE LISTENER
this.port = CHROME_OR_BROWSER.runtime.connect({ name: LocalData().partyName });
this.port = CHROME_OR_BROWSER.runtime.connect({
name: LocalData().partyName,
});
// Initialize listener
this.port.postMessage({
type: 'INIT',
type: "INIT",
roomId: LocalData().partyName,
roomPin: LocalData().partyPin,
});
// Listener
this.port.onMessage.addListener((response) => {
if (response.isError === true) {
this.props.notify('Uh oh. Got lost from the party.');
this.props.notify("Uh oh. Got lost from the party.");
goTo(Create, this.props);
return;
} else {
// CONTINUE TUTORIAL
if (this.props.tutorialComplete === false) {
this.props.resetTutorial('chat');
this.props.resetTutorial("chat");
}
}
@@ -201,13 +218,21 @@ export default class Chat extends Component {
}
// IF CHAT IS HIDDEN AND ALLOWS NOTIFICATION
if (!document.querySelector('body.visible') && this.state.allowChatNotification === true) {
if (response.messages && response.messages.length !== this.state.messages.length) {
if (
!document.querySelector("body.visible") &&
this.state.allowChatNotification === true
) {
if (
response.messages &&
response.messages.length !== this.state.messages.length
) {
const lastMessage = response.messages[response.messages.length - 1];
if (lastMessage.uid !== '<system>') {
if (lastMessage.uid !== "<system>") {
this.props.notify(
`${lastMessage.name}${
lastMessage.type === 'giphy' ? ' sent a gif.' : ': ' + lastMessage.text
lastMessage.type === "giphy"
? " sent a gif."
: ": " + lastMessage.text
}`
);
}
@@ -223,7 +248,7 @@ export default class Chat extends Component {
// GIPHY IPC
const giphyInject = `var giphySearchInteraction=function(e){if(e.source===window){const{data}=e;if(data.watchPartyDirection==='TO_SCRIPT'){if(data.type==='WATCH_PARTY_SEARCH_GIF'){const giphyInput=document.querySelector('.giphy-search-form input');if(giphyInput){giphyInput.value=data.value;giphyInput.dispatchEvent(new Event('change',{bubbles:true}))}}}}};window.addEventListener("message",giphySearchInteraction);`;
const giphyInjectScript = document.createElement('script');
const giphyInjectScript = document.createElement("script");
giphyInjectScript.text = giphyInject;
document.head.appendChild(giphyInjectScript);
@@ -257,22 +282,22 @@ export default class Chat extends Component {
callEventListener(event) {
this.setState(event);
if (event.onCall === true) {
VoxeetSDK.mediaDevice.enumerateAudioDevices('input').then((devices) => {
VoxeetSDK.mediaDevice.enumerateAudioDevices("input").then((devices) => {
this.setState({
audioInputs: devices,
selectedAudioInput: devices.length > 0 ? devices[0].deviceId : '',
selectedAudioInput: devices.length > 0 ? devices[0].deviceId : "",
});
});
VoxeetSDK.mediaDevice.enumerateAudioDevices('output').then((devices) => {
VoxeetSDK.mediaDevice.enumerateAudioDevices("output").then((devices) => {
this.setState({
audioOutputs: devices,
selectedAudioOutput: devices.length > 0 ? devices[0].deviceId : '',
selectedAudioOutput: devices.length > 0 ? devices[0].deviceId : "",
});
});
VoxeetSDK.mediaDevice.enumerateVideoDevices('output').then((devices) => {
VoxeetSDK.mediaDevice.enumerateVideoDevices("output").then((devices) => {
this.setState({
videoInputs: devices,
selectedVideoInput: devices.length > 0 ? devices[0].deviceId : '',
selectedVideoInput: devices.length > 0 ? devices[0].deviceId : "",
});
});
}
@@ -295,14 +320,14 @@ export default class Chat extends Component {
}).catch((err) => {
this.props.updateLoading(false);
this.props.notify(err.message || err.statusText);
console.error('Sync Party API error', err);
console.error("Sync Party API error", err);
});
} else {
this.mVideoListener.start();
}
}
endParty() {
this.props.notify('Ending party...');
this.props.notify("Ending party...");
this.props.updateLoading(true);
const data = {
partyName: LocalData().partyName,
@@ -317,20 +342,20 @@ export default class Chat extends Component {
);
DeleteRoomApi(data)
.then((res) => {
this.props.notify('Ended party');
removeLocalData('partyPin');
removeLocalData('partyName');
this.props.notify("Ended party");
removeLocalData("partyPin");
removeLocalData("partyName");
goTo(Create, this.props);
this.props.updateLoading(false);
})
.catch((err) => {
this.props.updateLoading(false);
this.props.notify(err.message || err.statusText);
console.error('End Party API error', err);
console.error("End Party API error", err);
});
}
leaveParty() {
this.props.notify('Leaving party...');
this.props.notify("Leaving party...");
this.props.updateLoading(true);
const data = {
partyName: LocalData().partyName,
@@ -346,28 +371,30 @@ export default class Chat extends Component {
);
LeaveRoomApi(data)
.then((res) => {
this.props.notify('Left party');
removeLocalData('partyPin');
removeLocalData('partyName');
this.props.notify("Left party");
removeLocalData("partyPin");
removeLocalData("partyName");
goTo(Create, this.props);
this.props.updateLoading(false);
})
.catch((err) => {
this.props.updateLoading(false);
this.props.notify(err.message || err.statusText);
console.error('End Party API error', err);
console.error("End Party API error", err);
});
}
shareParty() {
const el = document.createElement('textarea');
el.value = `Join my party on Watch Party!\nParty Name: ${LocalData().partyName}\nParty Pin: ${
LocalData().partyPin
}\n${window.location.href}\n---\nGet Watch Party at https:\\\\get.chromewatchparty.com`;
const el = document.createElement("textarea");
el.value = `Join my party on Watch Party!\nParty Name: ${
LocalData().partyName
}\nParty Pin: ${LocalData().partyPin}\n${
window.location.href
}\n---\nGet Watch Party at https:\\\\get.chromewatchparty.com`;
document.body.appendChild(el);
el.select();
document.execCommand('copy');
document.execCommand("copy");
document.body.removeChild(el);
this.props.notify('Copied party invitation');
this.props.notify("Copied party invitation");
}
sendMessage(message) {
const { sendingMessages } = this.state;
@@ -378,9 +405,9 @@ export default class Chat extends Component {
uid: LocalData().userUid,
text: message,
time: new Date(),
type: '',
type: "",
};
if (this.state.gif === true) data.type = 'giphy';
if (this.state.gif === true) data.type = "giphy";
if (this.state.replyTo !== null) data.replyTo = this.state.replyTo.id;
sendingMessages.push(data);
this.setState({
@@ -401,7 +428,7 @@ export default class Chat extends Component {
this.setState({ sendingMessages: sm });
scrollThread();
this.props.notify(err.message || err.statusText);
console.error('Send Message API error', err);
console.error("Send Message API error", err);
});
this.setState({ replyTo: null });
scrollThread();
@@ -409,10 +436,10 @@ export default class Chat extends Component {
sendMessageInvoker(overrideMessage) {
if (overrideMessage) this.sendMessage(overrideMessage);
else {
const trim = this.state.newMessage.replace(/^\s+|\s+$/g, '');
if (trim !== '') this.sendMessage(trim);
const trim = this.state.newMessage.replace(/^\s+|\s+$/g, "");
if (trim !== "") this.sendMessage(trim);
}
this.setState({ newMessage: '' });
this.setState({ newMessage: "" });
}
gifClick(iGif) {
this.sendMessageInvoker(iGif.images.original.url);
@@ -421,12 +448,12 @@ export default class Chat extends Component {
const { onCall, conference, admin, adminOnly } = this.state;
if (window.navigator && onCall === false) {
try {
const overlay = document.createElement('div');
const overlay = document.createElement("div");
overlay.innerHTML = `
<div id="mic-highlight"></div>
<h4 id="mic-text">Grant Mic / Camera Permission</h4>
`;
overlay.id = 'mic-permission-overlay';
overlay.id = "mic-permission-overlay";
document.body.appendChild(overlay);
window.navigator
.getUserMedia({
@@ -439,32 +466,51 @@ export default class Chat extends Component {
video: true,
})
.then(() => {
document.getElementById('mic-permission-overlay').remove();
this.mCallManager.toggleCall(onCall, conference, admin, adminOnly, useVideo);
document.getElementById("mic-permission-overlay").remove();
this.mCallManager.toggleCall(
onCall,
conference,
admin,
adminOnly,
useVideo
);
})
.catch(() => {
document.getElementById('mic-permission-overlay').remove();
document.getElementById("mic-permission-overlay").remove();
this.props.notify(
'Check your camera permission for this website. You can modify site permission by clicking on the lock (🔒) icon in the top left, then clicking site permissions.',
"Check your camera permission for this website. You can modify site permission by clicking on the lock (🔒) icon in the top left, then clicking site permissions.",
15000
);
});
} else {
document.getElementById('mic-permission-overlay').remove();
this.mCallManager.toggleCall(onCall, conference, admin, adminOnly, useVideo);
document.getElementById("mic-permission-overlay").remove();
this.mCallManager.toggleCall(
onCall,
conference,
admin,
adminOnly,
useVideo
);
}
})
.catch(() => {
document.getElementById('mic-permission-overlay').remove();
document.getElementById("mic-permission-overlay").remove();
this.props.notify(
'Check your mic permission for this website. You can modify site permission by clicking on the lock (🔒) icon in the top left, then clicking site permissions.',
"Check your mic permission for this website. You can modify site permission by clicking on the lock (🔒) icon in the top left, then clicking site permissions.",
15000
);
});
} catch (err) {
console.error('Handle Phone Call Error', err);
console.error("Handle Phone Call Error", err);
}
} else this.mCallManager.toggleCall(onCall, conference, admin, adminOnly, useVideo);
} else
this.mCallManager.toggleCall(
onCall,
conference,
admin,
adminOnly,
useVideo
);
}
handleMute() {
this.mCallManager.toggleMute(this.state.muted);
@@ -502,7 +548,7 @@ export default class Chat extends Component {
adminOnly: !this.state.adminOnly,
}).catch((err) => {
this.props.notify(err.message || err.statusText);
console.error('Update Admin Only API error', err);
console.error("Update Admin Only API error", err);
});
}
setReplyTo(message) {
@@ -514,7 +560,7 @@ export default class Chat extends Component {
getReplyToContent() {
const { replyTo } = this.state;
if (replyTo) {
if (replyTo.type === 'giphy') {
if (replyTo.type === "giphy") {
return <img alt="gif" src={replyTo.text} />;
}
return (
@@ -562,15 +608,17 @@ export default class Chat extends Component {
const alerts = [
{
condition: () => adminOnly,
message: 'Party is currently in admin only mode.',
message: "Party is currently in admin only mode.",
},
{
condition: () => getPlayerSource() === PLAYER_SOURCE.FUNIMATION,
message: 'If sync stops working, try (Ctrl + Shift + R) or (⌘ + Shift + R)',
message:
"If sync stops working, try (Ctrl + Shift + R) or (⌘ + Shift + R)",
},
{
condition: () => window.location.href.includes(PLAYER_SOURCE.PRIMEVIDEO),
message: 'Support on Prime Video is untested, and may be buggy.',
condition: () =>
window.location.href.includes(PLAYER_SOURCE.PRIMEVIDEO),
message: "Support on Prime Video is untested, and may be buggy.",
},
];
return (
@@ -597,7 +645,12 @@ export default class Chat extends Component {
>
WATCH PARTY
</Typography>
<Typography color="textPrimary" className="room-title" variant="h4" gutterBottom>
<Typography
color="textPrimary"
className="room-title"
variant="h4"
gutterBottom
>
{name}
</Typography>
</div>
@@ -606,9 +659,9 @@ export default class Chat extends Component {
<TextField
className="share-textbox"
label="Party Details"
value={`Party Name: ${LocalData().partyName}\nParty Pin: ${LocalData().partyPin}\n${
window.location.href
}`}
value={`Party Name: ${LocalData().partyName}\nParty Pin: ${
LocalData().partyPin
}\n${window.location.href}`}
multiline
rowsMax={2}
variant="outlined"
@@ -635,13 +688,19 @@ export default class Chat extends Component {
color="secondary"
>
<Button onClick={this.leaveParty} startIcon={<Exit />}>
<Typography variant="caption" className="party-control-button-text">
<Typography
variant="caption"
className="party-control-button-text"
>
Leave
</Typography>
</Button>
{admin && (
<Button onClick={this.endParty} startIcon={<Delete />}>
<Typography variant="caption" className="party-control-button-text">
<Typography
variant="caption"
className="party-control-button-text"
>
End
</Typography>
</Button>
@@ -654,15 +713,17 @@ export default class Chat extends Component {
checked={allowChatNotification}
onChange={this.updateAllowChatNotification}
name="allowChatNotification"
color={allowChatNotification ? 'secondary' : 'primary'}
color={allowChatNotification ? "secondary" : "primary"}
/>
}
label={
<span>
Allow chat notification when side panel is closed
<br />
<span style={{ color: '#8a8a8a' }}>
{allowChatNotification ? 'Notifications Enabled' : 'Notifications Disabled'}
<span style={{ color: "#8a8a8a" }}>
{allowChatNotification
? "Notifications Enabled"
: "Notifications Disabled"}
</span>
</span>
}
@@ -675,15 +736,17 @@ export default class Chat extends Component {
checked={allowAutoRejoin}
onChange={this.updateAllowAutoRejoin}
name="allowAutoRejoin"
color={allowAutoRejoin ? 'secondary' : 'primary'}
color={allowAutoRejoin ? "secondary" : "primary"}
/>
}
label={
<span>
Allow Watch Party to auto rejoin (within 1 minute)
<br />
<span style={{ color: '#8a8a8a' }}>
{allowAutoRejoin ? 'Auto Rejoin Enabled' : 'Auto Rejoin Disabled'}
<span style={{ color: "#8a8a8a" }}>
{allowAutoRejoin
? "Auto Rejoin Enabled"
: "Auto Rejoin Disabled"}
</span>
</span>
}
@@ -697,7 +760,7 @@ export default class Chat extends Component {
checked={adminOnly}
onChange={this.updateAdminOnly}
name="adminOnly"
color={adminOnly ? 'secondary' : 'primary'}
color={adminOnly ? "secondary" : "primary"}
disabled={adminModeUpdate}
/>
}
@@ -705,10 +768,10 @@ export default class Chat extends Component {
<span>
Admin Only Mode
<br />
<span style={{ color: '#8a8a8a' }}>
<span style={{ color: "#8a8a8a" }}>
{adminOnly
? 'Only admin can update player and start calls'
: 'All party members can update player and start calls'}
? "Only admin can update player and start calls"
: "All party members can update player and start calls"}
</span>
</span>
}
@@ -726,25 +789,38 @@ export default class Chat extends Component {
}
label={
<span>
Allow Watch Party to change to the currently playing
(BETA) Allow Watch Party to change to the currently playing
<br />
<span style={{ color: '#8a8a8a' }}>
{allowAutoFollow ? 'Auto Follow Enabled' : 'Auto Follow Disabled'}
<span style={{ color: "#8a8a8a" }}>
{allowAutoFollow
? "Auto Follow Enabled"
: "Auto Follow Disabled"}
</span>
</span>
}
labelPlacement="end"
/>
<Typography className="party-controls-users-title" variant="overline">
<Typography
className="party-controls-users-title"
variant="overline"
>
PARTY MEMBERS
</Typography>
<div className="party-controls-users-container">
{users.map((user) => (
<Chip className="party-controls-users-chip" clickable size="small" label={user} />
<Chip
className="party-controls-users-chip"
clickable
size="small"
label={user}
/>
))}
</div>
{onCall && (
<Typography className="party-controls-users-title" variant="overline">
<Typography
className="party-controls-users-title"
variant="overline"
>
DEVICE SELECT
</Typography>
)}
@@ -760,9 +836,13 @@ export default class Chat extends Component {
color="secondary"
variant="outlined"
onChange={(ev) => {
VoxeetSDK.mediaDevice.selectAudioInput(ev.target.value).then(() => {
this.setState({ selectedAudioInput: ev.target.value });
});
VoxeetSDK.mediaDevice
.selectAudioInput(ev.target.value)
.then(() => {
this.setState({
selectedAudioInput: ev.target.value,
});
});
}}
>
{audioInputs.map((v) => (
@@ -781,9 +861,13 @@ export default class Chat extends Component {
color="secondary"
variant="outlined"
onChange={(ev) => {
VoxeetSDK.mediaDevice.selectAudioOutput(ev.target.value).then(() => {
this.setState({ selectedAudioOutput: ev.target.value });
});
VoxeetSDK.mediaDevice
.selectAudioOutput(ev.target.value)
.then(() => {
this.setState({
selectedAudioOutput: ev.target.value,
});
});
}}
>
{audioOutputs.map((v) => (
@@ -803,9 +887,13 @@ export default class Chat extends Component {
fullWidth
variant="outlined"
onChange={(ev) => {
VoxeetSDK.mediaDevice.selectVideoInput(ev.target.value).then(() => {
this.setState({ selectedVideoInput: ev.target.value });
});
VoxeetSDK.mediaDevice
.selectVideoInput(ev.target.value)
.then(() => {
this.setState({
selectedVideoInput: ev.target.value,
});
});
}}
>
{videoInputs.map((v) => (
@@ -819,10 +907,11 @@ export default class Chat extends Component {
</ExpansionPanel>
{player ? (
<Card elevation={0} className="media-info-card">
{player.showName && player.status !== PLAYER_STATUS.NOT_PLAYING ? (
{player.showName &&
player.status !== PLAYER_STATUS.NOT_PLAYING ? (
<CardContent>
<Typography
style={{ display: 'block' }}
style={{ display: "block" }}
className="media-info-at updated-by"
variant="caption"
color="secondary"
@@ -848,16 +937,22 @@ export default class Chat extends Component {
</Typography>
</div>
</div>
<Typography
variant="overline"
style={{ fontSize: 9, display: 'block', marginTop: 12 }}
>
Watch Party will not automatically change the show for you.
</Typography>
{allowAutoFollow ? null : (
<Typography
variant="overline"
style={{ fontSize: 9, display: "block", marginTop: 12 }}
>
Watch Party will not automatically change the show for
you.
</Typography>
)}
</CardContent>
) : (
<CardContent>
<Typography style={{ fontSize: 12, marginBottom: 12 }} variant="h4">
<Typography
style={{ fontSize: 12, marginBottom: 12 }}
variant="h4"
>
Nothing playing right now
</Typography>
<Typography variant="overline" style={{ fontSize: 9 }}>
@@ -868,7 +963,11 @@ export default class Chat extends Component {
</CardContent>
)}
{player && player.showName && player.status ? (
<Button className="media-info-link" href={player.url} startIcon={<LinkOutlined />}>
<Button
className="media-info-link"
href={player.url}
startIcon={<LinkOutlined />}
>
Link to currently playing
</Button>
) : null}
@@ -900,7 +999,9 @@ export default class Chat extends Component {
<Paper
square
variant="outlined"
className={`replying-to-card ${replyTo !== null ? 'replying-to-card-up' : ''}`}
className={`replying-to-card ${
replyTo !== null ? "replying-to-card-up" : ""
}`}
>
<div className="replying-to-content">
<Typography variant="overline" display="block" gutterBottom>
@@ -914,8 +1015,15 @@ export default class Chat extends Component {
</Paper>
<div className="text-phone-panel">
{gif || newMessage ? null : (
<Tooltip title="Fullscreen with Watch Party" aria-label="Fullscreen">
<IconButton className="icon-button" color="secondary" onClick={this.toggleFullscreen}>
<Tooltip
title="Fullscreen with Watch Party"
aria-label="Fullscreen"
>
<IconButton
className="icon-button"
color="secondary"
onClick={this.toggleFullscreen}
>
{isFullscreen ? <FullscreenExit /> : <Fullscreen />}
</IconButton>
</Tooltip>
@@ -925,11 +1033,21 @@ export default class Chat extends Component {
) : (
<Tooltip
placement="top"
title={onCall ? (usingVideo ? 'Stop Video' : 'Start Video') : 'Join Video Call'}
title={
onCall
? usingVideo
? "Stop Video"
: "Start Video"
: "Join Video Call"
}
>
<IconButton
onClick={onCall ? () => this.handleVideo() : () => this.handlePhoneCall(true)}
color={usingVideo ? 'primary' : 'secondary'}
onClick={
onCall
? () => this.handleVideo()
: () => this.handlePhoneCall(true)
}
color={usingVideo ? "primary" : "secondary"}
>
{usingVideo ? <VideocamOffRounded /> : <VideocamRounded />}
</IconButton>
@@ -938,11 +1056,14 @@ export default class Chat extends Component {
{gif || newMessage || !callEnabled ? null : callActionPending ? (
<CircularProgress className="icon-button" color="secondary" />
) : (
<Tooltip placement="top" title={onCall ? 'Leave Call' : 'Join Call'}>
<Tooltip
placement="top"
title={onCall ? "Leave Call" : "Join Call"}
>
<IconButton
disabled={callActionPending}
onClick={() => this.handlePhoneCall(false)}
color={!onCall ? 'secondary' : 'primary'}
color={!onCall ? "secondary" : "primary"}
className="icon-button"
>
{onCall ? <PhoneDisable /> : <PhoneEnable />}
@@ -977,12 +1098,14 @@ export default class Chat extends Component {
multiline
rowsMax="3"
size="small"
placeholder={this.state.gif ? 'Search something...' : 'Say something...'}
placeholder={
this.state.gif ? "Search something..." : "Say something..."
}
helperText={
this.state.newMessage && !this.state.gif
? 'Enter to send / Shift+Enter for new line'
? "Enter to send / Shift+Enter for new line"
: this.state.gif
? 'Click on gif to send / Scroll to load more'
? "Click on gif to send / Scroll to load more"
: null
}
variant="outlined"
@@ -993,19 +1116,19 @@ export default class Chat extends Component {
scrollThread();
if (gif) {
window.postMessage({
watchPartyDirection: 'TO_SCRIPT',
type: 'WATCH_PARTY_SEARCH_GIF',
watchPartyDirection: "TO_SCRIPT",
type: "WATCH_PARTY_SEARCH_GIF",
value: e.target.value,
});
}
}}
InputProps={{
id: 'chat-message-box-input',
id: "chat-message-box-input",
endAdornment: (
<InputAdornment position="end">
<IconButton
className={`${this.state.gif ? 'gif-active' : ''} ${
this.state.newMessage ? 'message-active' : ''
className={`${this.state.gif ? "gif-active" : ""} ${
this.state.newMessage ? "message-active" : ""
} message-send`}
size="small"
onClick={() => this.sendMessageInvoker(newMessage)}
@@ -1018,13 +1141,15 @@ export default class Chat extends Component {
startAdornment: (
<InputAdornment position="start">
<IconButton
className={`gif-button ${this.state.gif ? 'gif-close' : ''}`}
className={`gif-button ${
this.state.gif ? "gif-close" : ""
}`}
onClick={() => {
this.setState({ gif: !gif });
if (!gif) {
window.postMessage({
watchPartyDirection: 'TO_SCRIPT',
type: 'WATCH_PARTY_SEARCH_GIF',
watchPartyDirection: "TO_SCRIPT",
type: "WATCH_PARTY_SEARCH_GIF",
value: newMessage,
});
scrollThread();
@@ -1042,9 +1167,9 @@ export default class Chat extends Component {
<ReactGiphySearchbox
apiKey="ojJbIMUN6XRMn4mHiFFav3rMCpXUg8sq"
onSelect={this.gifClick}
masonryConfig={[{ columns: 2, imageWidth: '50%', gutter: 5 }]}
masonryConfig={[{ columns: 2, imageWidth: "50%", gutter: 5 }]}
searchFormClassName="giphy-search-form"
wrapperClassName={`giphy-wrapper ${gif ? '' : 'giphy-wrapper-down'}`}
wrapperClassName={`giphy-wrapper ${gif ? "" : "giphy-wrapper-down"}`}
listWrapperClassName="giphy-list-wrapper"
listItemClassName="giphy-list-item"
poweredByGiphy
+159 -83
View File
@@ -10,7 +10,7 @@ CITED ARE THE SOLE INTELLECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE
COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
************************************************************************/
/*global chrome */
import React, { Component } from 'react';
import React, { Component } from "react";
import {
Button,
FormControlLabel,
@@ -27,7 +27,7 @@ import {
Card,
CardContent,
CardActions,
} from '@material-ui/core';
} from "@material-ui/core";
import {
JoinRoomApi,
CreateRoomApi,
@@ -38,9 +38,9 @@ import {
getUserUid,
emptyLocalData,
setTutorialStatus,
} from './Api';
import { goTo } from 'route-lite';
import Chat from './Chat';
} from "./Api";
import { goTo } from "route-lite";
import Chat from "./Chat";
import {
ChevronRight,
InfoRounded,
@@ -51,8 +51,8 @@ import {
KeyboardArrowLeft,
KeyboardArrowRight,
Notifications,
} from '@material-ui/icons';
import { Autocomplete } from '@material-ui/lab';
} from "@material-ui/icons";
import { Autocomplete } from "@material-ui/lab";
const CONSTANTS = {
USER_NAME_LENGTH: 12,
@@ -62,37 +62,52 @@ const CONSTANTS = {
export default class Create extends Component {
constructor(props) {
super(props);
const defaultMode = LocalData().partyName ? 'join' : 'create';
const defaultMode = LocalData().partyName ? "join" : "create";
this.state = {
userName: LocalData().userName || '',
name: LocalData().partyName || '',
pin: LocalData().partyPin || '',
userName: LocalData().userName || "",
name: LocalData().partyName || "",
pin: LocalData().partyPin || "",
mode: defaultMode,
parties: [],
adminOnly: false,
publicParty: false,
alertStep:
this.props.status && this.props.status.importantAlert
? this.props.status.importantAlert
: 0,
allowAutoRejoin:
LocalData().allowAutoRejoin !== undefined ? LocalData().allowAutoRejoin : true,
LocalData().allowAutoRejoin !== undefined
? LocalData().allowAutoRejoin
: true,
allowChatNotification:
LocalData().allowChatNotification !== undefined ? LocalData().allowChatNotification : true,
LocalData().allowChatNotification !== undefined
? LocalData().allowChatNotification
: true,
allowAutoFollow: LocalData().allowAutoFollow || false,
expanded: 'alerts',
expanded: "alerts",
};
this.createCall = this.createCall.bind(this);
this.joinCall = this.joinCall.bind(this);
this.success = this.success.bind(this);
this.partyNameAutocompleteProcessor = this.partyNameAutocompleteProcessor.bind(this);
this.partyNameAutocompleteProcessor = this.partyNameAutocompleteProcessor.bind(
this
);
this.updateAllowAutoRejoin = this.updateAllowAutoRejoin.bind(this);
this.updateAllowAutoFollow = this.updateAllowAutoFollow.bind(this);
this.updateAllowChatNotification = this.updateAllowChatNotification.bind(this);
this.updateAllowChatNotification = this.updateAllowChatNotification.bind(
this
);
this.clearPartyHistory = this.clearPartyHistory.bind(this);
this.handleSteps = this.handleSteps.bind(this);
}
componentDidMount() {
const { lastActive, userName, partyName, partyPin, allowAutoRejoin } = LocalData();
const {
lastActive,
userName,
partyName,
partyPin,
allowAutoRejoin,
} = LocalData();
// CONTINUE TUTORIAL
if (this.props.tutorialComplete === false) {
this.props.resetTutorial();
@@ -105,7 +120,9 @@ export default class Create extends Component {
partyName &&
partyPin
) {
if (Math.abs(new Date(parseInt(lastActive)) - new Date().getTime()) <= 60000) {
if (
Math.abs(new Date(parseInt(lastActive)) - new Date().getTime()) <= 60000
) {
this.props.updateLoading(true);
this.props.setVisible(true);
this.joinCall(userName, partyName, partyPin);
@@ -113,7 +130,7 @@ export default class Create extends Component {
}
chrome.runtime.sendMessage(
{
type: 'GET_PARTIES',
type: "GET_PARTIES",
},
(response) => {
this.setState({ parties: response });
@@ -127,33 +144,34 @@ export default class Create extends Component {
if (value.length <= CONSTANTS.PIN_LENGTH) this.setState({ pin: value });
}
userNameChange(value) {
if (value.length <= CONSTANTS.USER_NAME_LENGTH) this.setState({ userName: value });
if (value.length <= CONSTANTS.USER_NAME_LENGTH)
this.setState({ userName: value });
}
createOrJoin() {
this.props.updateLoading(true);
getUserUid();
const { userName, name, pin, mode } = this.state;
if (!userName.replace(/\s+/g, '')) {
this.props.notify('Missing user name');
if (!userName.replace(/\s+/g, "")) {
this.props.notify("Missing user name");
this.props.updateLoading(false);
return;
}
if (!name.replace(/\s+/g, '')) {
this.props.notify('Missing party name');
if (!name.replace(/\s+/g, "")) {
this.props.notify("Missing party name");
this.props.updateLoading(false);
return;
}
if (!pin.replace(/\s+/g, '')) {
this.props.notify('Missing party pin');
if (!pin.replace(/\s+/g, "")) {
this.props.notify("Missing party pin");
this.props.updateLoading(false);
return;
}
if (userName && name && pin) {
switch (mode) {
case 'create':
case "create":
this.createCall(userName.trim(), name.trim(), pin);
break;
case 'join':
case "join":
this.joinCall(userName.trim(), name.trim(), pin);
break;
default:
@@ -161,7 +179,7 @@ export default class Create extends Component {
break;
}
} else {
this.props.notify('Double check your inputs');
this.props.notify("Double check your inputs");
}
}
createCall(userName, partyName, partyPin) {
@@ -177,7 +195,8 @@ export default class Create extends Component {
time: 0,
url: window.location.href,
},
adminOnly: this.state.adminOnly,
adminOnly: this.state.adminOnly || this.state.publicParty,
publicParty: this.state.publicParty,
};
CreateRoomApi(apidata)
.then((res) => res.json())
@@ -190,8 +209,8 @@ export default class Create extends Component {
}
})
.catch((err) => {
console.error('Create Party API Error', err);
this.props.notify(err.message || 'Something went wrong');
console.error("Create Party API Error", err);
this.props.notify(err.message || "Something went wrong");
this.props.updateLoading(false);
});
}
@@ -215,8 +234,8 @@ export default class Create extends Component {
})
.catch((err) => {
emptyLocalData();
console.error('Join Party API Error', err);
this.props.notify(err.message || 'Something went wrong');
console.error("Join Party API Error", err);
this.props.notify(err.message || "Something went wrong");
this.props.updateLoading(false);
});
}
@@ -226,20 +245,22 @@ export default class Create extends Component {
goTo(Chat, this.props);
}
partyNameAutocompleteProcessor(v) {
if (v !== null && v !== undefined && typeof v === 'object') {
if (v !== null && v !== undefined && typeof v === "object") {
if (v.name) this.partyNameChange(v.name);
else this.partyNameChange('');
else this.partyNameChange("");
if (v.pin) this.partyPinChange(v.pin);
else this.partyPinChange('');
} else if (typeof v === 'object' && (v === null || v === undefined)) {
this.partyNameChange('');
this.partyPinChange('');
} else if (v !== undefined && v !== null && typeof v === 'string') {
else this.partyPinChange("");
} else if (typeof v === "object" && (v === null || v === undefined)) {
this.partyNameChange("");
this.partyPinChange("");
} else if (v !== undefined && v !== null && typeof v === "string") {
this.partyNameChange(v);
}
}
updateAllowChatNotification() {
updateLocalData({ allowChatNotification: !this.state.allowChatNotification });
updateLocalData({
allowChatNotification: !this.state.allowChatNotification,
});
this.setState({ allowChatNotification: !this.state.allowChatNotification });
}
updateAllowAutoRejoin() {
@@ -254,7 +275,7 @@ export default class Create extends Component {
this.setState({
parties: [],
});
chrome.runtime.sendMessage({ type: 'EMPTY_PARTIES' });
chrome.runtime.sendMessage({ type: "EMPTY_PARTIES" });
}
handleSteps(direction) {
const { alertStep } = this.state;
@@ -264,7 +285,7 @@ export default class Create extends Component {
}
handleExpanders(e) {
const { expanded } = this.state;
if (e === expanded) this.setState({ expanded: '' });
if (e === expanded) this.setState({ expanded: "" });
else this.setState({ expanded: e });
}
render() {
@@ -275,6 +296,7 @@ export default class Create extends Component {
userName,
parties,
adminOnly,
publicParty,
allowAutoRejoin,
allowAutoFollow,
allowChatNotification,
@@ -297,19 +319,19 @@ export default class Create extends Component {
<ButtonGroup className="create-mode-select" size="small" fullWidth>
<Button
id="mode-select-left"
variant={mode === 'create' ? 'contained' : null}
color={mode === 'create' ? 'secondary' : null}
disableElevation={mode === 'create'}
onClick={() => this.setState({ mode: 'create' })}
variant={mode === "create" ? "contained" : null}
color={mode === "create" ? "secondary" : null}
disableElevation={mode === "create"}
onClick={() => this.setState({ mode: "create" })}
>
Create
</Button>
<Button
id="mode-select-right"
variant={mode === 'join' ? 'contained' : null}
color={mode === 'join' ? 'secondary' : null}
disableElevation={mode === 'join'}
onClick={() => this.setState({ mode: 'join' })}
variant={mode === "join" ? "contained" : null}
color={mode === "join" ? "secondary" : null}
disableElevation={mode === "join"}
onClick={() => this.setState({ mode: "join" })}
>
Join
</Button>
@@ -323,7 +345,9 @@ export default class Create extends Component {
value={userName}
onChange={(e) => this.userNameChange(e.target.value)}
helperText={
userName ? `${userName.length}/${CONSTANTS.USER_NAME_LENGTH} Characters` : null
userName
? `${userName.length}/${CONSTANTS.USER_NAME_LENGTH} Characters`
: null
}
/>
<Autocomplete
@@ -333,7 +357,9 @@ export default class Create extends Component {
autoComplete
freeSolo
value={{ name: name, pin: pin }}
onInputChange={(e, v, r) => this.partyNameAutocompleteProcessor({ name: v, pin: pin })}
onInputChange={(e, v, r) =>
this.partyNameAutocompleteProcessor({ name: v, pin: pin })
}
onChange={(e, v) => this.partyNameAutocompleteProcessor(v)}
renderInput={(params) => (
<TextField
@@ -343,7 +369,11 @@ export default class Create extends Component {
className="create-name addFocus"
label="Party Name"
variant="outlined"
helperText={name ? `${name.length}/${CONSTANTS.NAME_LENGTH} Characters` : null}
helperText={
name
? `${name.length}/${CONSTANTS.NAME_LENGTH} Characters`
: null
}
/>
)}
/>
@@ -356,48 +386,76 @@ export default class Create extends Component {
type="number"
value={pin}
onChange={(e) => this.partyPinChange(e.target.value)}
helperText={pin ? `${pin.length}/${CONSTANTS.PIN_LENGTH} Digits` : null}
helperText={
pin ? `${pin.length}/${CONSTANTS.PIN_LENGTH} Digits` : null
}
/>
<FormControlLabel
className={`notification-switch admin-only-switch ${
mode !== 'create' ? 'admin-only-switch-hidden' : ''
mode !== "create" ? "admin-only-switch-hidden" : ""
}`}
control={
<Switch
checked={adminOnly}
checked={adminOnly || publicParty}
onChange={() => this.setState({ adminOnly: !adminOnly })}
name="adminOnly"
color={adminOnly ? 'secondary' : 'primary'}
color={adminOnly || publicParty ? "secondary" : "primary"}
/>
}
label={
<span>
Admin Only Mode (can be changed later)
<br />
<span style={{ color: '#8a8a8a' }}>
{adminOnly
? 'Only admin will update currently playing and start calls'
: 'All members will update currently playing and start calls'}
<span style={{ color: "#8a8a8a" }}>
{adminOnly || publicParty
? "Only admin will update currently playing and start calls"
: "All members will update currently playing and start calls"}
</span>
</span>
}
labelPlacement="end"
/>
{/* <FormControlLabel
className={`notification-switch admin-only-switch ${
mode !== "create" ? "admin-only-switch-hidden" : ""
}`}
control={
<Switch
checked={publicParty}
onChange={() => this.setState({ publicParty: !publicParty })}
name="publicParty"
color={publicParty ? "secondary" : "primary"}
/>
}
label={
<span>
Public Party (can be changed later)
<br />
<span style={{ color: "#8a8a8a" }}>
{publicParty
? "Party will be listed and available to join from Watch Party website"
: "Only people you share with can join"}
</span>
</span>
}
labelPlacement="end"
/> */}
<Button
size="small"
variant="contained"
color="secondary"
onClick={() => this.createOrJoin()}
>
<span>{mode === 'create' ? 'Start Party' : 'Join Party'}</span> <ChevronRight />
<span>{mode === "create" ? "Start Party" : "Join Party"}</span>{" "}
<ChevronRight />
</Button>
</Paper>
<ExpansionPanel
expanded={expanded === 'alerts'}
expanded={expanded === "alerts"}
className="create-settings-card create-alerts-card"
>
<ExpansionPanelSummary
onClick={() => this.handleExpanders('alerts')}
onClick={() => this.handleExpanders("alerts")}
expandIcon={<ExpandLess />}
>
<Notifications />
@@ -410,20 +468,29 @@ export default class Create extends Component {
<div className="alerts-stepper-container">
<Card className="alerts-stepper-card" elevation={10}>
<CardContent>
<Typography color="textSecondary" gutterBottom variant="overline">
<Typography
color="textSecondary"
gutterBottom
variant="overline"
>
{status.alerts[alertStep].title}
</Typography>
<Typography variant="body2" component="p">
{status.alerts[alertStep].description}
</Typography>
</CardContent>
{status.alerts[alertStep].link && status.alerts[alertStep].linkText && (
<CardActions>
<Button href={status.alerts[alertStep].link} target="_blank" size="small">
{status.alerts[alertStep].linkText}
</Button>
</CardActions>
)}
{status.alerts[alertStep].link &&
status.alerts[alertStep].linkText && (
<CardActions>
<Button
href={status.alerts[alertStep].link}
target="_blank"
size="small"
>
{status.alerts[alertStep].linkText}
</Button>
</CardActions>
)}
</Card>
<MobileStepper
className="alerts-stepper-controls"
@@ -431,7 +498,10 @@ export default class Create extends Component {
color="secondary"
activeStep={alertStep}
backButton={
<IconButton disabled={alertStep === 0} onClick={() => this.handleSteps(-1)}>
<IconButton
disabled={alertStep === 0}
onClick={() => this.handleSteps(-1)}
>
<KeyboardArrowLeft />
</IconButton>
}
@@ -454,11 +524,11 @@ export default class Create extends Component {
</ExpansionPanelDetails>
</ExpansionPanel>
<ExpansionPanel
expanded={expanded === 'settings'}
expanded={expanded === "settings"}
className="create-settings-card create-settings-expander"
>
<ExpansionPanelSummary
onClick={() => this.handleExpanders('settings')}
onClick={() => this.handleExpanders("settings")}
expandIcon={<ExpandLess />}
>
<Settings />
@@ -480,8 +550,10 @@ export default class Create extends Component {
<span>
Allow chat notification when side panel is closed
<br />
<span style={{ color: '#8a8a8a' }}>
{allowChatNotification ? 'Notifications Enabled' : 'Notifications Disabled'}
<span style={{ color: "#8a8a8a" }}>
{allowChatNotification
? "Notifications Enabled"
: "Notifications Disabled"}
</span>
</span>
}
@@ -500,8 +572,10 @@ export default class Create extends Component {
<span>
Allow Watch Party to auto rejoin (within 1 minute)
<br />
<span style={{ color: '#8a8a8a' }}>
{allowAutoRejoin ? 'Auto Rejoin Enabled' : 'Auto Rejoin Disabled'}
<span style={{ color: "#8a8a8a" }}>
{allowAutoRejoin
? "Auto Rejoin Enabled"
: "Auto Rejoin Disabled"}
</span>
</span>
}
@@ -520,8 +594,10 @@ export default class Create extends Component {
<span>
Allow Watch Party to change to the currently playing show
<br />
<span style={{ color: '#8a8a8a' }}>
{allowAutoFollow ? 'Auto Follow Enabled' : 'Auto Follow Disabled'}
<span style={{ color: "#8a8a8a" }}>
{allowAutoFollow
? "Auto Follow Enabled"
: "Auto Follow Disabled"}
</span>
</span>
}
+6 -4
View File
@@ -9,14 +9,16 @@ ALL CONTENT ON WATCH PARTY'S WEBSITE OR IN WATCH PARTY'S CHROME EXTENSION APP, U
CITED ARE THE SOLE INTELLECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE
COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
************************************************************************/
import React from 'react';
import { Typography } from '@material-ui/core';
import { Warning } from '@material-ui/icons';
import React from "react";
import { Typography } from "@material-ui/core";
import { Warning } from "@material-ui/icons";
const Inactive = (props) => (
<div id="party-loading" className="inactive">
<Warning />
<Typography variant="overline">SORRY, WATCH PARTY IS UNAVAILABLE RIGHT NOW</Typography>
<Typography variant="overline">
SORRY, WATCH PARTY IS UNAVAILABLE RIGHT NOW
</Typography>
<Typography variant="caption">{props.status}</Typography>
</div>
);
+2 -2
View File
@@ -9,8 +9,8 @@ ALL CONTENT ON WATCH PARTY'S WEBSITE OR IN WATCH PARTY'S CHROME EXTENSION APP, U
CITED ARE THE SOLE INTELLECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE
COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
************************************************************************/
import React from 'react';
import { CircularProgress } from '@material-ui/core';
import React from "react";
import { CircularProgress } from "@material-ui/core";
const Loading = () => (
<div id="party-loading">
+3 -3
View File
@@ -12,7 +12,7 @@ COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
.thread-wrapper * {
margin: 0;
padding: 0;
font-family: 'Roboto', sans-serif !important;
font-family: "Roboto", sans-serif !important;
letter-spacing: 1.15px;
word-break: break-word !important;
}
@@ -116,7 +116,7 @@ COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
line-height: 16px;
font-size: 13px;
font-weight: 100;
font-family: 'Roboto';
font-family: "Roboto";
letter-spacing: 1.5px;
white-space: break-spaces;
word-break: break-all;
@@ -273,7 +273,7 @@ COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
white-space: break-spaces;
}
.thread-interactive-question::before {
content: '[MESSAGE FROM ADMIN]';
content: "[MESSAGE FROM ADMIN]";
display: block;
margin-bottom: 10px;
}
+70 -30
View File
@@ -9,7 +9,7 @@ ALL CONTENT ON WATCH PARTY'S WEBSITE OR IN WATCH PARTY'S CHROME EXTENSION APP, U
CITED ARE THE SOLE INTELLECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE
COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
************************************************************************/
import React, { Component, createRef } from 'react';
import React, { Component, createRef } from "react";
import {
Typography,
IconButton,
@@ -17,11 +17,16 @@ import {
TextField,
InputAdornment,
Button,
} from '@material-ui/core';
import { Reply, Send } from '@material-ui/icons';
import './Thread.css';
import { LocalData, webhookFetcher } from './Api';
import { CellMeasurer, CellMeasurerCache, AutoSizer, List } from 'react-virtualized';
} from "@material-ui/core";
import { Reply, Send } from "@material-ui/icons";
import "./Thread.css";
import { LocalData, webhookFetcher } from "./Api";
import {
CellMeasurer,
CellMeasurerCache,
AutoSizer,
List,
} from "react-virtualized";
var cache = new CellMeasurerCache({
fixedWidth: true,
@@ -44,23 +49,25 @@ export default class Thread extends Component {
setTimeout(() => {
const id = messages[msgIdx].id || `sending-${msgIdx}`;
const msg = document.getElementById(id);
msg.classList.add('highlight');
setTimeout(() => msg.classList.remove('highlight'), 2000);
msg.classList.add("highlight");
setTimeout(() => msg.classList.remove("highlight"), 2000);
}, 500);
}
handleInteractiveMessageCall(msg) {
const thanksElement = document.createElement('div');
thanksElement.innerText = 'THANK YOU FOR THE FEEDBACK';
thanksElement.className = 'thread-interactive-thankyou';
if (msg.uid === '<system>') {
const thanksElement = document.createElement("div");
thanksElement.innerText = "THANK YOU FOR THE FEEDBACK";
thanksElement.className = "thread-interactive-thankyou";
if (msg.uid === "<system>") {
if (msg.endpoint) {
var bodyData = {
question: msg.text,
...LocalData(),
};
if (msg.type === 'interactive/text') {
if (msg.type === "interactive/text") {
const answerElement = document.getElementById(`reply-${msg.id}`);
bodyData.answer = answerElement ? answerElement.value : 'ANSWER_ELEM_NOT_FOUND';
bodyData.answer = answerElement
? answerElement.value
: "ANSWER_ELEM_NOT_FOUND";
answerElement.disabled = true;
answerElement.parentElement.parentElement.parentElement.firstElementChild.remove();
answerElement.parentElement.replaceWith(thanksElement);
@@ -73,19 +80,28 @@ export default class Thread extends Component {
}
}
getItemClassNames(uid, userUid, msgIdx, messages, isSending = false) {
const lastUid = msgIdx >= 1 ? messages[msgIdx - 1].uid : '';
return `thread-item ${uid === userUid ? 'my-message ' : ''}${
isSending ? 'sending-message ' : ''
}${uid === '<system>' ? 'system-message ' : ''}${lastUid === uid ? 'continued-message' : ''}`;
const lastUid = msgIdx >= 1 ? messages[msgIdx - 1].uid : "";
return `thread-item ${uid === userUid ? "my-message " : ""}${
isSending ? "sending-message " : ""
}${uid === "<system>" ? "system-message " : ""}${
lastUid === uid ? "continued-message" : ""
}`;
}
getMessageTextOrImage(msg, measure) {
if (msg.type === 'giphy') {
if (msg.type === "giphy") {
return <img onLoad={measure} alt="gif" src={msg.text} />;
}
if (msg.type === 'interactive/text') {
if (msg.type === "interactive/text") {
return (
<Paper onLoad={measure} elevation={0} className="thread-interactive-text">
<Typography className="thread-interactive-question" variant="overline">
<Paper
onLoad={measure}
elevation={0}
className="thread-interactive-text"
>
<Typography
className="thread-interactive-question"
variant="overline"
>
{msg.text}
</Typography>
<TextField
@@ -98,7 +114,9 @@ export default class Thread extends Component {
InputProps={{
endAdornment: (
<InputAdornment position="end">
<IconButton onClick={() => this.handleInteractiveMessageCall(msg)}>
<IconButton
onClick={() => this.handleInteractiveMessageCall(msg)}
>
<Send />
</IconButton>
</InputAdornment>
@@ -109,10 +127,17 @@ export default class Thread extends Component {
</Paper>
);
}
if (msg.type === 'interactive/link') {
if (msg.type === "interactive/link") {
return (
<Paper onLoad={measure} elevation={0} className="thread-interactive-text">
<Typography className="thread-interactive-question" variant="overline">
<Paper
onLoad={measure}
elevation={0}
className="thread-interactive-text"
>
<Typography
className="thread-interactive-question"
variant="overline"
>
{msg.text}
</Typography>
<Button
@@ -138,7 +163,10 @@ export default class Thread extends Component {
if (replyMessage) {
const msgIdx = messages.indexOf(replyMessage);
return (
<div className="thread-reply" onClick={() => this.scrollToMessage(msgIdx, messages)}>
<div
className="thread-reply"
onClick={() => this.scrollToMessage(msgIdx, messages)}
>
<p className="thread-reply-name">Reply to {replyMessage.name}:</p>
{this.getMessageTextOrImage(replyMessage)}
</div>
@@ -169,7 +197,13 @@ export default class Thread extends Component {
style={params.style}
id={msg.id || `sending-${msgIdx}`}
key={`msg-${msgIdx}-item`}
className={this.getItemClassNames(msg.uid, userUid, msgIdx, messages, !!!msg.id)}
className={this.getItemClassNames(
msg.uid,
userUid,
msgIdx,
messages,
!!!msg.id
)}
>
<div className="thread-name">{msg.name}</div>
{this.getReplyMessage(msg.replyTo, messages)}
@@ -194,7 +228,7 @@ export default class Thread extends Component {
const { autoSizeWidth } = this.state;
const { sentMessages, isSending, sendingMessages, setReplyTo } = this.props;
return !isSending ? (
<AutoSizer style={{ flex: '1 auto', minWidth: '100%' }}>
<AutoSizer style={{ flex: "1 auto", minWidth: "100%" }}>
{({ height, width }) => {
if (autoSizeWidth !== width) {
cache.clearAll();
@@ -222,7 +256,13 @@ export default class Thread extends Component {
<div
id={msg.id || `sending-${msgIdx}`}
key={`sending-msg-${msgIdx}-item`}
className={this.getItemClassNames(msg.uid, userUid, msgIdx, sendingMessages, true)}
className={this.getItemClassNames(
msg.uid,
userUid,
msgIdx,
sendingMessages,
true
)}
>
<div className="thread-name">{msg.name}</div>
{this.getReplyMessage(msg.replyTo, sentMessages)}
+47 -44
View File
@@ -1,6 +1,6 @@
import React, { Component } from 'react';
import { Popover, MobileStepper, Button, Typography } from '@material-ui/core';
import { setTutorialStatus } from './Api';
import React, { Component } from "react";
import { Popover, MobileStepper, Button, Typography } from "@material-ui/core";
import { setTutorialStatus } from "./Api";
export default class Tutorial extends Component {
constructor(props) {
@@ -24,12 +24,12 @@ export default class Tutorial extends Component {
<div className="tutorial-content">
<Typography variant="subtitle1">Take A Tour</Typography>
<Typography variant="body2">
Welcome to Watch Party! Take a quick tour to see how it works. Start by clicking on
the (WP) button to the right...
Welcome to Watch Party! Take a quick tour to see how it works.
Start by clicking on the (WP) button to the right...
</Typography>
</div>
),
e: '.watch-party-fab',
e: ".watch-party-fab",
dn: () => this.props.visible !== true,
},
{
@@ -41,57 +41,57 @@ export default class Tutorial extends Component {
</Typography>
</div>
),
e: '.create-input-card',
e: ".create-input-card",
},
{
c: (
<div className="tutorial-content">
<Typography variant="subtitle1">Resize</Typography>
<Typography variant="body2">
Use this little tab <span id="resize-demo">👉</span> to resize the sidebar, double
click on it to resize to the default width
Use this little tab <span id="resize-demo">👉</span> to resize the
sidebar, double click on it to resize to the default width
</Typography>
</div>
),
e: '#party-width-dragger',
e: "#party-width-dragger",
},
{
c: (
<div className="tutorial-content">
<Typography variant="subtitle1">Notifications</Typography>
<Typography variant="body2">
Keep an eye on this section for any important notifications, use the left and right
buttons to see more notifications
Keep an eye on this section for any important notifications, use
the left and right buttons to see more notifications
</Typography>
</div>
),
e: '.create-alerts-card',
e: ".create-alerts-card",
},
{
c: (
<div className="tutorial-content">
<Typography variant="subtitle1">Settings</Typography>
<Typography variant="body2">
Click on 'Settings' to see your available options. You can start the tour again from
here if needed.
Click on 'Settings' to see your available options. You can start
the tour again from here if needed.
</Typography>
</div>
),
e: '.create-settings-expander',
e: ".create-settings-expander",
},
{
c: (
<div className="tutorial-content">
<Typography variant="subtitle1">Create A Party</Typography>
<Typography variant="body2">
Alright, now fill out the fields here, and create a party. We'll continue the tour
after you're in a party.
Alright, now fill out the fields here, and create a party. We'll
continue the tour after you're in a party.
<br />
Click on next to be able to type.
</Typography>
</div>
),
e: '.create-input-card',
e: ".create-input-card",
on: () => this.setState({ open: false }),
},
{
@@ -99,64 +99,67 @@ export default class Tutorial extends Component {
<div className="tutorial-content">
<Typography variant="subtitle1">Title Card</Typography>
<Typography variant="body2">
This top area is the 'Title Card', click on or near the down arrow to see your
settings, and other details. If you're on a call you can control the volume from here.
This top area is the 'Title Card', click on or near the down arrow
to see your settings, and other details. If you're on a call you
can control the volume from here.
</Typography>
</div>
),
db: () => true,
e: '.party-chat-header',
e: ".party-chat-header",
},
{
c: (
<div className="tutorial-content">
<Typography variant="subtitle1">Now Playing</Typography>
<Typography variant="body2">
Start playing something and you will see this area update to show what's currently
playing.
Start playing something and you will see this area update to show
what's currently playing.
</Typography>
</div>
),
e: '.media-info-card',
e: ".media-info-card",
},
{
c: (
<div className="tutorial-content">
<Typography variant="subtitle1">Chat &amp; Call</Typography>
<Typography variant="body2">
You can send messages, start/join a call, or go fullscreen from here. You can send a
gif, by click on the GIF button.
You can send messages, start/join a call, or go fullscreen from
here. You can send a gif, by click on the GIF button.
<br />
Use this fullscreen button to have access to Watch Party when in fullscreen.
Use this fullscreen button to have access to Watch Party when in
fullscreen.
</Typography>
</div>
),
e: '.text-phone-panel',
e: ".text-phone-panel",
},
{
c: (
<div className="tutorial-content">
<Typography variant="subtitle1">Hide Sidebar</Typography>
<Typography variant="body2">
You can hide the sidebar by click on the (WP) button again, sync will continue to work
even when hidden.
You can hide the sidebar by click on the (WP) button again, sync
will continue to work even when hidden.
</Typography>
</div>
),
e: '.watch-party-fab',
e: ".watch-party-fab",
},
{
c: (
<div className="tutorial-content">
<Typography variant="subtitle1">Hide Watch Party</Typography>
<Typography variant="body2">
Look for the Watch Party icon in your extensions bar, you can hide the (WP) button
from your screen when you don't want it in your way.
Look for the Watch Party icon in your extensions bar, you can hide
the (WP) button from your screen when you don't want it in your
way.
</Typography>
</div>
),
e:
'div.party-chat-header div.MuiButtonBase-root.MuiIconButton-root.MuiExpansionPanelSummary-expandIcon.MuiIconButton-edgeEnd',
"div.party-chat-header div.MuiButtonBase-root.MuiIconButton-root.MuiExpansionPanelSummary-expandIcon.MuiIconButton-edgeEnd",
},
{
c: (
@@ -167,7 +170,7 @@ export default class Tutorial extends Component {
</Typography>
</div>
),
e: '#party-width-dragger',
e: "#party-width-dragger",
},
];
}
@@ -203,7 +206,7 @@ export default class Tutorial extends Component {
this.setState({
open: !nextProps.tutorialComplete && nextProps.showFab,
});
if (nextProps.tutorialComponent === 'chat') {
if (nextProps.tutorialComponent === "chat") {
this.setState({
index: 6,
});
@@ -227,12 +230,12 @@ export default class Tutorial extends Component {
anchorEl={el}
open={open}
anchorOrigin={{
vertical: 'center',
horizontal: 'left',
vertical: "center",
horizontal: "left",
}}
transformOrigin={{
vertical: 'center',
horizontal: 'right',
vertical: "center",
horizontal: "right",
}}
>
{this.steps[index].c}
@@ -243,7 +246,7 @@ export default class Tutorial extends Component {
activeStep={index}
variant="progress"
LinearProgressProps={{
color: 'secondary',
color: "secondary",
}}
backButton={
<Button
@@ -253,7 +256,7 @@ export default class Tutorial extends Component {
color="secondary"
disabled={this.steps[index].db && this.steps[index].db()}
>
{index === 0 ? 'Skip' : 'Back'}
{index === 0 ? "Skip" : "Back"}
</Button>
}
nextButton={
@@ -264,7 +267,7 @@ export default class Tutorial extends Component {
color="secondary"
disabled={this.steps[index].dn && this.steps[index].dn()}
>
{index === this.steps.length - 1 ? 'Done' : 'Next'}
{index === this.steps.length - 1 ? "Done" : "Next"}
</Button>
}
/>
+261 -420
View File
@@ -9,17 +9,22 @@ ALL CONTENT ON WATCH PARTY'S WEBSITE OR IN WATCH PARTY'S CHROME EXTENSION APP, U
CITED ARE THE SOLE INTELLECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE
COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
************************************************************************/
import { PLAYER_STATUS, getPlayerSource, PLAYER_SOURCE, LocalData } from './Api';
import {
PLAYER_STATUS,
getPlayerSource,
PLAYER_SOURCE,
LocalData,
} from "./Api";
const templateListener = (video) => console.log('MISSING VIDEO LISTENER');
const templateListener = (video) => console.log("MISSING VIDEO LISTENER");
export default class VideoListener {
constructor(listener = templateListener, selectors, nameSelectors) {
this.video = {
status: PLAYER_STATUS.NOT_PLAYING,
time: 0,
showName: '',
source: '',
showName: "",
source: "",
element: null,
};
this.nameSelectors = nameSelectors;
@@ -44,7 +49,7 @@ export default class VideoListener {
this.video.element !== null &&
this.video.element !== undefined &&
this.video.status !== PLAYER_STATUS.NOT_PLAYING &&
this.video.showName !== '' &&
this.video.showName !== "" &&
this.video.showName !== null &&
(this.video.status !== this.server.status ||
Math.abs(this.video.element.currentTime - this.server.time) > 1.5)
@@ -81,11 +86,11 @@ export default class VideoListener {
switch (this.video.source) {
case PLAYER_SOURCE.CRUNCHYROLL:
case PLAYER_SOURCE.FUNIMATION:
window.removeEventListener('watchParty', this.crunchyRollListener);
window.removeEventListener("watchParty", this.crunchyRollListener);
break;
default:
this.video.element.removeEventListener('playing', this.onplay);
this.video.element.removeEventListener('pause', this.onpause);
this.video.element.removeEventListener("playing", this.onplay);
this.video.element.removeEventListener("pause", this.onpause);
break;
}
await this.timeout(250);
@@ -97,159 +102,117 @@ export default class VideoListener {
) {
switch (serverPlayer.source) {
case PLAYER_SOURCE.NETFLIX:
window.postMessage({ type: 'SEEK', time: serverPlayer.time * 1000 }, '*');
window.postMessage(
{ type: "SEEK", time: serverPlayer.time * 1000 },
"*"
);
break;
case PLAYER_SOURCE.HULU:
window.postMessage(
{ type: "SEEK", time: serverPlayer.time },
"*"
);
break;
case PLAYER_SOURCE.AMAZON:
if (this.video.status === PLAYER_STATUS.PAUSED)
await this.video.element
.play()
.catch((err) => console.error('WatchParty erred when syncing time.'));
.catch((err) =>
console.error("WatchParty erred when syncing time.")
);
await this.timeout(250);
this.video.element.currentTime = serverPlayer.time;
await this.timeout(500);
break;
case PLAYER_SOURCE.DISNEY:
case PLAYER_SOURCE.YOUTUBE:
case PLAYER_SOURCE.HBOMAX:
case PLAYER_SOURCE.HBONOW:
case PLAYER_SOURCE.GOOGLEPLAY:
case PLAYER_SOURCE.STAN:
case PLAYER_SOURCE.HOTSTAR:
case PLAYER_SOURCE.VIKI:
case PLAYER_SOURCE.APPLE:
case PLAYER_SOURCE.AIRTEL:
case PLAYER_SOURCE.VIMEO:
case PLAYER_SOURCE.DAILYMOTION:
this.video.element.currentTime = serverPlayer.time;
await this.timeout(500);
break;
case PLAYER_SOURCE.YOUTUBE:
this.video.element.currentTime = serverPlayer.time;
break;
case PLAYER_SOURCE.HULU:
window.postMessage({ type: 'SEEK', time: serverPlayer.time }, '*');
break;
case PLAYER_SOURCE.HBOMAX:
case PLAYER_SOURCE.HBONOW:
this.video.element.currentTime = serverPlayer.time;
break;
case PLAYER_SOURCE.PEACOCK:
window.postMessage(
JSON.stringify({
watchPartyDirection: 'TO_SCRIPT',
type: 'WATCH_PARTY_SEEK',
status: serverPlayer.status,
time: serverPlayer.time,
})
);
break;
case PLAYER_SOURCE.GOOGLEPLAY:
this.video.element.currentTime = serverPlayer.time;
break;
case PLAYER_SOURCE.CRUNCHYROLL:
window.postMessage(
JSON.stringify({
watchPartyDirection: 'TO_SCRIPT',
type: 'WATCH_PARTY_SEEK',
status: serverPlayer.status,
time: serverPlayer.time,
})
);
break;
case PLAYER_SOURCE.FUNIMATION:
window.postMessage(
JSON.stringify({
watchPartyDirection: 'TO_SCRIPT',
type: 'WATCH_PARTY_SEEK',
status: serverPlayer.status,
time: serverPlayer.time,
})
);
break;
case PLAYER_SOURCE.APPLE:
this.video.element.currentTime = serverPlayer.time;
break;
case PLAYER_SOURCE.VIKI:
this.video.element.currentTime = serverPlayer.time;
break;
case PLAYER_SOURCE.ROOSTERTEETH:
window.postMessage(
JSON.stringify({
watchPartyDirection: 'TO_SCRIPT',
type: 'WATCH_PARTY_SEEK',
watchPartyDirection: "TO_SCRIPT",
type: "WATCH_PARTY_SEEK",
status: serverPlayer.status,
time: serverPlayer.time,
})
);
break;
case PLAYER_SOURCE.STAN:
this.video.element.currentTime = serverPlayer.time;
break;
case PLAYER_SOURCE.HOTSTAR:
this.video.element.currentTime = serverPlayer.time;
break;
default:
break;
}
}
// TOGGLE PLAYER STATUS
switch (serverPlayer.status) {
case PLAYER_STATUS.PAUSED:
if (
PLAYER_SOURCE.HULU === this.video.source ||
PLAYER_SOURCE.NETFLIX === this.video.source ||
PLAYER_SOURCE.HBOMAX === this.video.source ||
PLAYER_SOURCE.HBONOW === this.video.source
) {
window.postMessage({ type: 'PAUSE', time: serverPlayer.time }, '*');
} else if (
PLAYER_SOURCE.CRUNCHYROLL === this.video.source ||
PLAYER_SOURCE.PEACOCK === this.video.source ||
PLAYER_SOURCE.FUNIMATION === this.video.source ||
PLAYER_SOURCE.ROOSTERTEETH === this.video.source
) {
window.postMessage(
JSON.stringify({
watchPartyDirection: 'TO_SCRIPT',
type: 'WATCH_PARTY_STATUS',
status: serverPlayer.status,
time: serverPlayer.time,
})
if (
PLAYER_SOURCE.CRUNCHYROLL === this.video.source ||
PLAYER_SOURCE.PEACOCK === this.video.source ||
PLAYER_SOURCE.FUNIMATION === this.video.source ||
PLAYER_SOURCE.ROOSTERTEETH === this.video.source
) {
window.postMessage(
JSON.stringify({
watchPartyDirection: "TO_SCRIPT",
type: "WATCH_PARTY_STATUS",
status: serverPlayer.status,
time: serverPlayer.time,
})
);
} else if (
PLAYER_SOURCE.HULU === this.video.source ||
PLAYER_SOURCE.NETFLIX === this.video.source ||
PLAYER_SOURCE.HBOMAX === this.video.source ||
PLAYER_SOURCE.HBONOW === this.video.source
) {
if (
serverPlayer.status === PLAYER_STATUS.PAUSED ||
serverPlayer.status === PLAYER_STATUS.PLAYING
) {
const PAUSE_OR_PLAY =
serverPlayer.status === PLAYER_STATUS.PAUSED
? "PAUSE"
: serverPlayer.status === PLAYER_STATUS.PLAYING
? "PLAY"
: "";
window.postMessage(
{ type: PAUSE_OR_PLAY, time: serverPlayer.time },
"*"
);
}
} else {
if (serverPlayer.status === PLAYER_STATUS.PLAYING) {
await this.video.element
.play()
.catch((err) =>
console.error("WatchParty erred when syncing play.")
);
} else {
await this.video.element.pause();
}
break;
case PLAYER_STATUS.PLAYING:
if (
PLAYER_SOURCE.HULU === this.video.source ||
PLAYER_SOURCE.NETFLIX === this.video.source ||
PLAYER_SOURCE.HBOMAX === this.video.source ||
PLAYER_SOURCE.HBONOW === this.video.source
) {
window.postMessage({ type: 'PLAY', time: serverPlayer.time }, '*');
} else if (
PLAYER_SOURCE.CRUNCHYROLL === this.video.source ||
PLAYER_SOURCE.PEACOCK === this.video.source ||
PLAYER_SOURCE.FUNIMATION === this.video.source ||
PLAYER_SOURCE.ROOSTERTEETH === this.video.source
) {
window.postMessage(
JSON.stringify({
watchPartyDirection: 'TO_SCRIPT',
type: 'WATCH_PARTY_STATUS',
status: serverPlayer.status,
time: serverPlayer.time,
})
);
} else {
await this.video.element
.play()
.catch((err) => console.error('WatchParty erred when syncing play.'));
}
break;
default:
break;
} else if (serverPlayer.status === PLAYER_STATUS.PAUSED) {
await this.video.element.pause();
}
}
await this.timeout(500);
// RE-ADD LISTENERS FOR FUTURE SYNC
switch (this.video.source) {
case PLAYER_SOURCE.CRUNCHYROLL:
case PLAYER_SOURCE.FUNIMATION:
window.addEventListener('watchParty', this.crunchyRollListener);
window.addEventListener("watchParty", this.crunchyRollListener);
break;
default:
this.video.element.addEventListener('playing', this.onplay);
this.video.element.addEventListener('pause', this.onpause);
this.video.element.addEventListener("playing", this.onplay);
this.video.element.addEventListener("pause", this.onpause);
break;
}
}
@@ -266,117 +229,92 @@ export default class VideoListener {
const nS = this.nameSelectors[this.video.source];
switch (this.video.source) {
case PLAYER_SOURCE.NETFLIX:
var nshow = document.querySelector(nS.show).innerHTML || '';
var nepisode = '';
var nshow = document.querySelector(nS.show).innerHTML || "";
var nepisode = "";
if (document.querySelectorAll(nS.episode)) {
document.querySelectorAll(nS.episode).forEach((el) => (nepisode += el.innerHTML + ' '));
document
.querySelectorAll(nS.episode)
.forEach((el) => (nepisode += el.innerHTML + " "));
}
return nshow === '' && nepisode === '' ? null : nshow + '\n' + nepisode;
case PLAYER_SOURCE.AMAZON:
const ashow = document.querySelector(nS.show).innerText || '';
return ashow === '' ? null : ashow;
case PLAYER_SOURCE.HULU:
const hshowContainer = document.querySelector(nS.show);
const hepisodeContainer = document.querySelector(nS.episode);
const hshow = hshowContainer ? hshowContainer.innerText : '';
const hepisode = hepisodeContainer ? hepisodeContainer.innerText.replace(/\n/gi, ' ') : '';
return hshow === '' && hepisode === '' ? null : hshow + '\n' + hepisode;
return nshow === "" && nepisode === "" ? null : nshow + "\n" + nepisode;
case PLAYER_SOURCE.DISNEY:
this.video.element.parentElement.click();
await this.timeout(200);
const dshow = document.querySelector(nS.show)
? document.querySelector(nS.show).innerHTML
: '';
: "";
const depisode = document.querySelector(nS.episode)
? document.querySelector(nS.episode).innerHTML
: '';
return dshow === '' && depisode === '' ? null : dshow + '\n' + depisode;
case PLAYER_SOURCE.YOUTUBE:
const yshow = document.querySelector(nS.show).innerText || '';
const yepisode = document.querySelector(nS.episode).innerText || '';
return yshow === '' && yepisode === '' ? null : yshow + '\n' + yepisode;
case PLAYER_SOURCE.HBOMAX:
case PLAYER_SOURCE.HBONOW:
const bottomHalf = this.video.element.parentNode.parentNode.parentNode.parentNode.parentNode
.children[1];
bottomHalf.children[0].id = 'hboUpperTitle';
bottomHalf.children[1].id = 'hboLowerTitle';
const hboshow = document.querySelector('#hboUpperTitle').innerText;
const hboepisode = document.querySelector('#hboLowerTitle').innerText;
return hboshow === '' && hboepisode === '' ? null : hboshow + '\n' + hboepisode;
case PLAYER_SOURCE.PEACOCK:
const peacockshow = document.querySelector(nS.show).innerText || '';
const peacockepisode = document.querySelector(nS.episode).innerText || '';
return peacockshow === '' && peacockepisode === ''
? null
: peacockshow + '\n' + peacockepisode;
: "";
return dshow === "" && depisode === "" ? null : dshow + "\n" + depisode;
case PLAYER_SOURCE.GOOGLEPLAY:
const playerIframe = document.querySelector(this.selectors[PLAYER_SOURCE.GOOGLEPLAY]);
var googleplayshow = '';
const playerIframe = document.querySelector(
this.selectors[PLAYER_SOURCE.GOOGLEPLAY]
);
var googleplayshow = "";
if (playerIframe) {
googleplayshow =
playerIframe.contentWindow.document.querySelector(nS.show).innerText || '';
const gpsel = playerIframe.contentWindow.document.querySelector(
nS.show
);
googleplayshow = gpsel ? gpsel.innerText : "";
}
return googleplayshow === '' ? null : googleplayshow;
case PLAYER_SOURCE.CRUNCHYROLL:
const crunchyrollTitle = document.querySelector(nS.show);
const crunchyrollshow = crunchyrollTitle ? crunchyrollTitle.innerText : '';
return crunchyrollshow === '' ? null : crunchyrollshow;
return googleplayshow === "" ? null : googleplayshow;
case PLAYER_SOURCE.APPLE:
const appleTvPlayer = document.querySelector('apple-tv-plus-player');
const appleTvInternal = appleTvPlayer.shadowRoot.querySelector('amp-video-player-internal');
const appleTvVideoContainer = appleTvInternal.shadowRoot.querySelector('amp-video-player');
const appleTvShowContainer = appleTvVideoContainer.querySelector(nS.show);
const appleTvEpisodeContainer = appleTvVideoContainer.querySelector(nS.episode);
const appleTvShow = appleTvShowContainer ? appleTvShowContainer.innerText : '';
const appleTvEpisode = appleTvEpisodeContainer ? appleTvEpisodeContainer.innerText : '';
return appleTvShow === '' && appleTvEpisode === ''
const appleTvPlayer = document.querySelector("apple-tv-plus-player");
const appleTvInternal = appleTvPlayer.shadowRoot.querySelector(
"amp-video-player-internal"
);
const appleTvVideoContainer = appleTvInternal.shadowRoot.querySelector(
"amp-video-player"
);
const appleTvShowContainer = appleTvVideoContainer.querySelector(
nS.show
);
const appleTvEpisodeContainer = appleTvVideoContainer.querySelector(
nS.episode
);
const appleTvShow = appleTvShowContainer
? appleTvShowContainer.innerText
: "";
const appleTvEpisode = appleTvEpisodeContainer
? appleTvEpisodeContainer.innerText
: "";
return appleTvShow === "" && appleTvEpisode === ""
? null
: appleTvShow + '\n' + appleTvEpisode;
: appleTvShow + "\n" + appleTvEpisode;
case PLAYER_SOURCE.VIKI:
const docTitleSplit = document.title.split('|');
const docTitleSplit = document.title.split("|");
if (docTitleSplit.length > 1) return docTitleSplit[0].trim();
else return null;
case PLAYER_SOURCE.FUNIMATION:
const funimationShowContainer = document.querySelector(nS.show);
const funimationEpisodeContainer = document.querySelector(nS.episode);
const funimationShow = funimationShowContainer ? funimationShowContainer.innerText : '';
const funimationEpisode = funimationEpisodeContainer
? funimationEpisodeContainer.innerText.replace(/\n/gi, '')
: '';
return funimationShow === '' && funimationEpisode === ''
? null
: funimationShow + '\n' + funimationEpisode;
case PLAYER_SOURCE.ROOSTERTEETH:
const roosterTeethShowContainer = document.querySelector(nS.show);
const roosterTeethEpisodeContainer = document.querySelector(nS.episode);
const roosterTeethShow = roosterTeethShowContainer
? roosterTeethShowContainer.innerText
: '';
const roosterTeethEpisode = roosterTeethEpisodeContainer
? roosterTeethEpisodeContainer.innerText
: '';
return roosterTeethShow === '' && roosterTeethEpisode === ''
? null
: roosterTeethShow + '\n' + roosterTeethEpisode;
case PLAYER_SOURCE.STAN:
const stanShowContainer = document.querySelector(nS.show);
const stanEpisodeContainer = document.querySelector(nS.episode);
const stanShow = stanShowContainer ? stanShowContainer.innerHTML : '';
const stanEpisode = stanEpisodeContainer ? stanEpisodeContainer.innerHTML : '';
return stanShow === '' && stanEpisode === '' ? null : stanShow + '\n' + stanEpisode;
case PLAYER_SOURCE.HOTSTAR:
const hotstarShowContainer = document.querySelector(nS.show);
const hotstarEpisodeContainer = document.querySelector(nS.episode);
const hotstarShow = hotstarShowContainer ? hotstarShowContainer.innerText : '';
const hotstarEpisode = hotstarEpisodeContainer ? hotstarEpisodeContainer.innerText : '';
return hotstarShow === '' && hotstarEpisode === ''
const stanShow = stanShowContainer ? stanShowContainer.innerHTML : "";
const stanEpisode = stanEpisodeContainer
? stanEpisodeContainer.innerHTML
: "";
return stanShow === "" && stanEpisode === ""
? null
: hotstarShow + '\n' + hotstarEpisode;
: stanShow + "\n" + stanEpisode;
default:
break;
if (nS) {
const showElement = nS.show ? document.querySelector(nS.show) : null;
const episodeElement = nS.episode
? document.querySelector(nS.episode)
: null;
if (showElement !== null || episodeElement !== null) {
const showText = showElement
? showElement.innerText.replace(/\n/gi, " ")
: "";
const episodeText = episodeElement
? episodeElement.innerText.replace(/\n/gi, " ")
: "";
if (showText !== "" || episodeText !== "") {
return showText + "\n" + episodeText;
}
}
}
return null;
}
}
async onplay(ev) {
@@ -395,8 +333,8 @@ export default class VideoListener {
}
async crunchyRollListener(ev) {
if (
ev.detail.watchPartyDirection === 'TO_APP' &&
ev.detail.type === 'WATCH_PARTY_PLAYER_UPDATE'
ev.detail.watchPartyDirection === "TO_APP" &&
ev.detail.type === "WATCH_PARTY_PLAYER_UPDATE"
) {
this.updateStatus({
status: ev.detail.status,
@@ -417,15 +355,15 @@ export default class VideoListener {
case PLAYER_SOURCE.FUNIMATION:
window.postMessage(
JSON.stringify({
watchPartyDirection: 'TO_SCRIPT',
type: 'WATCH_PARTY_ADD_LISTENERS',
watchPartyDirection: "TO_SCRIPT",
type: "WATCH_PARTY_ADD_LISTENERS",
})
);
window.addEventListener('watchParty', this.crunchyRollListener);
window.addEventListener("watchParty", this.crunchyRollListener);
break;
default:
videoElement.addEventListener('playing', this.onplay);
videoElement.addEventListener('pause', this.onpause);
videoElement.addEventListener("playing", this.onplay);
videoElement.addEventListener("pause", this.onpause);
break;
}
}
@@ -434,37 +372,34 @@ export default class VideoListener {
source: getPlayerSource(),
showName: await this.getShowName(),
});
const vS = this.selectors[this.video.source];
switch (this.video.source) {
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().pause();getVideoPlayer().seek(e.data.time);}if(e.data.type&&e.data.type==="PAUSE"){getVideoPlayer().pause();}if(e.data.type&&e.data.type==="PLAY"){getVideoPlayer().play();}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');
const seekInjectScript = document.createElement("script");
seekInjectScript.text = seekInject;
document.head.appendChild(seekInjectScript);
const videoElement = document.querySelector(this.selectors[PLAYER_SOURCE.NETFLIX]);
if (videoElement && !this.video.element) {
this.firstTimeSync(videoElement);
const netflixVideoElement = document.querySelector(vS);
if (netflixVideoElement && !this.video.element) {
this.firstTimeSync(netflixVideoElement);
} else {
setInterval(
this.video.element
? null
: () => {
var nve = document.querySelector(this.selectors[PLAYER_SOURCE.NETFLIX]);
if (nve !== null && (this.video.element !== nve || this.video.element === null)) {
this.firstTimeSync(nve);
}
},
1000
);
setInterval(() => {
var nve = document.querySelector(vS);
if (
nve !== null &&
(this.video.element !== nve || this.video.element === null)
) {
this.firstTimeSync(nve);
}
}, 1000);
}
break;
case PLAYER_SOURCE.HULU:
const huluSeekInject = `window.seekScriptLoaded=!0;var getVideoPlayer=function(){var e=document.querySelector("${
this.selectors[PLAYER_SOURCE.HULU]
}").__HuluDashPlayer__;return e;},seekInteraction=function(e){if(e.source==window){if(e.data.type&&"SEEK"==e.data.type){getVideoPlayer().seek(e.data.time,e.data.time);}if(e.data.type&&e.data.type==="PAUSE"){getVideoPlayer().pause();}if(e.data.type&&e.data.type==="PLAY"){getVideoPlayer().play();}e.data.type&&"teardown"==e.data.type&&(window.removeEventListener("message",seekInteraction,!1),window.seekScriptLoaded=!1)}};window.addEventListener("message",seekInteraction,!1);`;
const huluSeekInjectScript = document.createElement('script');
const huluSeekInject = `window.seekScriptLoaded=!0;var getVideoPlayer=function(){var e=document.querySelector("${vS}").__HuluDashPlayer__;return e;},seekInteraction=function(e){if(e.source==window){if(e.data.type&&"SEEK"==e.data.type){getVideoPlayer().seek(e.data.time,e.data.time);}if(e.data.type&&e.data.type==="PAUSE"){getVideoPlayer().pause();}if(e.data.type&&e.data.type==="PLAY"){getVideoPlayer().play();}e.data.type&&"teardown"==e.data.type&&(window.removeEventListener("message",seekInteraction,!1),window.seekScriptLoaded=!1)}};window.addEventListener("message",seekInteraction,!1);`;
const huluSeekInjectScript = document.createElement("script");
huluSeekInjectScript.text = huluSeekInject;
document.head.appendChild(huluSeekInjectScript);
const huluVideoElement = document.querySelector(this.selectors[PLAYER_SOURCE.HULU]);
const huluVideoElement = document.querySelector(vS);
if (huluVideoElement) {
this.firstTimeSync(huluVideoElement);
} else {
@@ -472,91 +407,9 @@ export default class VideoListener {
this.video.element
? null
: () => {
var hve = document.querySelector(this.selectors[PLAYER_SOURCE.HULU]);
if (hve !== null && (this.video.element !== hve || this.video.element === null)) {
this.firstTimeSync(hve);
}
},
1000
);
}
break;
case PLAYER_SOURCE.AMAZON:
const amazonVideoElement = document.querySelector(this.selectors[PLAYER_SOURCE.AMAZON]);
if (amazonVideoElement) {
this.firstTimeSync(amazonVideoElement);
} else {
setInterval(
this.video.element
? null
: () => {
var ave = document.querySelector(this.selectors[PLAYER_SOURCE.AMAZON]);
if (ave !== null && (this.video.element !== ave || this.video.element === null)) {
this.firstTimeSync(ave);
}
},
1000
);
}
break;
case PLAYER_SOURCE.DISNEY:
const disneyVideoElement = document.querySelector(this.selectors[PLAYER_SOURCE.DISNEY]);
if (disneyVideoElement) {
this.firstTimeSync(disneyVideoElement);
} else {
setInterval(
this.video.element
? null
: () => {
var dve = document.querySelector(this.selectors[PLAYER_SOURCE.DISNEY]);
if (dve !== null && (this.video.element !== dve || this.video.element === null)) {
this.firstTimeSync(dve);
}
},
1000
);
}
break;
case PLAYER_SOURCE.YOUTUBE:
const youtubeVideoElement = document.querySelector(this.selectors[PLAYER_SOURCE.YOUTUBE]);
if (youtubeVideoElement) this.firstTimeSync(youtubeVideoElement);
else {
setInterval(
this.video.element
? null
: () => {
var yve = document.querySelector(this.selectors[PLAYER_SOURCE.YOUTUBE]);
if (yve !== null && (this.video.element !== yve || this.video.element === null)) {
this.firstTimeSync(yve);
}
},
1000
);
}
break;
case PLAYER_SOURCE.HBOMAX:
const hboSeekInject = `window.seekScriptLoaded=!0;var getVideoPlayer=function(){var e=document.querySelector("${
this.selectors[PLAYER_SOURCE.HBOMAX]
}")._dispNode;return e;},seekInteraction=function(e){if(e.source==window){if(e.data.type&&e.data.type==="PAUSE"){getVideoPlayer().pause();}if(e.data.type&&e.data.type==="PLAY"){getVideoPlayer().play();}e.data.type&&"teardown"==e.data.type&&(window.removeEventListener("message",seekInteraction,!1),window.seekScriptLoaded=!1)}};window.addEventListener("message",seekInteraction,!1);`;
const hboSeekInjectScript = document.createElement('script');
hboSeekInjectScript.text = hboSeekInject;
document.head.appendChild(hboSeekInjectScript);
const hboVideoElement = document.querySelector(this.selectors[PLAYER_SOURCE.HBOMAX]);
if (hboVideoElement) {
const bottomHalf =
hboVideoElement.parentNode.parentNode.parentNode.parentNode.parentNode.children[1];
bottomHalf.children[0].id = 'hboUpperTitle';
bottomHalf.children[1].id = 'hboLowerTitle';
this.firstTimeSync(hboVideoElement);
} else {
setInterval(
this.video.element
? null
: () => {
var hve = document.querySelector(this.selectors[PLAYER_SOURCE.HBOMAX]);
var hve = document.querySelector(vS);
if (
hve !== null &&
hve !== undefined &&
(this.video.element !== hve || this.video.element === null)
) {
this.firstTimeSync(hve);
@@ -567,30 +420,35 @@ export default class VideoListener {
}
break;
case PLAYER_SOURCE.HBONOW:
const hboNowSeekInject = `window.seekScriptLoaded=!0;var getVideoPlayer=function(){var e=document.querySelector("${
this.selectors[PLAYER_SOURCE.HBONOW]
}")._dispNode;return e;},seekInteraction=function(e){if(e.source==window){if(e.data.type&&e.data.type==="PAUSE"){getVideoPlayer().pause();}if(e.data.type&&e.data.type==="PLAY"){getVideoPlayer().play();}e.data.type&&"teardown"==e.data.type&&(window.removeEventListener("message",seekInteraction,!1),window.seekScriptLoaded=!1)}};window.addEventListener("message",seekInteraction,!1);`;
const hboNowSeekInjectScript = document.createElement('script');
hboNowSeekInjectScript.text = hboNowSeekInject;
document.head.appendChild(hboNowSeekInjectScript);
const hboNowVideoElement = document.querySelector(this.selectors[PLAYER_SOURCE.HBONOW]);
if (hboNowVideoElement) {
case PLAYER_SOURCE.HBOMAX:
const hboSeekInject = `window.seekScriptLoaded=!0;var getVideoPlayer=function(){var e=document.querySelector("${vS}")._dispNode;return e;},seekInteraction=function(e){if(e.source==window){if(e.data.type&&e.data.type==="PAUSE"){getVideoPlayer().pause();}if(e.data.type&&e.data.type==="PLAY"){getVideoPlayer().play();}e.data.type&&"teardown"==e.data.type&&(window.removeEventListener("message",seekInteraction,!1),window.seekScriptLoaded=!1)}};window.addEventListener("message",seekInteraction,!1);`;
const hboSeekInjectScript = document.createElement("script");
hboSeekInjectScript.text = hboSeekInject;
document.head.appendChild(hboSeekInjectScript);
const hboVideoElement = document.querySelector(vS);
if (hboVideoElement) {
const bottomHalf =
hboNowVideoElement.parentNode.parentNode.parentNode.parentNode.parentNode.children[1];
bottomHalf.children[0].id = 'hboUpperTitle';
bottomHalf.children[1].id = 'hboLowerTitle';
this.firstTimeSync(hboNowVideoElement);
hboVideoElement.parentNode.parentNode.parentNode.parentNode
.parentNode.children[1];
bottomHalf.children[0].id = "hboUpperTitle";
bottomHalf.children[1].id = "hboLowerTitle";
this.firstTimeSync(hboVideoElement);
} else {
setInterval(
this.video.element
? null
: () => {
var hve = document.querySelector(this.selectors[PLAYER_SOURCE.HBONOW]);
var hve = document.querySelector(vS);
if (
hve !== null &&
hve !== undefined &&
(this.video.element !== hve || this.video.element === null)
) {
const bottomHalf =
hve.parentNode.parentNode.parentNode.parentNode.parentNode
.children[1];
bottomHalf.children[0].id = "hboUpperTitle";
bottomHalf.children[1].id = "hboLowerTitle";
this.firstTimeSync(hve);
}
},
@@ -599,13 +457,11 @@ export default class VideoListener {
}
break;
case PLAYER_SOURCE.PEACOCK:
const peacockInject = `var watchPartyInteraction=function(e){if(e.source===window){const data=JSON.parse(e.data);const playerReactElement=document.querySelector("${
this.selectors[PLAYER_SOURCE.PEACOCK]
}");if(data.watchPartyDirection==='TO_SCRIPT'){if(data.type==='WATCH_PARTY_SEEK'){if(playerReactElement&&playerReactElement.player){playerReactElement.player.seek(data.time)}}else if(data.type==='WATCH_PARTY_STATUS'){if(playerReactElement&&playerReactElement.player){if(data.status==='PAUSED')playerReactElement.player.pause();if(data.status==='PLAYING')playerReactElement.player.play()}}}}};window.addEventListener("message",watchPartyInteraction);`;
const peacockInjectScript = document.createElement('script');
const peacockInject = `var watchPartyInteraction=function(e){if(e.source===window){const data=JSON.parse(e.data);const playerReactElement=document.querySelector("${vS}");if(data.watchPartyDirection==='TO_SCRIPT'){if(data.type==='WATCH_PARTY_SEEK'){if(playerReactElement&&playerReactElement.player){playerReactElement.player.seek(data.time)}}else if(data.type==='WATCH_PARTY_STATUS'){if(playerReactElement&&playerReactElement.player){if(data.status==='PAUSED')playerReactElement.player.pause();if(data.status==='PLAYING')playerReactElement.player.play()}}}}};window.addEventListener("message",watchPartyInteraction);`;
const peacockInjectScript = document.createElement("script");
peacockInjectScript.text = peacockInject;
document.head.appendChild(peacockInjectScript);
const peacockVideoElement = document.querySelector(this.selectors[PLAYER_SOURCE.PEACOCK]);
const peacockVideoElement = document.querySelector(vS);
if (peacockVideoElement) {
this.firstTimeSync(peacockVideoElement);
} else {
@@ -613,7 +469,7 @@ export default class VideoListener {
this.video.element
? null
: () => {
var pve = document.querySelector(this.selectors[PLAYER_SOURCE.PEACOCK]);
var pve = document.querySelector(vS);
if (
pve !== null &&
pve !== undefined &&
@@ -627,9 +483,11 @@ export default class VideoListener {
}
break;
case PLAYER_SOURCE.GOOGLEPLAY:
const playerIframe = document.querySelector(this.selectors[PLAYER_SOURCE.GOOGLEPLAY]);
const playerIframe = document.querySelector(vS);
if (playerIframe) {
const googlePlayVideoElement = playerIframe.contentWindow.document.querySelector('video');
const googlePlayVideoElement = playerIframe.contentWindow.document.querySelector(
"video"
);
if (googlePlayVideoElement) {
this.firstTimeSync(googlePlayVideoElement);
}
@@ -638,9 +496,11 @@ export default class VideoListener {
this.video.element
? null
: () => {
const pif = document.querySelector(this.selectors[PLAYER_SOURCE.GOOGLEPLAY]);
const pif = document.querySelector(vS);
if (pif) {
const gpve = pif.contentWindow.document.querySelector('video');
const gpve = pif.contentWindow.document.querySelector(
"video"
);
if (gpve) {
this.firstTimeSync(gpve);
}
@@ -652,10 +512,10 @@ export default class VideoListener {
break;
case PLAYER_SOURCE.CRUNCHYROLL:
const crunchyRollInject = `var sendToWatchPartyApp = function(pS, pT) { var customWatchPartyEvent = new CustomEvent('watchParty', { detail: { watchPartyDirection: 'TO_APP', type: 'WATCH_PARTY_PLAYER_UPDATE', status: pS, time: pT } }); window.dispatchEvent(customWatchPartyEvent); }, watchPartyGetTimeAndSend = function(pS) { if (window.VILOS_PLAYERJS) { window.VILOS_PLAYERJS.getCurrentTime(function(pT) { sendToWatchPartyApp(pS, pT); }); } }, watchPartySendPlaying = function() { watchPartyGetTimeAndSend('PLAYING'); }, watchPartySendPaused = function() { watchPartyGetTimeAndSend('PAUSED'); }, watchPartyInteraction = function(e) { if (e.source === window) { const data = JSON.parse(e.data); if (data.watchPartyDirection === 'TO_SCRIPT') { if (data.type === 'WATCH_PARTY_ADD_LISTENERS') { if (window.VILOS_PLAYERJS) { window.VILOS_PLAYERJS.on('play', watchPartySendPlaying, 'player.js'); window.VILOS_PLAYERJS.on('pause', watchPartySendPaused, 'player.js'); } } else if (data.type === 'WATCH_PARTY_SEEK') { if (window.VILOS_PLAYERJS) { window.VILOS_PLAYERJS.setCurrentTime(data.time); } } else if (data.type === 'WATCH_PARTY_STATUS') { if (window.VILOS_PLAYERJS) { if (data.status === 'PAUSED') window.VILOS_PLAYERJS.pause(); if (data.status === 'PLAYING') window.VILOS_PLAYERJS.play(); } } } } }; window.addEventListener("message", watchPartyInteraction);`;
const crunchyRollInjectScript = document.createElement('script');
const crunchyRollInjectScript = document.createElement("script");
crunchyRollInjectScript.text = crunchyRollInject;
document.head.appendChild(crunchyRollInjectScript);
const crunchyrollIframe = document.querySelector(this.selectors[PLAYER_SOURCE.CRUNCHYROLL]);
const crunchyrollIframe = document.querySelector(vS);
if (crunchyrollIframe) {
this.firstTimeSync(crunchyrollIframe);
} else {
@@ -663,7 +523,7 @@ export default class VideoListener {
this.video.element
? null
: () => {
const cif = document.querySelector(this.selectors[PLAYER_SOURCE.CRUNCHYROLL]);
const cif = document.querySelector(vS);
if (cif) {
this.firstTimeSync(cif);
}
@@ -673,34 +533,44 @@ export default class VideoListener {
}
break;
case PLAYER_SOURCE.APPLE:
const appleTvPlayer = document.querySelector('apple-tv-plus-player');
const appleTvInternal = appleTvPlayer.shadowRoot.querySelector('amp-video-player-internal');
const appleTvVideoContainer = appleTvInternal.shadowRoot.querySelector('amp-video-player');
const appleTvPlayer = document.querySelector("apple-tv-plus-player");
const appleTvInternal = appleTvPlayer.shadowRoot.querySelector(
"amp-video-player-internal"
);
const appleTvVideoContainer = appleTvInternal.shadowRoot.querySelector(
"amp-video-player"
);
const appleVideoElement = appleTvVideoContainer.shadowRoot.querySelector(
this.selectors[PLAYER_SOURCE.APPLE]
vS
);
if (appleVideoElement) {
const takeoverContainer = appleTvPlayer.shadowRoot.querySelector(
'.takeover.container.show'
".takeover.container.show"
);
if (takeoverContainer) takeoverContainer.style.maxWidth = 'var(--body-width)';
if (takeoverContainer)
takeoverContainer.style.maxWidth = "var(--body-width)";
this.firstTimeSync(appleVideoElement);
} else {
setInterval(
this.video.element
? null
: () => {
const atp = document.querySelector('apple-tv-plus-player');
const ati = atp.shadowRoot.querySelector('amp-video-player-internal');
const atv = ati.shadowRoot.querySelector('amp-video-player');
const atve = atv.shadowRoot.querySelector(this.selectors[PLAYER_SOURCE.APPLE]);
const tc = atp.shadowRoot.querySelector('.takeover.container.show');
const visible = document.querySelector('body.visible');
if (tc && visible) tc.style.maxWidth = 'var(--body-width)';
else if (tc && !visible) tc.style.maxWidth = 'none';
const atp = document.querySelector("apple-tv-plus-player");
const ati = atp.shadowRoot.querySelector(
"amp-video-player-internal"
);
const atv = ati.shadowRoot.querySelector("amp-video-player");
const atve = atv.shadowRoot.querySelector(vS);
const tc = atp.shadowRoot.querySelector(
".takeover.container.show"
);
const visible = document.querySelector("body.visible");
if (tc && visible) tc.style.maxWidth = "var(--body-width)";
else if (tc && !visible) tc.style.maxWidth = "none";
if (
!!atve === true &&
(!!this.video.element === false || atve !== this.video.element)
(!!this.video.element === false ||
atve !== this.video.element)
) {
this.firstTimeSync(atve);
}
@@ -709,41 +579,17 @@ export default class VideoListener {
);
}
break;
case PLAYER_SOURCE.VIKI:
const vikiVideoElement = document.querySelector(this.selectors[PLAYER_SOURCE.VIKI]);
if (vikiVideoElement) {
this.firstTimeSync(vikiVideoElement);
} else {
setInterval(
this.video.element
? null
: () => {
var vve = document.querySelector(this.selectors[PLAYER_SOURCE.VIKI]);
if (vve !== null && (this.video.element !== vve || this.video.element === null)) {
this.firstTimeSync(vve);
}
},
1000
);
}
break;
case PLAYER_SOURCE.FUNIMATION:
const funimationInject = `var sendToWatchPartyApp=function(pS,pT){var customWatchPartyEvent=new CustomEvent('watchParty',{detail:{watchPartyDirection:'TO_APP',type:'WATCH_PARTY_PLAYER_UPDATE',status:pS,time:pT}});window.dispatchEvent(customWatchPartyEvent)},watchPartyGetTimeAndSend=function(pS){const playerIframe=document.querySelector('${
this.selectors[PLAYER_SOURCE.FUNIMATION]
}');if(playerIframe){const player=playerIframe.contentWindow.document.querySelector('video');if(player){sendToWatchPartyApp(pS,player.currentTime)}}},watchPartySendPlaying=function(){watchPartyGetTimeAndSend('PLAYING')},watchPartySendPaused=function(){watchPartyGetTimeAndSend('PAUSED')},watchPartyAddListeners=function(){const playerIframe=document.querySelector('${
this.selectors[PLAYER_SOURCE.FUNIMATION]
}');if(playerIframe){const player=playerIframe.contentWindow.document.querySelector('video');if(player&&player.currentTime>0&&player.paused===false&&player.ended===false){player.parentNode.player.on('playing',watchPartySendPlaying);player.parentNode.player.on('pause',watchPartySendPaused);clearInterval(watchPartyAddListeners)}}},watchPartyInteraction=function(e){const data=JSON.parse(e.data);const playerIframe=document.querySelector('${
this.selectors[PLAYER_SOURCE.FUNIMATION]
}');if(playerIframe){const player=playerIframe.contentWindow.document.querySelector('video');if(player){if(data.watchPartyDirection==='TO_SCRIPT'){if(data.type==='WATCH_PARTY_ADD_LISTENERS'){player.addEventListener('playing',watchPartySendPlaying);player.addEventListener('pause',watchPartySendPaused)}else if(data.type==='WATCH_PARTY_SEEK'){const playerNode=playerIframe.contentWindow.document.querySelector('#brightcove-player');if(playerNode){playerNode.player.currentTime(data.time)}}else if(data.type==='WATCH_PARTY_STATUS'){if(data.status==='PAUSED')player.pause();if(data.status==='PLAYING')player.play()}}}else{setInterval(watchPartyAddListeners,1000)}}else{setInterval(watchPartyAddListeners,1000)}};window.addEventListener("message",watchPartyInteraction);`;
const funimationInjectScript = document.createElement('script');
const funimationInject = `var sendToWatchPartyApp=function(pS,pT){var customWatchPartyEvent=new CustomEvent('watchParty',{detail:{watchPartyDirection:'TO_APP',type:'WATCH_PARTY_PLAYER_UPDATE',status:pS,time:pT}});window.dispatchEvent(customWatchPartyEvent)},watchPartyGetTimeAndSend=function(pS){const playerIframe=document.querySelector('${vS}');if(playerIframe){const player=playerIframe.contentWindow.document.querySelector('video');if(player){sendToWatchPartyApp(pS,player.currentTime)}}},watchPartySendPlaying=function(){watchPartyGetTimeAndSend('PLAYING')},watchPartySendPaused=function(){watchPartyGetTimeAndSend('PAUSED')},watchPartyAddListeners=function(){const playerIframe=document.querySelector('${vS}');if(playerIframe){const player=playerIframe.contentWindow.document.querySelector('video');if(player&&player.currentTime>0&&player.paused===false&&player.ended===false){player.parentNode.player.on('playing',watchPartySendPlaying);player.parentNode.player.on('pause',watchPartySendPaused);clearInterval(watchPartyAddListeners)}}},watchPartyInteraction=function(e){const data=JSON.parse(e.data);const playerIframe=document.querySelector('${vS}');if(playerIframe){const player=playerIframe.contentWindow.document.querySelector('video');if(player){if(data.watchPartyDirection==='TO_SCRIPT'){if(data.type==='WATCH_PARTY_ADD_LISTENERS'){player.addEventListener('playing',watchPartySendPlaying);player.addEventListener('pause',watchPartySendPaused)}else if(data.type==='WATCH_PARTY_SEEK'){const playerNode=playerIframe.contentWindow.document.querySelector('#brightcove-player');if(playerNode){playerNode.player.currentTime(data.time)}}else if(data.type==='WATCH_PARTY_STATUS'){if(data.status==='PAUSED')player.pause();if(data.status==='PLAYING')player.play()}}}else{setInterval(watchPartyAddListeners,1000)}}else{setInterval(watchPartyAddListeners,1000)}};window.addEventListener("message",watchPartyInteraction);`;
const funimationInjectScript = document.createElement("script");
funimationInjectScript.text = funimationInject;
document.head.appendChild(funimationInjectScript);
const funimationIframe = document.querySelector(this.selectors[PLAYER_SOURCE.FUNIMATION]);
const funimationIframe = document.querySelector(vS);
if (funimationIframe) {
this.firstTimeSync(funimationIframe);
} else {
setInterval(() => {
const fif = document.querySelector(this.selectors[PLAYER_SOURCE.FUNIMATION]);
const fif = document.querySelector(vS);
if (!this.video.element && fif) {
this.firstTimeSync(fif);
}
@@ -751,15 +597,11 @@ export default class VideoListener {
}
break;
case PLAYER_SOURCE.ROOSTERTEETH:
const roosterTeethInject = `var watchPartyInteraction=function(e){const data=JSON.parse(e.data);const player=document.querySelector('${
this.selectors[PLAYER_SOURCE.ROOSTERTEETH]
}');if(player){const playerNode=player.parentNode;if(playerNode.player){if(data.watchPartyDirection==='TO_SCRIPT'){if(data.type==='WATCH_PARTY_SEEK'){playerNode.player.currentTime(data.time);}else if(data.type==='WATCH_PARTY_STATUS'){if(data.status==='PAUSED')player.pause();if(data.status==='PLAYING')player.play()}}}}};window.addEventListener("message",watchPartyInteraction);`;
const roosterTeethInjectScript = document.createElement('script');
const roosterTeethInject = `var watchPartyInteraction=function(e){const data=JSON.parse(e.data);const player=document.querySelector('${vS}');if(player){const playerNode=player.parentNode;if(playerNode.player){if(data.watchPartyDirection==='TO_SCRIPT'){if(data.type==='WATCH_PARTY_SEEK'){playerNode.player.currentTime(data.time);}else if(data.type==='WATCH_PARTY_STATUS'){if(data.status==='PAUSED')player.pause();if(data.status==='PLAYING')player.play()}}}}};window.addEventListener("message",watchPartyInteraction);`;
const roosterTeethInjectScript = document.createElement("script");
roosterTeethInjectScript.text = roosterTeethInject;
document.head.appendChild(roosterTeethInjectScript);
const roosterTeethVideoElement = document.querySelector(
this.selectors[PLAYER_SOURCE.ROOSTERTEETH]
);
const roosterTeethVideoElement = document.querySelector(vS);
if (roosterTeethVideoElement) {
this.firstTimeSync(roosterTeethVideoElement);
} else {
@@ -767,7 +609,7 @@ export default class VideoListener {
this.video.element
? null
: () => {
var rtve = document.querySelector(this.selectors[PLAYER_SOURCE.ROOSTERTEETH]);
var rtve = document.querySelector(vS);
if (
rtve !== null &&
(this.video.element !== rtve || this.video.element === null)
@@ -780,27 +622,26 @@ export default class VideoListener {
}
break;
case PLAYER_SOURCE.STAN:
const stanVideoElement = document.querySelector(this.selectors[PLAYER_SOURCE.STAN]);
if (stanVideoElement) {
this.firstTimeSync(stanVideoElement);
} else {
setInterval(() => {
var sve = document.querySelector(this.selectors[PLAYER_SOURCE.STAN]);
if (sve && !this.video.element && this.video.element !== sve) {
this.firstTimeSync(sve);
}
}, 1000);
}
break;
case PLAYER_SOURCE.HOTSTAR:
const hotstarVideoElement = document.querySelector(this.selectors[PLAYER_SOURCE.HOTSTAR]);
if (hotstarVideoElement) {
this.firstTimeSync(hotstarVideoElement);
case PLAYER_SOURCE.VIKI:
case PLAYER_SOURCE.YOUTUBE:
case PLAYER_SOURCE.DISNEY:
case PLAYER_SOURCE.AMAZON:
case PLAYER_SOURCE.AIRTEL:
case PLAYER_SOURCE.VIMEO:
case PLAYER_SOURCE.DAILYMOTION:
const videoElement = document.querySelector(vS);
if (videoElement) {
this.firstTimeSync(videoElement);
} else {
setInterval(() => {
var hsve = document.querySelector(this.selectors[PLAYER_SOURCE.HOTSTAR]);
if (hsve && !this.video.element && this.video.element !== hsve) {
this.firstTimeSync(hsve);
var newVideoElement = document.querySelector(vS);
if (
newVideoElement &&
!this.video.element &&
this.video.element !== newVideoElement
) {
this.firstTimeSync(newVideoElement);
}
}, 1000);
}
@@ -813,12 +654,12 @@ export default class VideoListener {
switch (this.video.source) {
case PLAYER_SOURCE.CRUNCHYROLL:
case PLAYER_SOURCE.FUNIMATION:
window.removeEventListener('watchParty', this.crunchyRollListener);
window.removeEventListener("watchParty", this.crunchyRollListener);
break;
default:
if (this.video.element) {
this.video.element.removeEventListener('playing', this.onplay);
this.video.element.removeEventListener('pause', this.onpause);
this.video.element.removeEventListener("playing", this.onplay);
this.video.element.removeEventListener("pause", this.onpause);
}
}
}
+31 -3
View File
@@ -124,7 +124,8 @@ body.youtube.visible .ytp-tooltip.ytp-bottom.ytp-preview {
bottom: 100px !important;
top: unset !important;
}
body.youtube.visible td-two-column-browse-results-renderer.grid:not(.grid-disabled) {
body.youtube.visible
td-two-column-browse-results-renderer.grid:not(.grid-disabled) {
max-width: calc(100% - 48px);
}
body.youtube.visible ytd-miniplayer {
@@ -325,6 +326,29 @@ body.hotstar .party-content-wrapper textarea {
background: transparent !important;
height: initial !important;
}
/* AIRTEL */
body.airtel.visible header {
max-width: var(--body-width);
}
/* VIMEO */
body.vimeo.visible main#main > div:first-of-type {
max-width: 100% !important;
}
body.vimeo.visible #topnav_outer_wrap {
max-width: var(--body-width) !important;
}
body.vimeo #party-routes-wrapper .party-chat-container * {
box-sizing: initial !important;
}
body.vimeo #party-routes-wrapper .party-chat-header * {
box-sizing: border-box !important;
}
/* DAILYMOTION */
body.dailymotion.visible #player-wrapper {
max-width: 55%;
height: var(--dailymotion-player-height);
left: var(--dailymotion-player-left) !important;
}
#party-loading {
position: absolute;
@@ -600,6 +624,7 @@ textarea::-webkit-scrollbar {
padding-left: 1rem;
}
.media-info-right .show-name {
color: inherit !important;
font-size: 12px;
line-height: 16px;
white-space: break-spaces !important;
@@ -759,13 +784,16 @@ body.amazon-prime .notification-switch .MuiSwitch-thumb {
}
.admin-only-switch {
margin-bottom: 20px !important;
margin-bottom: 0px !important;
transition: all ease-in 0.3s !important;
height: 70px !important;
margin-top: 0 !important;
overflow: hidden;
opacity: 1;
}
.admin-only-switch:last-of-type {
margin-bottom: 20px !important;
}
.admin-only-switch.admin-only-switch-hidden {
height: 0 !important;
opacity: 0;
@@ -1156,7 +1184,7 @@ body.visible .vxt-video-container {
opacity: 1;
}
.MuiPopover-root[role='presentation'] {
.MuiPopover-root[role="presentation"] {
z-index: 9999 !important;
}
+65 -36
View File
@@ -9,22 +9,26 @@ ALL CONTENT ON WATCH PARTY'S WEBSITE OR IN WATCH PARTY'S CHROME EXTENSION APP, U
CITED ARE THE SOLE INTELLECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE
COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
************************************************************************/
import App from './App';
import React from 'react';
import ReactDOM from 'react-dom';
import { PLAYER_SOURCE, getPlayerSource } from './Api';
import './index.css';
import 'react-virtualized/styles.css';
import App from "./App";
import React from "react";
import ReactDOM from "react-dom";
import {
PLAYER_SOURCE,
getPlayerSource,
UpdateDailymotionVariables,
} from "./Api";
import "./index.css";
import "react-virtualized/styles.css";
const PartyWrapper = document.createElement('div');
PartyWrapper.id = 'party_wrapper';
const PartyWrapper = document.createElement("div");
PartyWrapper.id = "party_wrapper";
document.body.appendChild(PartyWrapper);
document.addEventListener(
'keydown',
"keydown",
(ev) => {
if (ev.code === 'KeyF') {
if (ev.target.tagName !== 'INPUT' && ev.target.tagName !== 'TEXTAREA') {
if (ev.code === "KeyF") {
if (ev.target.tagName !== "INPUT" && ev.target.tagName !== "TEXTAREA") {
ev.stopImmediatePropagation();
ev.stopPropagation();
}
@@ -35,13 +39,13 @@ document.addEventListener(
switch (getPlayerSource()) {
case PLAYER_SOURCE.NETFLIX:
document.body.classList.add('netflix');
document.body.classList.add("netflix");
break;
case PLAYER_SOURCE.HULU:
document.addEventListener(
'keydown',
"keydown",
(ev) => {
if (ev.target.tagName !== 'INPUT' || ev.target.tagName !== 'TEXTAREA') {
if (ev.target.tagName !== "INPUT" || ev.target.tagName !== "TEXTAREA") {
ev.stopImmediatePropagation();
ev.stopPropagation();
} else {
@@ -50,34 +54,37 @@ switch (getPlayerSource()) {
},
{ capture: true }
);
document.body.classList.add('hulu');
document.body.classList.add("hulu");
break;
case PLAYER_SOURCE.AMAZON:
document.body.classList.add('amazon-prime');
document.body.classList.add("amazon-prime");
break;
case PLAYER_SOURCE.DISNEY:
document.body.classList.add('disney');
document.body.classList.add("disney");
break;
case PLAYER_SOURCE.YOUTUBE:
document.body.classList.add('youtube');
document.body.classList.add("youtube");
break;
case PLAYER_SOURCE.HBONOW:
case PLAYER_SOURCE.HBOMAX:
document.body.classList.add('hbo');
document.body.classList.add("hbo");
window.addEventListener(
'mousedown',
"mousedown",
(ev) => {
const partyWrapper = document.querySelector('#party_wrapper');
const tutorialWrapper = document.querySelector('.watch-party-tutorial');
const partyWrapper = document.querySelector("#party_wrapper");
const tutorialWrapper = document.querySelector(".watch-party-tutorial");
if (
(partyWrapper && partyWrapper.contains(ev.target)) ||
(tutorialWrapper && tutorialWrapper.contains(ev.target))
) {
if (ev.target.id !== 'party-width-dragger') {
if (ev.target.id !== "party-width-dragger") {
ev.stopImmediatePropagation();
ev.preventDefault();
}
if (ev.target.tagName === 'INPUT' || ev.target.tagName === 'TEXTAREA') {
if (
ev.target.tagName === "INPUT" ||
ev.target.tagName === "TEXTAREA"
) {
ev.target.focus();
}
}
@@ -85,9 +92,9 @@ switch (getPlayerSource()) {
{ capture: true }
);
window.addEventListener(
'keydown',
"keydown",
(ev) => {
if (ev.target.tagName === 'INPUT' || ev.target.tagName === 'TEXTAREA') {
if (ev.target.tagName === "INPUT" || ev.target.tagName === "TEXTAREA") {
ev.target.focus();
}
ev.stopImmediatePropagation();
@@ -97,34 +104,56 @@ switch (getPlayerSource()) {
);
break;
case PLAYER_SOURCE.PEACOCK:
document.body.classList.add('peacock');
document.body.classList.add("peacock");
window.addEventListener(
"keydown",
(ev) => {
if (ev.target.tagName === "INPUT" || ev.target.tagName === "TEXTAREA") {
ev.target.focus();
}
ev.stopImmediatePropagation();
ev.stopPropagation();
},
{ capture: true }
);
break;
case PLAYER_SOURCE.GOOGLEPLAY:
document.body.classList.add('googleplay');
document.body.classList.add("googleplay");
break;
case PLAYER_SOURCE.CRUNCHYROLL:
document.body.classList.add('crunchyroll');
document.body.classList.add("crunchyroll");
break;
case PLAYER_SOURCE.APPLE:
document.body.classList.add('apple');
document.body.classList.add("apple");
break;
case PLAYER_SOURCE.VIKI:
document.body.classList.add('viki');
document.body.classList.add("viki");
break;
case PLAYER_SOURCE.FUNIMATION:
document.body.classList.add('funimation');
document.body.classList.add("funimation");
break;
case PLAYER_SOURCE.ROOSTERTEETH:
document.body.classList.add('roosterteeth');
document.body.classList.add("roosterteeth");
break;
case PLAYER_SOURCE.STAN:
document.body.classList.add('stan');
document.body.classList.add("stan");
break;
case PLAYER_SOURCE.HOTSTAR:
document.body.classList.add('hotstar');
document.body.classList.add("hotstar");
break;
case PLAYER_SOURCE.AIRTEL:
document.body.classList.add("airtel");
break;
case PLAYER_SOURCE.VIMEO:
document.body.classList.add("vimeo");
break;
case PLAYER_SOURCE.DAILYMOTION:
window.addEventListener("resize", UpdateDailymotionVariables);
document.body.classList.add("dailymotion");
document.querySelector("html").style.fontSize = "10px";
break;
case PLAYER_SOURCE.LOCAL:
document.body.classList.add('local');
document.body.classList.add("local");
break;
default:
break;