diff --git a/admin/package-lock.json b/admin/package-lock.json index 312f6f7..145eb69 100644 --- a/admin/package-lock.json +++ b/admin/package-lock.json @@ -1,6 +1,6 @@ { "name": "watch-party-admin", - "version": "1.7.7", + "version": "1.7.8", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/admin/src/Dashboard.jsx b/admin/src/Dashboard.jsx index 264f418..f419f4f 100644 --- a/admin/src/Dashboard.jsx +++ b/admin/src/Dashboard.jsx @@ -63,6 +63,9 @@ const PLAYER_SOURCES = [ { text: 'VRV', value: 'vrv.' }, { text: 'Stan', value: 'stan.' }, { text: 'Hotstar', value: 'hotstar.' }, + { text: 'Airtel', value: 'airtelxstream.' }, + { text: 'Vimeo', value: 'vimeo.' }, + { text: 'Dailymotion', value: 'dailymotion.' }, ]; const MESSAGE_TYPES = [ diff --git a/app/package-lock.json b/app/package-lock.json index 970ed4d..03e9745 100644 --- a/app/package-lock.json +++ b/app/package-lock.json @@ -1,6 +1,6 @@ { "name": "watch-party-crx", - "version": "1.7.7", + "version": "1.7.8", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/app/public/background.js b/app/public/background.js index c17f1a7..fe3388b 100644 --- a/app/public/background.js +++ b/app/public/background.js @@ -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({ diff --git a/app/public/manifest.json b/app/public/manifest.json index 0f7f44c..fcf4cb4 100644 --- a/app/public/manifest.json +++ b/app/public/manifest.json @@ -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"], diff --git a/app/src/Api.js b/app/src/Api.js index e91fc02..16b28c9 100644 --- a/app/src/Api.js +++ b/app/src/Api.js @@ -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` + ); + } + } +}; diff --git a/app/src/App.js b/app/src/App.js index fa1e3cb..798d6c0 100644 --- a/app/src/App.js +++ b/app/src/App.js @@ -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 ( 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" > -
+
||
{loading && } - {status[APP_VERSION_STRING] && status[APP_VERSION_STRING].active === true ? ( + {status[APP_VERSION_STRING] && + status[APP_VERSION_STRING].active === true ? ( { status={ status[APP_VERSION_STRING] ? status[APP_VERSION_STRING].message - : 'Connecting to server...' + : "Connecting to server..." } /> )} diff --git a/app/src/CallManager.js b/app/src/CallManager.js index d98193a..097e632 100644 --- a/app/src/CallManager.js +++ b/app/src/CallManager.js @@ -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); }); }); diff --git a/app/src/Chat.js b/app/src/Chat.js index fe09cf5..3eff975 100644 --- a/app/src/Chat.js +++ b/app/src/Chat.js @@ -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 !== '') { + if (lastMessage.uid !== "") { 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 = `

Grant Mic / Camera Permission

`; - 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 gif; } 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 - + {name}
@@ -606,9 +659,9 @@ export default class Chat extends Component { {admin && ( @@ -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={ Allow chat notification when side panel is closed
- - {allowChatNotification ? 'Notifications Enabled' : 'Notifications Disabled'} + + {allowChatNotification + ? "Notifications Enabled" + : "Notifications Disabled"} } @@ -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={ Allow Watch Party to auto rejoin (within 1 minute)
- - {allowAutoRejoin ? 'Auto Rejoin Enabled' : 'Auto Rejoin Disabled'} + + {allowAutoRejoin + ? "Auto Rejoin Enabled" + : "Auto Rejoin Disabled"} } @@ -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 { Admin Only Mode
- + {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"} } @@ -726,25 +789,38 @@ export default class Chat extends Component { } label={ - Allow Watch Party to change to the currently playing + (BETA) Allow Watch Party to change to the currently playing
- - {allowAutoFollow ? 'Auto Follow Enabled' : 'Auto Follow Disabled'} + + {allowAutoFollow + ? "Auto Follow Enabled" + : "Auto Follow Disabled"} } labelPlacement="end" /> - + PARTY MEMBERS
{users.map((user) => ( - + ))}
{onCall && ( - + DEVICE SELECT )} @@ -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 { {player ? ( - {player.showName && player.status !== PLAYER_STATUS.NOT_PLAYING ? ( + {player.showName && + player.status !== PLAYER_STATUS.NOT_PLAYING ? ( - - Watch Party will not automatically change the show for you. - + {allowAutoFollow ? null : ( + + Watch Party will not automatically change the show for + you. + + )} ) : ( - + Nothing playing right now @@ -868,7 +963,11 @@ export default class Chat extends Component { )} {player && player.showName && player.status ? ( - ) : null} @@ -900,7 +999,9 @@ export default class Chat extends Component {
@@ -914,8 +1015,15 @@ export default class Chat extends Component {
{gif || newMessage ? null : ( - - + + {isFullscreen ? : } @@ -925,11 +1033,21 @@ export default class Chat extends Component { ) : ( this.handleVideo() : () => this.handlePhoneCall(true)} - color={usingVideo ? 'primary' : 'secondary'} + onClick={ + onCall + ? () => this.handleVideo() + : () => this.handlePhoneCall(true) + } + color={usingVideo ? "primary" : "secondary"} > {usingVideo ? : } @@ -938,11 +1056,14 @@ export default class Chat extends Component { {gif || newMessage || !callEnabled ? null : callActionPending ? ( ) : ( - + this.handlePhoneCall(false)} - color={!onCall ? 'secondary' : 'primary'} + color={!onCall ? "secondary" : "primary"} className="icon-button" > {onCall ? : } @@ -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: ( this.sendMessageInvoker(newMessage)} @@ -1018,13 +1141,15 @@ export default class Chat extends Component { startAdornment: ( { 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 { { 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 { @@ -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 } /> this.partyNameAutocompleteProcessor({ name: v, pin: pin })} + onInputChange={(e, v, r) => + this.partyNameAutocompleteProcessor({ name: v, pin: pin }) + } onChange={(e, v) => this.partyNameAutocompleteProcessor(v)} renderInput={(params) => ( )} /> @@ -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 + } /> this.setState({ adminOnly: !adminOnly })} name="adminOnly" - color={adminOnly ? 'secondary' : 'primary'} + color={adminOnly || publicParty ? "secondary" : "primary"} /> } label={ Admin Only Mode (can be changed later)
- - {adminOnly - ? 'Only admin will update currently playing and start calls' - : 'All members will update currently playing and start calls'} + + {adminOnly || publicParty + ? "Only admin will update currently playing and start calls" + : "All members will update currently playing and start calls"} } labelPlacement="end" /> + {/* this.setState({ publicParty: !publicParty })} + name="publicParty" + color={publicParty ? "secondary" : "primary"} + /> + } + label={ + + Public Party (can be changed later) +
+ + {publicParty + ? "Party will be listed and available to join from Watch Party website" + : "Only people you share with can join"} + +
+ } + labelPlacement="end" + /> */} this.handleExpanders('alerts')} + onClick={() => this.handleExpanders("alerts")} expandIcon={} > @@ -410,20 +468,29 @@ export default class Create extends Component {
- + {status.alerts[alertStep].title} {status.alerts[alertStep].description} - {status.alerts[alertStep].link && status.alerts[alertStep].linkText && ( - - - - )} + {status.alerts[alertStep].link && + status.alerts[alertStep].linkText && ( + + + + )} this.handleSteps(-1)}> + this.handleSteps(-1)} + > } @@ -454,11 +524,11 @@ export default class Create extends Component { this.handleExpanders('settings')} + onClick={() => this.handleExpanders("settings")} expandIcon={} > @@ -480,8 +550,10 @@ export default class Create extends Component { Allow chat notification when side panel is closed
- - {allowChatNotification ? 'Notifications Enabled' : 'Notifications Disabled'} + + {allowChatNotification + ? "Notifications Enabled" + : "Notifications Disabled"} } @@ -500,8 +572,10 @@ export default class Create extends Component { Allow Watch Party to auto rejoin (within 1 minute)
- - {allowAutoRejoin ? 'Auto Rejoin Enabled' : 'Auto Rejoin Disabled'} + + {allowAutoRejoin + ? "Auto Rejoin Enabled" + : "Auto Rejoin Disabled"} } @@ -520,8 +594,10 @@ export default class Create extends Component { Allow Watch Party to change to the currently playing show
- - {allowAutoFollow ? 'Auto Follow Enabled' : 'Auto Follow Disabled'} + + {allowAutoFollow + ? "Auto Follow Enabled" + : "Auto Follow Disabled"} } diff --git a/app/src/Inactive.js b/app/src/Inactive.js index bfd7d62..11c7bdd 100644 --- a/app/src/Inactive.js +++ b/app/src/Inactive.js @@ -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) => (
- SORRY, WATCH PARTY IS UNAVAILABLE RIGHT NOW + + SORRY, WATCH PARTY IS UNAVAILABLE RIGHT NOW + {props.status}
); diff --git a/app/src/Loading.js b/app/src/Loading.js index 2979364..8dd07f1 100644 --- a/app/src/Loading.js +++ b/app/src/Loading.js @@ -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 = () => (
diff --git a/app/src/Thread.css b/app/src/Thread.css index 8b189cc..3ad8a17 100644 --- a/app/src/Thread.css +++ b/app/src/Thread.css @@ -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; } diff --git a/app/src/Thread.js b/app/src/Thread.js index 519b2b9..568520d 100644 --- a/app/src/Thread.js +++ b/app/src/Thread.js @@ -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 === '') { + const thanksElement = document.createElement("div"); + thanksElement.innerText = "THANK YOU FOR THE FEEDBACK"; + thanksElement.className = "thread-interactive-thankyou"; + if (msg.uid === "") { 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-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-message " : ""}${ + lastUid === uid ? "continued-message" : "" + }`; } getMessageTextOrImage(msg, measure) { - if (msg.type === 'giphy') { + if (msg.type === "giphy") { return gif; } - if (msg.type === 'interactive/text') { + if (msg.type === "interactive/text") { return ( - - + + {msg.text} - this.handleInteractiveMessageCall(msg)}> + this.handleInteractiveMessageCall(msg)} + > @@ -109,10 +127,17 @@ export default class Thread extends Component { ); } - if (msg.type === 'interactive/link') { + if (msg.type === "interactive/link") { return ( - - + + {msg.text}
), - 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={ } 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"} } /> diff --git a/app/src/VideoListener.js b/app/src/VideoListener.js index f026375..9e65422 100644 --- a/app/src/VideoListener.js +++ b/app/src/VideoListener.js @@ -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); } } } diff --git a/app/src/index.css b/app/src/index.css index c613fff..098d11a 100644 --- a/app/src/index.css +++ b/app/src/index.css @@ -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; } diff --git a/app/src/index.js b/app/src/index.js index 2b85c58..fd32649 100644 --- a/app/src/index.js +++ b/app/src/index.js @@ -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; diff --git a/assets/Webstore.psd b/assets/Webstore.psd index 8415e26..d3320e3 100644 Binary files a/assets/Webstore.psd and b/assets/Webstore.psd differ diff --git a/assets/images/1.jpg b/assets/images/1.jpg index ecd1ec7..84731c2 100644 Binary files a/assets/images/1.jpg and b/assets/images/1.jpg differ diff --git a/assets/images/IG_02.jpg b/assets/images/IG_02.jpg deleted file mode 100644 index 542ea57..0000000 Binary files a/assets/images/IG_02.jpg and /dev/null differ diff --git a/assets/images/Webstore_02.jpg b/assets/images/Webstore_02.jpg new file mode 100644 index 0000000..c693a14 Binary files /dev/null and b/assets/images/Webstore_02.jpg differ diff --git a/assets/images/IG_03.jpg b/assets/images/Webstore_03.jpg similarity index 99% rename from assets/images/IG_03.jpg rename to assets/images/Webstore_03.jpg index a268af1..a4ce127 100644 Binary files a/assets/images/IG_03.jpg and b/assets/images/Webstore_03.jpg differ diff --git a/assets/images/IG_04.jpg b/assets/images/Webstore_04.jpg similarity index 99% rename from assets/images/IG_04.jpg rename to assets/images/Webstore_04.jpg index 0cdbe8b..9777e04 100644 Binary files a/assets/images/IG_04.jpg and b/assets/images/Webstore_04.jpg differ diff --git a/assets/images/IG_05.jpg b/assets/images/Webstore_05.jpg similarity index 99% rename from assets/images/IG_05.jpg rename to assets/images/Webstore_05.jpg index 6b24543..33cc5c2 100644 Binary files a/assets/images/IG_05.jpg and b/assets/images/Webstore_05.jpg differ diff --git a/assets/images/Webstore_08.jpg b/assets/images/Webstore_08.jpg index dfea3db..2ef8586 100644 Binary files a/assets/images/Webstore_08.jpg and b/assets/images/Webstore_08.jpg differ diff --git a/assets/images/Webstore_11.jpg b/assets/images/Webstore_11.jpg index 44e367f..43330f7 100644 Binary files a/assets/images/Webstore_11.jpg and b/assets/images/Webstore_11.jpg differ diff --git a/assets/images/Webstore_14.jpg b/assets/images/Webstore_14.jpg index 8a49f8b..d312df7 100644 Binary files a/assets/images/Webstore_14.jpg and b/assets/images/Webstore_14.jpg differ diff --git a/functions/modules/app.js b/functions/modules/app.js index 16f0a57..da7fb75 100644 --- a/functions/modules/app.js +++ b/functions/modules/app.js @@ -1,7 +1,7 @@ -const express = require('express'); -const cors = require('cors'); +const express = require("express"); +const cors = require("cors"); -require('https').globalAgent.keepAlive = true; +require("https").globalAgent.keepAlive = true; let authenticator; let tokenValidator; @@ -19,47 +19,47 @@ let updateAdminOnly; const app = express(); app.use(cors({ origin: true })); app.use((req, res, next) => { - if (!authenticator) authenticator = require('./authenticator'); + if (!authenticator) authenticator = require("./authenticator"); authenticator(req, res, next); }); -app.get('/validator/:partyName', (req, res) => { - if (!tokenValidator) tokenValidator = require('./tokenValidator'); +app.get("/validator/:partyName", (req, res) => { + if (!tokenValidator) tokenValidator = require("./tokenValidator"); tokenValidator(req, res); }); -app.get('/refresher/:token', (req, res) => { - if (!tokenRefresher) tokenRefresher = require('./tokenRefresher'); +app.get("/refresher/:token", (req, res) => { + if (!tokenRefresher) tokenRefresher = require("./tokenRefresher"); tokenRefresher(req, res); }); -app.post('/create', (req, res) => { - if (!createRoom) createRoom = require('./createRoom'); +app.post("/create", (req, res) => { + if (!createRoom) createRoom = require("./createRoom"); createRoom(req, res); }); -app.post('/join', (req, res) => { - if (!joinRoom) joinRoom = require('./joinRoom'); +app.post("/join", (req, res) => { + if (!joinRoom) joinRoom = require("./joinRoom"); joinRoom(req, res); }); -app.post('/message', (req, res) => { - if (!sendMessage) sendMessage = require('./sendMessage'); +app.post("/message", (req, res) => { + if (!sendMessage) sendMessage = require("./sendMessage"); sendMessage(req, res); }); -app.post('/updatePlayer', (req, res) => { - if (!updatePlayer) updatePlayer = require('./updatePlayer'); +app.post("/updatePlayer", (req, res) => { + if (!updatePlayer) updatePlayer = require("./updatePlayer"); updatePlayer(req, res); }); -app.post('/updateVoxeet', (req, res) => { - if (!updateVoxeet) updateVoxeet = require('./updateVoxeet'); +app.post("/updateVoxeet", (req, res) => { + if (!updateVoxeet) updateVoxeet = require("./updateVoxeet"); updateVoxeet(req, res); }); -app.delete('/leave/:rid/users/:uid', (req, res) => { - if (!leaveRoom) leaveRoom = require('./leaveRoom'); +app.delete("/leave/:rid/users/:uid", (req, res) => { + if (!leaveRoom) leaveRoom = require("./leaveRoom"); leaveRoom(req, res); }); -app.delete('/delete/:rid', (req, res) => { - if (!deleteRoom) deleteRoom = require('./deleteRoom'); +app.delete("/delete/:rid", (req, res) => { + if (!deleteRoom) deleteRoom = require("./deleteRoom"); deleteRoom(req, res); }); -app.put('/updateAdminOnly/:rid/:adminOnly', (req, res) => { - if (!updateAdminOnly) updateAdminOnly = require('./updateAdminOnly'); +app.put("/updateAdminOnly/:rid/:adminOnly", (req, res) => { + if (!updateAdminOnly) updateAdminOnly = require("./updateAdminOnly"); updateAdminOnly(req, res); }); diff --git a/functions/modules/authenticator.js b/functions/modules/authenticator.js index c201a71..e7eed59 100644 --- a/functions/modules/authenticator.js +++ b/functions/modules/authenticator.js @@ -1,59 +1,67 @@ -const admin = require('firebase-admin'); -const Logger = require('../Logger'); -const mLogger = new Logger('modules', 'authenticator'); +const admin = require("firebase-admin"); +const Logger = require("../Logger"); +const mLogger = new Logger("modules", "authenticator"); module.exports = (req, res, next) => { mLogger.start(); - res.set('Access-Control-Allow-Origin', ['*']); - if (req.url === '/') { - mLogger.success('HEARTBEAT', { URL: req.url }); - res.status(200).send({ message: 'ALIVE' }); + res.set("Access-Control-Allow-Origin", ["*"]); + if (req.url === "/") { + mLogger.success("HEARTBEAT", { URL: req.url }); + res.status(200).send({ message: "ALIVE" }); return next(); } - if (req.method === 'OPTIONS') { - mLogger.success('OPTIONS CALL', { URL: req.url }); + if (req.method === "OPTIONS") { + mLogger.success("OPTIONS CALL", { URL: req.url }); res.status(200).send(); return next(); } if (req.headers.authorization) { try { - const token = req.headers.authorization.split(' ')[1]; - const reqToken = token.split(':')[0]; - const reqUid = token.split(':')[1]; + const token = req.headers.authorization.split(" ")[1]; + const reqToken = token.split(":")[0]; + const reqUid = token.split(":")[1]; admin .auth() .verifyIdToken(reqToken) .then((user) => { if (user.uid === reqUid) { - if (req.method === 'POST') { + if (req.method === "POST") { const bodydata = JSON.parse(req.body); bodydata.uid = user.uid; req.body = JSON.stringify(bodydata); } - if (req.method === 'GET' || req.method === 'DELETE' || req.method === 'PUT') { + if ( + req.method === "GET" || + req.method === "DELETE" || + req.method === "PUT" + ) { req.body = JSON.stringify({ uid: user.uid }); } - mLogger.success('AUTHORIZED', { URL: req.url, UID: reqUid }); + mLogger.success("AUTHORIZED", { URL: req.url, UID: reqUid }); return next(); } else { - mLogger.success('NOT AUTHORIZED', { URL: req.url }); - return res.status(401).send({ message: 'Unauthorized' }); + mLogger.success("NOT AUTHORIZED", { URL: req.url }); + return res.status(401).send({ message: "Unauthorized" }); } }) .catch((err) => { - mLogger.error('AUTH VALIDATE FIREBASE ERROR', { + mLogger.error("AUTH VALIDATE FIREBASE ERROR", { URL: req.url, Error: err, }); - return res.status(500).send({ message: 'Unable to verify user token' }); + return res + .status(500) + .send({ message: "Unable to verify user token" }); }); } catch (err) { - mLogger.error('AUTH VALIDATE ERROR', { URL: req.url, Error: err }); - return res.status(401).send({ message: 'Something went wrong when authorizing' }); + mLogger.error("AUTH VALIDATE ERROR", { URL: req.url, Error: err }); + return res + .status(401) + .send({ message: "Something went wrong when authorizing" }); } } else { - mLogger.error('NO AUTH TOKEN', { URL: req.url }); - res.status(401).send({ message: 'Got no user token' }); + mLogger.error("NO AUTH TOKEN", { URL: req.url }); + res.status(401).send({ message: "Got no user token" }); } return 0; }; diff --git a/functions/modules/createRoom.js b/functions/modules/createRoom.js index e7e1626..ba5816e 100644 --- a/functions/modules/createRoom.js +++ b/functions/modules/createRoom.js @@ -1,4 +1,4 @@ -const admin = require('firebase-admin'); +const admin = require("firebase-admin"); const partyNameHasInvalidChar = (partyName) => /\\/gi.test(partyName) || /\//gi.test(partyName) || /\./gi.test(partyName); @@ -7,32 +7,36 @@ const isValidPin = (pin) => /^.*[0-9].{2}$/.test(pin); module.exports = async (req, res) => { const bodydata = JSON.parse(req.body); - console.log('Requested Create - UID - ', bodydata.uid); + console.log("Requested Create - UID - ", bodydata.uid); if (!bodydata.userName) { - return res.status(400).send({ message: 'Missing user name' }); + return res.status(400).send({ message: "Missing user name" }); } else if (!bodydata.partyName) { - return res.status(400).send({ message: 'Missing party name' }); + return res.status(400).send({ message: "Missing party name" }); } else if (!bodydata.partyPin) { - return res.status(400).send({ message: 'Missing party pin' }); + return res.status(400).send({ message: "Missing party pin" }); } else if (partyNameHasInvalidChar(bodydata.partyName)) { - res.status(400).send({ message: 'Party name can not have "\\" or "/" or "."' }); - } else if (!isValidPin(bodydata.partyPin)) { - return res + res .status(400) - .send({ message: 'Party pin can only have digits and must be atleast 3 digits' }); + .send({ message: 'Party name can not have "\\" or "/" or "."' }); + } else if (!isValidPin(bodydata.partyPin)) { + return res.status(400).send({ + message: "Party pin can only have digits and must be atleast 3 digits", + }); } else { const roomNameTaken = await admin .firestore() - .collection('rooms') - .doc(bodydata.partyName.replace('/', '\\')) + .collection("rooms") + .doc(bodydata.partyName.replace("/", "\\")) .get() .then((docSnap) => docSnap.exists); if (roomNameTaken) { - return res.status(409).send({ message: 'That party name is already taken' }); + return res + .status(409) + .send({ message: "That party name is already taken" }); } else { await admin .firestore() - .collection('rooms') + .collection("rooms") .doc(bodydata.partyName) .set({ name: bodydata.partyName, @@ -41,19 +45,20 @@ module.exports = async (req, res) => { createdAt: new Date(), adminUid: bodydata.uid, adminOnly: bodydata.adminOnly, + publicParty: !!bodydata.publicParty, }) .catch((err) => { - res.status(500).send({ message: 'Unable to start party.' }); + res.status(500).send({ message: "Unable to start party." }); console.error(err); }); await admin .firestore() - .collection('rooms') + .collection("rooms") .doc(bodydata.partyName) - .collection('messages') + .collection("messages") .add({ - uid: '', - name: '', + uid: "", + name: "", text: `${bodydata.userName} started the party.`, time: new Date(), }) @@ -65,9 +70,9 @@ module.exports = async (req, res) => { }); await admin .firestore() - .collection('rooms') + .collection("rooms") .doc(bodydata.partyName) - .collection('users') + .collection("users") .doc(bodydata.uid) .set({ admin: true, @@ -79,7 +84,9 @@ module.exports = async (req, res) => { err ); }); - return res.status(201).send({ roomId: bodydata.partyName, message: 'Started a party!' }); + return res + .status(201) + .send({ roomId: bodydata.partyName, message: "Started a party!" }); } } }; diff --git a/website/404.html b/website/404.html index d4f2a1b..adb87e4 100644 --- a/website/404.html +++ b/website/404.html @@ -122,6 +122,9 @@ COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION. GET FIREFOX ADD-ON + + GET EDGE ADD-ON + GET CHROME EXTENSION @@ -160,6 +163,14 @@ COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION. > Get Firefox Add-On + + Get Edge Add-On +