Merge branch 'v1.6.0'
@@ -2,55 +2,7 @@
|
|||||||
"name": "watch-party-crx",
|
"name": "watch-party-crx",
|
||||||
"version": "1.6.0",
|
"version": "1.6.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {},
|
||||||
"@giphy/js-fetch-api": "^1.5.8",
|
|
||||||
"@giphy/react-components": "^1.0.4",
|
|
||||||
"@material-ui/core": "^4.9.10",
|
|
||||||
"@material-ui/icons": "^4.9.1",
|
|
||||||
"@voxeet/voxeet-web-sdk": "^2.3.1",
|
|
||||||
"autoprefixer": "7.1.6",
|
|
||||||
"babel-core": "6.26.3",
|
|
||||||
"babel-eslint": "10.x",
|
|
||||||
"babel-jest": "20.0.3",
|
|
||||||
"babel-preset-react-app": "^9.0.1",
|
|
||||||
"babel-runtime": "6.26.0",
|
|
||||||
"case-sensitive-paths-webpack-plugin": "2.1.1",
|
|
||||||
"chalk": "1.1.3",
|
|
||||||
"css-loader": "0.28.7",
|
|
||||||
"dotenv": "4.0.0",
|
|
||||||
"dotenv-expand": "4.2.0",
|
|
||||||
"eslint": "6.x",
|
|
||||||
"eslint-config-react-app": "^5.0.1",
|
|
||||||
"eslint-loader": "2.2.1",
|
|
||||||
"eslint-plugin-flowtype": "3.x",
|
|
||||||
"eslint-plugin-import": "2.x",
|
|
||||||
"eslint-plugin-jsx-a11y": "6.x",
|
|
||||||
"eslint-plugin-react": "7.x",
|
|
||||||
"file-loader": "4.2.0",
|
|
||||||
"firebase": "^7.14.0",
|
|
||||||
"fs-extra": "3.0.1",
|
|
||||||
"html-webpack-plugin": "^4.0.0-beta.8",
|
|
||||||
"jest": "20.0.4",
|
|
||||||
"object-assign": "4.1.1",
|
|
||||||
"postcss-flexbugs-fixes": "3.2.0",
|
|
||||||
"postcss-loader": "2.0.8",
|
|
||||||
"promise": "8.0.1",
|
|
||||||
"prop-types": "^15.7.2",
|
|
||||||
"raf": "3.4.0",
|
|
||||||
"react": "^16.4.1",
|
|
||||||
"react-chat-ui": "^0.3.2",
|
|
||||||
"react-dev-utils": "^9.0.0-next.68",
|
|
||||||
"react-dom": "^16.4.1",
|
|
||||||
"react-frame-component": "^4.0.0",
|
|
||||||
"resolve": "1.6.0",
|
|
||||||
"route-lite": "^0.3.0",
|
|
||||||
"style-loader": "0.19.0",
|
|
||||||
"sw-precache-webpack-plugin": "^0.11.5",
|
|
||||||
"url-loader": "0.6.2",
|
|
||||||
"webpack-dev-server": "^3.11.0",
|
|
||||||
"webpack-manifest-plugin": "2.0.4",
|
|
||||||
"whatwg-fetch": "2.0.3"
|
|
||||||
},
|
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node scripts/start.js",
|
"start": "node scripts/start.js",
|
||||||
"build": "node scripts/build.js",
|
"build": "node scripts/build.js",
|
||||||
@@ -101,6 +53,39 @@
|
|||||||
"extends": "react-app"
|
"extends": "react-app"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@material-ui/core": "^4.9.10",
|
||||||
|
"@material-ui/icons": "^4.9.1",
|
||||||
|
"@material-ui/lab": "^4.0.0-alpha.56",
|
||||||
|
"@voxeet/voxeet-web-sdk": "^2.3.1",
|
||||||
|
"autoprefixer": "7.1.6",
|
||||||
|
"babel-runtime": "6.26.0",
|
||||||
|
"case-sensitive-paths-webpack-plugin": "2.1.1",
|
||||||
|
"chalk": "1.1.3",
|
||||||
|
"css-loader": "0.28.7",
|
||||||
|
"dotenv": "4.0.0",
|
||||||
|
"dotenv-expand": "4.2.0",
|
||||||
|
"file-loader": "4.2.0",
|
||||||
|
"firebase": "^7.14.0",
|
||||||
|
"fs-extra": "3.0.1",
|
||||||
|
"html-webpack-plugin": "^4.0.0-beta.8",
|
||||||
|
"jest": "20.0.4",
|
||||||
|
"object-assign": "4.1.1",
|
||||||
|
"postcss-flexbugs-fixes": "3.2.0",
|
||||||
|
"postcss-loader": "2.0.8",
|
||||||
|
"promise": "8.0.1",
|
||||||
|
"prop-types": "^15.7.2",
|
||||||
|
"raf": "3.4.0",
|
||||||
|
"react": "^16.4.1",
|
||||||
|
"react-dom": "^16.4.1",
|
||||||
|
"react-frame-component": "^4.0.0",
|
||||||
|
"react-giphy-searchbox": "^1.4.0",
|
||||||
|
"resolve": "1.6.0",
|
||||||
|
"route-lite": "^0.3.0",
|
||||||
|
"style-loader": "0.19.0",
|
||||||
|
"sw-precache-webpack-plugin": "^0.11.5",
|
||||||
|
"url-loader": "0.6.2",
|
||||||
|
"webpack-manifest-plugin": "2.0.4",
|
||||||
|
"whatwg-fetch": "2.0.3",
|
||||||
"@babel/core": "^7.1.6",
|
"@babel/core": "^7.1.6",
|
||||||
"@babel/preset-env": "^7.1.6",
|
"@babel/preset-env": "^7.1.6",
|
||||||
"@babel/preset-react": "^7.0.0",
|
"@babel/preset-react": "^7.0.0",
|
||||||
@@ -110,6 +95,19 @@
|
|||||||
"eslint-plugin-react-hooks": "^2.0.1",
|
"eslint-plugin-react-hooks": "^2.0.1",
|
||||||
"mini-css-extract-plugin": "^0.8.0",
|
"mini-css-extract-plugin": "^0.8.0",
|
||||||
"webpack": "^4.42.1",
|
"webpack": "^4.42.1",
|
||||||
"webpack-cli": "^3.3.11"
|
"webpack-cli": "^3.3.11",
|
||||||
|
"babel-core": "6.26.3",
|
||||||
|
"babel-eslint": "10.x",
|
||||||
|
"babel-jest": "20.0.3",
|
||||||
|
"babel-preset-react-app": "^9.0.1",
|
||||||
|
"eslint": "6.x",
|
||||||
|
"eslint-config-react-app": "^5.0.1",
|
||||||
|
"eslint-loader": "2.2.1",
|
||||||
|
"eslint-plugin-flowtype": "3.x",
|
||||||
|
"eslint-plugin-import": "2.x",
|
||||||
|
"eslint-plugin-jsx-a11y": "6.x",
|
||||||
|
"eslint-plugin-react": "7.x",
|
||||||
|
"webpack-dev-server": "^3.11.0",
|
||||||
|
"react-dev-utils": "^9.0.0-next.68"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,16 +5,9 @@ Proprietary and confidential
|
|||||||
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
||||||
https://www.chromewatchparty.com/copyright
|
https://www.chromewatchparty.com/copyright
|
||||||
=========================================================================
|
=========================================================================
|
||||||
ALL CONTENT ON IN WATCH PARTY'S CHROME EXTENSION APP, UNLESS OTHERWISE
|
ALL CONTENT ON WATCH PARTY'S WEBSITE OR IN WATCH PARTY'S CHROME EXTENSION APP, UNLESS OTHERWISE
|
||||||
CITED ARE THE SOLE INTELECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE
|
CITED ARE THE SOLE INTELECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE
|
||||||
COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
|
COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
|
||||||
|
|
||||||
Netflix logo is a trademark and intellectual property of Netflix, Inc.
|
|
||||||
Disney+ logo is a trademark and intellectual property of The Walt Disney Company
|
|
||||||
Prime logo is a trademark and intellectual property of Amazon.com, Inc.
|
|
||||||
YouTube logo is a trademark and intellectual property of Google, Inc.
|
|
||||||
Hulu logo is a trademark and intellectual property of Hulu, LLC.
|
|
||||||
HBO Now and HBO Max logos are trademark and intellectual property of WarnerMedia Direct,LLC.
|
|
||||||
------------------------------------------------------------------------->
|
------------------------------------------------------------------------->
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
|
|||||||
@@ -5,20 +5,16 @@ Proprietary and confidential
|
|||||||
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
||||||
https://www.chromewatchparty.com/copyright
|
https://www.chromewatchparty.com/copyright
|
||||||
=========================================================================
|
=========================================================================
|
||||||
ALL CONTENT ON IN WATCH PARTY'S CHROME EXTENSION APP, UNLESS OTHERWISE
|
ALL CONTENT ON WATCH PARTY'S WEBSITE OR IN WATCH PARTY'S CHROME EXTENSION APP, UNLESS OTHERWISE
|
||||||
CITED ARE THE SOLE INTELECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE
|
CITED ARE THE SOLE INTELECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE
|
||||||
COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
|
COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
|
||||||
|
|
||||||
Netflix logo is a trademark and intellectual property of Netflix, Inc.
|
|
||||||
Disney+ logo is a trademark and intellectual property of The Walt Disney Company
|
|
||||||
Prime logo is a trademark and intellectual property of Amazon.com, Inc.
|
|
||||||
YouTube logo is a trademark and intellectual property of Google, Inc.
|
|
||||||
Hulu logo is a trademark and intellectual property of Hulu, LLC.
|
|
||||||
HBO Now and HBO Max logos are trademark and intellectual property of WarnerMedia Direct,LLC.
|
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
/* global chrome */
|
/* global chrome */
|
||||||
/* global firebase */
|
/* global firebase */
|
||||||
|
|
||||||
|
const APP_VERSION = '1.6.0';
|
||||||
|
const APP_VERSION_STRING = APP_VERSION.replace(/\./g, '');
|
||||||
|
|
||||||
const firebaseConfig = {
|
const firebaseConfig = {
|
||||||
apiKey: 'AIzaSyCJLuYpzXLDRmu2ttzFuSGmYcpFxqToWFU',
|
apiKey: 'AIzaSyCJLuYpzXLDRmu2ttzFuSGmYcpFxqToWFU',
|
||||||
authDomain: 'watch-party-crx.firebaseapp.com',
|
authDomain: 'watch-party-crx.firebaseapp.com',
|
||||||
@@ -68,11 +64,40 @@ const sendAuth = async (sendResponse) => {
|
|||||||
sendResponse(firebase.auth().currentUser);
|
sendResponse(firebase.auth().currentUser);
|
||||||
};
|
};
|
||||||
|
|
||||||
chrome.runtime.onInstalled.addListener(() => {
|
chrome.runtime.onInstalled.addListener((details) => {
|
||||||
chrome.tabs.create({
|
if (details.reason) {
|
||||||
url: 'https://www.chromewatchparty.com/welcome',
|
if (details.reason === 'install') {
|
||||||
active: true,
|
if (window.localStorage.getItem('watchPartyVersion')) {
|
||||||
});
|
if (window.localStorage.getItem('watchPartyVersion') !== APP_VERSION) {
|
||||||
|
chrome.tabs.create({
|
||||||
|
url: `http://www.chromewatchparty.com/changes/v${APP_VERSION}`,
|
||||||
|
active: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
chrome.tabs.create({
|
||||||
|
url: 'https://www.chromewatchparty.com/welcome',
|
||||||
|
active: true,
|
||||||
|
});
|
||||||
|
window.localStorage.setItem('watchPartyVersion', APP_VERSION);
|
||||||
|
}
|
||||||
|
} else if (details.reason === 'update') {
|
||||||
|
if (window.localStorage.getItem('watchPartyVersion')) {
|
||||||
|
if (window.localStorage.getItem('watchPartyVersion') !== APP_VERSION) {
|
||||||
|
chrome.tabs.create({
|
||||||
|
url: `http://www.chromewatchparty.com/changes/v${APP_VERSION}`,
|
||||||
|
active: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
chrome.tabs.create({
|
||||||
|
url: `http://www.chromewatchparty.com/changes/v${APP_VERSION}`,
|
||||||
|
active: true,
|
||||||
|
});
|
||||||
|
window.localStorage.setItem('watchPartyVersion', APP_VERSION);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
|
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
|
||||||
@@ -84,6 +109,16 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
|
|||||||
case 'GET_AUTH':
|
case 'GET_AUTH':
|
||||||
sendAuth(sendResponse);
|
sendAuth(sendResponse);
|
||||||
break;
|
break;
|
||||||
|
case 'GET_PARTIES':
|
||||||
|
sendResponse(
|
||||||
|
window.localStorage.getItem('parties')
|
||||||
|
? JSON.parse(window.localStorage.getItem('parties'))
|
||||||
|
: []
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 'EMPTY_PARTIES':
|
||||||
|
window.localStorage.removeItem('parties');
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
console.warn('Unknown message type: <', type, '>');
|
console.warn('Unknown message type: <', type, '>');
|
||||||
break;
|
break;
|
||||||
@@ -98,7 +133,7 @@ chrome.runtime.onConnect.addListener((port) => {
|
|||||||
port.messageListener && port.messageListener();
|
port.messageListener && port.messageListener();
|
||||||
});
|
});
|
||||||
port.onMessage.addListener((request) => {
|
port.onMessage.addListener((request) => {
|
||||||
const { type, roomId } = request;
|
const { type, roomId, roomPin } = request;
|
||||||
if (type === 'INIT') {
|
if (type === 'INIT') {
|
||||||
port.roomListener = firebase
|
port.roomListener = firebase
|
||||||
.firestore()
|
.firestore()
|
||||||
@@ -152,6 +187,26 @@ chrome.runtime.onConnect.addListener((port) => {
|
|||||||
port.postMessage({ isError: true, ...err });
|
port.postMessage({ isError: true, ...err });
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
window.localStorage.setItem(
|
||||||
|
'parties',
|
||||||
|
JSON.stringify([
|
||||||
|
{
|
||||||
|
name: roomId,
|
||||||
|
pin: roomPin,
|
||||||
|
},
|
||||||
|
])
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -5,16 +5,9 @@ Proprietary and confidential
|
|||||||
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
||||||
https://www.chromewatchparty.com/copyright
|
https://www.chromewatchparty.com/copyright
|
||||||
=========================================================================
|
=========================================================================
|
||||||
ALL CONTENT ON IN WATCH PARTY'S CHROME EXTENSION APP, UNLESS OTHERWISE
|
ALL CONTENT ON WATCH PARTY'S WEBSITE OR IN WATCH PARTY'S CHROME EXTENSION APP, UNLESS OTHERWISE
|
||||||
CITED ARE THE SOLE INTELECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE
|
CITED ARE THE SOLE INTELECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE
|
||||||
COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
|
COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
|
||||||
|
|
||||||
Netflix logo is a trademark and intellectual property of Netflix, Inc.
|
|
||||||
Disney+ logo is a trademark and intellectual property of The Walt Disney Company
|
|
||||||
Prime logo is a trademark and intellectual property of Amazon.com, Inc.
|
|
||||||
YouTube logo is a trademark and intellectual property of Google, Inc.
|
|
||||||
Hulu logo is a trademark and intellectual property of Hulu, LLC.
|
|
||||||
HBO Now and HBO Max logos are trademark and intellectual property of WarnerMedia Direct,LLC.
|
|
||||||
------------------------------------------------------------------------->
|
------------------------------------------------------------------------->
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
|
|||||||
@@ -17,7 +17,9 @@
|
|||||||
"https://*.youtube.com/*",
|
"https://*.youtube.com/*",
|
||||||
"https://play.hbonow.com/*",
|
"https://play.hbonow.com/*",
|
||||||
"https://play.hbomax.com/*",
|
"https://play.hbomax.com/*",
|
||||||
"https://*.peacocktv.com/*"
|
"https://*.peacocktv.com/*",
|
||||||
|
"https://play.google.com/movies/*",
|
||||||
|
"https://*.crunchyroll.com/*"
|
||||||
],
|
],
|
||||||
"content_security_policy": "script-src 'self' https://www.gstatic.com/ https://*.firebaseio.com https://www.googleapis.com; object-src 'self'",
|
"content_security_policy": "script-src 'self' https://www.gstatic.com/ https://*.firebaseio.com https://www.googleapis.com; object-src 'self'",
|
||||||
"content_scripts": [
|
"content_scripts": [
|
||||||
@@ -30,7 +32,9 @@
|
|||||||
"https://*.youtube.com/*",
|
"https://*.youtube.com/*",
|
||||||
"https://play.hbonow.com/*",
|
"https://play.hbonow.com/*",
|
||||||
"https://play.hbomax.com/*",
|
"https://play.hbomax.com/*",
|
||||||
"https://*.peacocktv.com/*"
|
"https://*.peacocktv.com/*",
|
||||||
|
"https://play.google.com/*",
|
||||||
|
"https://*.crunchyroll.com/*"
|
||||||
],
|
],
|
||||||
"run_at": "document_idle",
|
"run_at": "document_idle",
|
||||||
"js": ["/static/js/content.js"],
|
"js": ["/static/js/content.js"],
|
||||||
|
|||||||
@@ -5,20 +5,17 @@ Proprietary and confidential
|
|||||||
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
||||||
https://www.chromewatchparty.com/copyright
|
https://www.chromewatchparty.com/copyright
|
||||||
=========================================================================
|
=========================================================================
|
||||||
ALL CONTENT ON IN WATCH PARTY'S CHROME EXTENSION APP, UNLESS OTHERWISE
|
ALL CONTENT ON WATCH PARTY'S WEBSITE OR IN WATCH PARTY'S CHROME EXTENSION APP, UNLESS OTHERWISE
|
||||||
CITED ARE THE SOLE INTELECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE
|
CITED ARE THE SOLE INTELECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE
|
||||||
COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
|
COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
|
||||||
|
|
||||||
Netflix logo is a trademark and intellectual property of Netflix, Inc.
|
|
||||||
Disney+ logo is a trademark and intellectual property of The Walt Disney Company
|
|
||||||
Prime logo is a trademark and intellectual property of Amazon.com, Inc.
|
|
||||||
YouTube logo is a trademark and intellectual property of Google, Inc.
|
|
||||||
Hulu logo is a trademark and intellectual property of Hulu, LLC.
|
|
||||||
HBO Now and HBO Max logos are trademark and intellectual property of WarnerMedia Direct,LLC.
|
|
||||||
------------------------------------------------------------------------->
|
------------------------------------------------------------------------->
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
|
<meta
|
||||||
|
http-equiv="Content-Security-Policy"
|
||||||
|
content="default-src *; style-src 'self' https://* 'unsafe-inline'; script-src 'self' http://* 'unsafe-inline' 'unsafe-eval'"
|
||||||
|
/>
|
||||||
<style>
|
<style>
|
||||||
a {
|
a {
|
||||||
display: table;
|
display: table;
|
||||||
@@ -34,6 +31,7 @@ HBO Now and HBO Max logos are trademark and intellectual property of WarnerMedia
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
border-radius: 36px;
|
border-radius: 36px;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
|
outline: none;
|
||||||
}
|
}
|
||||||
p {
|
p {
|
||||||
word-break: break-word;
|
word-break: break-word;
|
||||||
@@ -50,15 +48,30 @@ HBO Now and HBO Max logos are trademark and intellectual property of WarnerMedia
|
|||||||
background-color: #c0f300;
|
background-color: #c0f300;
|
||||||
color: black;
|
color: black;
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
min-width: max-content;
|
min-width: max-content;
|
||||||
padding: 5px 10px;
|
padding: 5px 10px;
|
||||||
background: #424242;
|
background: #424242;
|
||||||
}
|
}
|
||||||
|
button {
|
||||||
|
padding: 7.5px 3px;
|
||||||
|
margin: 10px 0;
|
||||||
|
border-radius: 13px;
|
||||||
|
width: 100%;
|
||||||
|
background: #c0f300;
|
||||||
|
outline: none !important;
|
||||||
|
border: none;
|
||||||
|
cursor: pointer;
|
||||||
|
filter: drop-shadow(0px 0px 15px rgba(0, 0, 0, 0.7));
|
||||||
|
transition: all ease-in 0.3s;
|
||||||
|
}
|
||||||
|
button:hover {
|
||||||
|
filter: drop-shadow(0px 0px 3px rgba(0, 0, 0, 0.7)) !important;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
<script src="popup.js"></script>
|
||||||
<p>
|
<p>
|
||||||
NOTHING TO DO HERE. GO TO A SUPPORTED WEBSITE, AND LOOK FOR WATCH PARTY IN THE BOTTOM RIGHT
|
NOTHING TO DO HERE. GO TO A SUPPORTED WEBSITE, AND LOOK FOR WATCH PARTY IN THE BOTTOM RIGHT
|
||||||
CORNER OF YOUR SCREEN
|
CORNER OF YOUR SCREEN
|
||||||
@@ -67,5 +80,7 @@ HBO Now and HBO Max logos are trademark and intellectual property of WarnerMedia
|
|||||||
<a target="_blank" href="https://www.chromewatchparty.com/welcome/#tips">FAQ</a>
|
<a target="_blank" href="https://www.chromewatchparty.com/welcome/#tips">FAQ</a>
|
||||||
<a target="_blank" href="mailto:admin@chromewatchparty.com?subject=User Feedback">Feedback</a>
|
<a target="_blank" href="mailto:admin@chromewatchparty.com?subject=User Feedback">Feedback</a>
|
||||||
<a target="_blank" href="https://paypal.me/Ayushya">Donate</a>
|
<a target="_blank" href="https://paypal.me/Ayushya">Donate</a>
|
||||||
|
<p style="width: 100%; max-width: 100%;"></p>
|
||||||
|
<button id="clear-button">Clear Party Names & Pins</button>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
/************************************************************************
|
||||||
|
Copyright (C) Ayushya Amitabh - All Rights Reserved
|
||||||
|
Unauthorized copying of this file, via any medium is strictly prohibited
|
||||||
|
Proprietary and confidential
|
||||||
|
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
||||||
|
https://www.chromewatchparty.com/copyright
|
||||||
|
=========================================================================
|
||||||
|
ALL CONTENT ON WATCH PARTY'S WEBSITE OR IN WATCH PARTY'S CHROME EXTENSION APP, UNLESS OTHERWISE
|
||||||
|
CITED ARE THE SOLE INTELECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE
|
||||||
|
COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
|
||||||
|
************************************************************************/
|
||||||
|
function clearLocal() {
|
||||||
|
window.localStorage.removeItem('parties');
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
window.onload = function () {
|
||||||
|
document.getElementById('clear-button').onclick = clearLocal;
|
||||||
|
};
|
||||||
@@ -5,20 +5,13 @@ Proprietary and confidential
|
|||||||
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
||||||
https://www.chromewatchparty.com/copyright
|
https://www.chromewatchparty.com/copyright
|
||||||
=========================================================================
|
=========================================================================
|
||||||
ALL CONTENT ON IN WATCH PARTY'S CHROME EXTENSION APP, UNLESS OTHERWISE
|
ALL CONTENT ON WATCH PARTY'S WEBSITE OR IN WATCH PARTY'S CHROME EXTENSION APP, UNLESS OTHERWISE
|
||||||
CITED ARE THE SOLE INTELECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE
|
CITED ARE THE SOLE INTELECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE
|
||||||
COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
|
COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
|
||||||
|
|
||||||
Netflix logo is a trademark and intellectual property of Netflix, Inc.
|
|
||||||
Disney+ logo is a trademark and intellectual property of The Walt Disney Company
|
|
||||||
Prime logo is a trademark and intellectual property of Amazon.com, Inc.
|
|
||||||
YouTube logo is a trademark and intellectual property of Google, Inc.
|
|
||||||
Hulu logo is a trademark and intellectual property of Hulu, LLC.
|
|
||||||
HBO Now and HBO Max logos are trademark and intellectual property of WarnerMedia Direct,LLC.
|
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
/*global chrome*/
|
/*global chrome*/
|
||||||
|
|
||||||
const API_HOST = 'https://us-central1-watch-party-crx.cloudfunctions.net/widgets2';
|
const API_HOST = 'https://us-central1-watch-party-crx.cloudfunctions.net/widgets';
|
||||||
|
|
||||||
export const PLAYER_STATUS = {
|
export const PLAYER_STATUS = {
|
||||||
PLAYING: 'PLAYING',
|
PLAYING: 'PLAYING',
|
||||||
@@ -35,6 +28,8 @@ export const PLAYER_SOURCE = {
|
|||||||
HBONOW: 'hbonow.',
|
HBONOW: 'hbonow.',
|
||||||
HBOMAX: 'hbomax.',
|
HBOMAX: 'hbomax.',
|
||||||
PEACOCK: 'peacocktv.',
|
PEACOCK: 'peacocktv.',
|
||||||
|
GOOGLEPLAY: 'play.google.',
|
||||||
|
CRUNCHYROLL: 'crunchyroll.',
|
||||||
LOCAL: 'localhost',
|
LOCAL: 'localhost',
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -48,6 +43,8 @@ export const getPlayerSource = () => {
|
|||||||
if (HREF.includes(PLAYER_SOURCE.HBONOW)) return PLAYER_SOURCE.HBONOW;
|
if (HREF.includes(PLAYER_SOURCE.HBONOW)) return PLAYER_SOURCE.HBONOW;
|
||||||
if (HREF.includes(PLAYER_SOURCE.HBOMAX)) return PLAYER_SOURCE.HBOMAX;
|
if (HREF.includes(PLAYER_SOURCE.HBOMAX)) return PLAYER_SOURCE.HBOMAX;
|
||||||
if (HREF.includes(PLAYER_SOURCE.PEACOCK)) return PLAYER_SOURCE.PEACOCK;
|
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.LOCAL)) return PLAYER_SOURCE.LOCAL;
|
if (HREF.includes(PLAYER_SOURCE.LOCAL)) return PLAYER_SOURCE.LOCAL;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -71,6 +68,13 @@ export const emptyLocalData = () => {
|
|||||||
window.localStorage.removeItem('WatchParty');
|
window.localStorage.removeItem('WatchParty');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const scrollThread = () => {
|
||||||
|
setTimeout(function () {
|
||||||
|
const pcc = document.querySelector('.thread-wrapper');
|
||||||
|
if (pcc) pcc.scrollTop = pcc.scrollHeight;
|
||||||
|
}, 500);
|
||||||
|
};
|
||||||
|
|
||||||
export const getUserUid = async () =>
|
export const getUserUid = async () =>
|
||||||
new Promise((resolve, reject) => {
|
new Promise((resolve, reject) => {
|
||||||
chrome.runtime.sendMessage(
|
chrome.runtime.sendMessage(
|
||||||
@@ -103,6 +107,23 @@ export const fetcher = async ({ endpoint, method, ...args }) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const webhookFetcher = async ({ endpoint, ...args }) => {
|
||||||
|
return new Promise((resolve, reject) =>
|
||||||
|
chrome.runtime.sendMessage(
|
||||||
|
{
|
||||||
|
type: 'API_CALL',
|
||||||
|
url: endpoint,
|
||||||
|
method: 'POST',
|
||||||
|
...args,
|
||||||
|
},
|
||||||
|
(response) => {
|
||||||
|
if (response.status > 299) reject(response);
|
||||||
|
else resolve({ json: () => response });
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export const CreateRoomApi = async (data) => {
|
export const CreateRoomApi = async (data) => {
|
||||||
return fetcher({
|
return fetcher({
|
||||||
endpoint: 'create',
|
endpoint: 'create',
|
||||||
@@ -149,9 +170,9 @@ export const UpdatePlayerApi = async (data) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const GetVoxeetTokenApi = async () => {
|
export const GetVoxeetTokenApi = async (data) => {
|
||||||
return fetcher({
|
return fetcher({
|
||||||
endpoint: 'validator',
|
endpoint: `validator/${data.partyName}`,
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -170,3 +191,10 @@ export const UpdateVoxeetApi = async (data) => {
|
|||||||
body: JSON.stringify(data),
|
body: JSON.stringify(data),
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const UpdateAdminOnly = async (data) => {
|
||||||
|
return fetcher({
|
||||||
|
endpoint: `updateAdminOnly/${data.partyName}/${data.adminOnly}`,
|
||||||
|
method: 'PUT',
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|||||||
@@ -5,20 +5,13 @@ Proprietary and confidential
|
|||||||
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
||||||
https://www.chromewatchparty.com/copyright
|
https://www.chromewatchparty.com/copyright
|
||||||
=========================================================================
|
=========================================================================
|
||||||
ALL CONTENT ON IN WATCH PARTY'S CHROME EXTENSION APP, UNLESS OTHERWISE
|
ALL CONTENT ON WATCH PARTY'S WEBSITE OR IN WATCH PARTY'S CHROME EXTENSION APP, UNLESS OTHERWISE
|
||||||
CITED ARE THE SOLE INTELECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE
|
CITED ARE THE SOLE INTELECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE
|
||||||
COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
|
COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
|
||||||
|
|
||||||
Netflix logo is a trademark and intellectual property of Netflix, Inc.
|
|
||||||
Disney+ logo is a trademark and intellectual property of The Walt Disney Company
|
|
||||||
Prime logo is a trademark and intellectual property of Amazon.com, Inc.
|
|
||||||
YouTube logo is a trademark and intellectual property of Google, Inc.
|
|
||||||
Hulu logo is a trademark and intellectual property of Hulu, LLC.
|
|
||||||
HBO Now and HBO Max logos are trademark and intellectual property of WarnerMedia Direct,LLC.
|
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
import Router from 'route-lite';
|
import Router from 'route-lite';
|
||||||
import { Fab, createMuiTheme, ThemeProvider, Snackbar } from '@material-ui/core';
|
import { Fab, createMuiTheme, ThemeProvider, Snackbar, Tooltip } from '@material-ui/core';
|
||||||
import Create from './Create';
|
import Create from './Create';
|
||||||
import Loading from './Loading';
|
import Loading from './Loading';
|
||||||
import firebase from 'firebase/app';
|
import firebase from 'firebase/app';
|
||||||
@@ -47,6 +40,30 @@ const Routes = (props) => (
|
|||||||
</Router>
|
</Router>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const resetResize = () => {
|
||||||
|
const checkedX = 400;
|
||||||
|
document.documentElement.style.setProperty('--party-width', `${checkedX}px`);
|
||||||
|
document.documentElement.style.setProperty('--neg-party-width', `-${checkedX}px`);
|
||||||
|
};
|
||||||
|
|
||||||
|
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`);
|
||||||
|
};
|
||||||
|
|
||||||
|
const stopResize = (ev) => {
|
||||||
|
document.documentElement.removeEventListener('mousemove', doResize, false);
|
||||||
|
document.documentElement.removeEventListener('mouseup', stopResize, false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const startResize = (ev) => {
|
||||||
|
document.documentElement.addEventListener('mousemove', doResize, false);
|
||||||
|
document.documentElement.addEventListener('mouseup', stopResize, false);
|
||||||
|
};
|
||||||
|
|
||||||
const App = () => {
|
const App = () => {
|
||||||
const closedNotification = { open: false, message: '' };
|
const closedNotification = { open: false, message: '' };
|
||||||
|
|
||||||
@@ -114,6 +131,15 @@ const App = () => {
|
|||||||
/>
|
/>
|
||||||
<div className="party-content-wrapper">
|
<div className="party-content-wrapper">
|
||||||
<div id="party-routes-wrapper">
|
<div id="party-routes-wrapper">
|
||||||
|
<Tooltip
|
||||||
|
placement="right-end"
|
||||||
|
title="Resize Sidebar / Double Click To Reset"
|
||||||
|
aria-label="Resize Sidebar / Double Click To Reset"
|
||||||
|
>
|
||||||
|
<div onDoubleClick={resetResize} onMouseDown={startResize} id="party-width-dragger">
|
||||||
|
||
|
||||||
|
</div>
|
||||||
|
</Tooltip>
|
||||||
{loading && <Loading />}
|
{loading && <Loading />}
|
||||||
{status[APP_VERSION_STRING] && status[APP_VERSION_STRING].active === true ? (
|
{status[APP_VERSION_STRING] && status[APP_VERSION_STRING].active === true ? (
|
||||||
<Routes
|
<Routes
|
||||||
@@ -121,13 +147,14 @@ const App = () => {
|
|||||||
notify={(message) => setNotification({ open: true, message })}
|
notify={(message) => setNotification({ open: true, message })}
|
||||||
appVersion={APP_VERSION}
|
appVersion={APP_VERSION}
|
||||||
appVersionString={APP_VERSION_STRING}
|
appVersionString={APP_VERSION_STRING}
|
||||||
|
status={status[APP_VERSION_STRING]}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<Inactive
|
<Inactive
|
||||||
status={
|
status={
|
||||||
status[APP_VERSION_STRING]
|
status[APP_VERSION_STRING]
|
||||||
? status[APP_VERSION_STRING].message
|
? status[APP_VERSION_STRING].message
|
||||||
: 'Uh oh, looks like our servers are down right now.'
|
: "Uh oh, can't connect to server. Trying again..."
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -5,25 +5,18 @@ Proprietary and confidential
|
|||||||
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
||||||
https://www.chromewatchparty.com/copyright
|
https://www.chromewatchparty.com/copyright
|
||||||
=========================================================================
|
=========================================================================
|
||||||
ALL CONTENT ON IN WATCH PARTY'S CHROME EXTENSION APP, UNLESS OTHERWISE
|
ALL CONTENT ON WATCH PARTY'S WEBSITE OR IN WATCH PARTY'S CHROME EXTENSION APP, UNLESS OTHERWISE
|
||||||
CITED ARE THE SOLE INTELECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE
|
CITED ARE THE SOLE INTELECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE
|
||||||
COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
|
COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
|
||||||
|
|
||||||
Netflix logo is a trademark and intellectual property of Netflix, Inc.
|
|
||||||
Disney+ logo is a trademark and intellectual property of The Walt Disney Company
|
|
||||||
Prime logo is a trademark and intellectual property of Amazon.com, Inc.
|
|
||||||
YouTube logo is a trademark and intellectual property of Google, Inc.
|
|
||||||
Hulu logo is a trademark and intellectual property of Hulu, LLC.
|
|
||||||
HBO Now and HBO Max logos are trademark and intellectual property of WarnerMedia Direct,LLC.
|
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
import VoxeetSDK from '@voxeet/voxeet-web-sdk';
|
import VoxeetSDK from "@voxeet/voxeet-web-sdk";
|
||||||
import {
|
import {
|
||||||
GetVoxeetTokenApi,
|
GetVoxeetTokenApi,
|
||||||
GetRefreshedVoxeetTokenApi,
|
GetRefreshedVoxeetTokenApi,
|
||||||
LocalData,
|
LocalData,
|
||||||
UpdateVoxeetApi,
|
UpdateVoxeetApi,
|
||||||
updateLocalData,
|
updateLocalData,
|
||||||
} from './Api';
|
} from "./Api";
|
||||||
|
|
||||||
export default class CallManager {
|
export default class CallManager {
|
||||||
constructor(listener, notify) {
|
constructor(listener, notify) {
|
||||||
@@ -33,12 +26,18 @@ export default class CallManager {
|
|||||||
this.__accessToken = LocalData().vrT;
|
this.__accessToken = LocalData().vrT;
|
||||||
this.__sessionInitialized = false;
|
this.__sessionInitialized = false;
|
||||||
this.__admin = false;
|
this.__admin = false;
|
||||||
|
this.__adminOnly = true;
|
||||||
}
|
}
|
||||||
toggleCall(onCall, conference, admin) {
|
toggleCall(onCall, conference, admin, adminOnly) {
|
||||||
this.listener({ callActionPending: true });
|
try {
|
||||||
this.__admin = admin;
|
this.listener({ callActionPending: true });
|
||||||
if (onCall === true) this.leaveCall();
|
this.__admin = admin;
|
||||||
else this.boot(conference);
|
this.__adminOnly = adminOnly;
|
||||||
|
if (onCall === true) this.leaveCall();
|
||||||
|
else this.boot(conference);
|
||||||
|
} catch (e) {
|
||||||
|
this.notify("Uh oh something went wrong, try rejoining the call.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
toggleMute(muted) {
|
toggleMute(muted) {
|
||||||
this.listener({ callActionPending: true });
|
this.listener({ callActionPending: true });
|
||||||
@@ -53,16 +52,23 @@ export default class CallManager {
|
|||||||
.fetch(conference._id)
|
.fetch(conference._id)
|
||||||
.then(this.joinCall)
|
.then(this.joinCall)
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
console.error('Failed to fetch conference', err);
|
console.error("Failed to fetch conference", err);
|
||||||
this.startCall();
|
this.startCall();
|
||||||
});
|
});
|
||||||
} else if (opened && !conference) this.startCall();
|
} else if (opened && !conference) {
|
||||||
else console.error('Unable to open Voxeet Session');
|
this.startCall();
|
||||||
|
} else {
|
||||||
|
this.listener({ onCall: false, muted: false, callActionPending: false });
|
||||||
|
console.error("Unable to open Voxeet Session");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
async startCall() {
|
async startCall() {
|
||||||
if (this.__admin === true) {
|
if (!this.__adminOnly || (this.__adminOnly && this.__admin)) {
|
||||||
VoxeetSDK.conference
|
VoxeetSDK.conference
|
||||||
.create({ alias: LocalData().partyName, pin: LocalData().partyPin })
|
.create({
|
||||||
|
alias: `AUTODELETE_${LocalData().partyName}`,
|
||||||
|
pin: LocalData().partyPin,
|
||||||
|
})
|
||||||
.then(async (conference) => {
|
.then(async (conference) => {
|
||||||
const updatedVoxeet = await UpdateVoxeetApi({
|
const updatedVoxeet = await UpdateVoxeetApi({
|
||||||
conference,
|
conference,
|
||||||
@@ -72,25 +78,55 @@ export default class CallManager {
|
|||||||
})
|
})
|
||||||
.then((res) => res.json())
|
.then((res) => res.json())
|
||||||
.then((res) => res.status <= 299)
|
.then((res) => res.status <= 299)
|
||||||
.catch((err) => console.error('Update Voxeet API Error', err));
|
.catch((err) => {
|
||||||
|
if (err.conference) {
|
||||||
|
this.joinCall(err.conference);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
this.notify(err.message);
|
||||||
|
this.listener({
|
||||||
|
onCall: false,
|
||||||
|
muted: false,
|
||||||
|
callActionPending: false,
|
||||||
|
});
|
||||||
|
console.error("Update Voxeet API Error", err);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
if (updatedVoxeet === true) {
|
if (updatedVoxeet === true) {
|
||||||
this.joinCall(conference);
|
this.joinCall(conference);
|
||||||
} else {
|
} else {
|
||||||
console.error('Failed to update party Voxeet');
|
this.listener({
|
||||||
|
onCall: false,
|
||||||
|
muted: false,
|
||||||
|
callActionPending: false,
|
||||||
|
});
|
||||||
|
console.error("Failed to update party Voxeet");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this.notify('Ask your party admin to start the call.');
|
this.notify("Ask your party admin to start the call.");
|
||||||
this.leaveCall();
|
this.leaveCall();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
async joinCall(conference) {
|
async joinCall(conference) {
|
||||||
const joined = await VoxeetSDK.conference
|
const joined = await VoxeetSDK.conference
|
||||||
.join(conference, { constraints: { audio: true, video: false } })
|
.join(conference, { constraints: { audio: true, video: false } })
|
||||||
.then(() => true);
|
.then(() => true)
|
||||||
if (!joined) {
|
.catch((e) => {
|
||||||
this.startCall();
|
this.listener({
|
||||||
}
|
onCall: false,
|
||||||
|
muted: false,
|
||||||
|
callActionPending: false,
|
||||||
|
});
|
||||||
|
this.notify("Unable to join call. Try again in a moment.");
|
||||||
|
console.error("Error joining call", e);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
// Leave changes as comment for later
|
||||||
|
// if (!joined) {
|
||||||
|
// this.startCall();
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
async leaveCall() {
|
async leaveCall() {
|
||||||
VoxeetSDK.conference.leave().then(() => {
|
VoxeetSDK.conference.leave().then(() => {
|
||||||
@@ -107,9 +143,9 @@ export default class CallManager {
|
|||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
} catch (error) {
|
} 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 false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -122,33 +158,26 @@ export default class CallManager {
|
|||||||
this.listener({ usersOnCall });
|
this.listener({ usersOnCall });
|
||||||
}
|
}
|
||||||
async initialize() {
|
async initialize() {
|
||||||
VoxeetSDK.conference.on('participantAdded', () => this.usersListHandle());
|
VoxeetSDK.conference.on("participantAdded", () => this.usersListHandle());
|
||||||
VoxeetSDK.conference.on('participantUpdated', () => this.usersListHandle());
|
VoxeetSDK.conference.on("participantUpdated", () => this.usersListHandle());
|
||||||
|
|
||||||
VoxeetSDK.conference.on('joined', () => {
|
VoxeetSDK.conference.on("joined", () => {
|
||||||
this.listener({ onCall: true, callActionPending: false });
|
this.listener({ onCall: true, callActionPending: false });
|
||||||
});
|
});
|
||||||
|
|
||||||
VoxeetSDK.conference.on('left', () => {
|
VoxeetSDK.conference.on("left", () => {
|
||||||
this.listener({ onCall: false, callActionPending: false, usersOnCall: {} });
|
this.listener({
|
||||||
|
onCall: false,
|
||||||
|
callActionPending: false,
|
||||||
|
usersOnCall: {},
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
VoxeetSDK.conference.on('streamAdded', (participant, stream) => {
|
VoxeetSDK.conference.on("streamAdded", (participant, stream) => {
|
||||||
if (participant !== VoxeetSDK.session.participant) {
|
|
||||||
const voiceNode = document.createElement('video');
|
|
||||||
voiceNode.srcObject = stream;
|
|
||||||
voiceNode.id = participant.id;
|
|
||||||
voiceNode.width = 0;
|
|
||||||
voiceNode.height = 0;
|
|
||||||
voiceNode.autoplay = true;
|
|
||||||
voiceNode.classList.add('voxeetAudioOut');
|
|
||||||
document.body.appendChild(voiceNode);
|
|
||||||
}
|
|
||||||
this.listener({ callActionPending: false });
|
this.listener({ callActionPending: false });
|
||||||
});
|
});
|
||||||
|
|
||||||
VoxeetSDK.conference.on('streamRemoved', (participant, stream) => {
|
VoxeetSDK.conference.on("streamRemoved", (participant, stream) => {
|
||||||
if (document.getElementById(participant.id)) document.getElementById(participant.id).remove();
|
|
||||||
this.listener({ callActionPending: false });
|
this.listener({ callActionPending: false });
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -158,7 +187,7 @@ export default class CallManager {
|
|||||||
this.__accessToken !== null ||
|
this.__accessToken !== null ||
|
||||||
this.__refreshToken !== null
|
this.__refreshToken !== null
|
||||||
) {
|
) {
|
||||||
await GetVoxeetTokenApi()
|
await GetVoxeetTokenApi({ partyName: LocalData().partyName })
|
||||||
.then((res) => res.json())
|
.then((res) => res.json())
|
||||||
.then((tokenResult) => {
|
.then((tokenResult) => {
|
||||||
if (tokenResult.status <= 299) {
|
if (tokenResult.status <= 299) {
|
||||||
@@ -166,11 +195,11 @@ export default class CallManager {
|
|||||||
this.updateTokens(access_token, refresh_token);
|
this.updateTokens(access_token, refresh_token);
|
||||||
VoxeetSDK.initializeToken(access_token, refresh_token);
|
VoxeetSDK.initializeToken(access_token, refresh_token);
|
||||||
} else {
|
} else {
|
||||||
console.error('Get Voxeet Token API Result Error', tokenResult);
|
console.error("Get Voxeet Token API Result Error", tokenResult);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
console.error('Get Voxeet Token API error', err);
|
console.error("Get Voxeet Token API error", err);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
VoxeetSDK.initializeToken(this.__accessToken, this.__refreshToken);
|
VoxeetSDK.initializeToken(this.__accessToken, this.__refreshToken);
|
||||||
@@ -186,7 +215,7 @@ export default class CallManager {
|
|||||||
resolve(access_token);
|
resolve(access_token);
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
console.error('Get Voxeet Token API error', err);
|
console.error("Get Voxeet Token API error", err);
|
||||||
reject(err);
|
reject(err);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -5,16 +5,9 @@ Proprietary and confidential
|
|||||||
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
||||||
https://www.chromewatchparty.com/copyright
|
https://www.chromewatchparty.com/copyright
|
||||||
=========================================================================
|
=========================================================================
|
||||||
ALL CONTENT ON IN WATCH PARTY'S CHROME EXTENSION APP, UNLESS OTHERWISE
|
ALL CONTENT ON WATCH PARTY'S WEBSITE OR IN WATCH PARTY'S CHROME EXTENSION APP, UNLESS OTHERWISE
|
||||||
CITED ARE THE SOLE INTELECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE
|
CITED ARE THE SOLE INTELECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE
|
||||||
COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
|
COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
|
||||||
|
|
||||||
Netflix logo is a trademark and intellectual property of Netflix, Inc.
|
|
||||||
Disney+ logo is a trademark and intellectual property of The Walt Disney Company
|
|
||||||
Prime logo is a trademark and intellectual property of Amazon.com, Inc.
|
|
||||||
YouTube logo is a trademark and intellectual property of Google, Inc.
|
|
||||||
Hulu logo is a trademark and intellectual property of Hulu, LLC.
|
|
||||||
HBO Now and HBO Max logos are trademark and intellectual property of WarnerMedia Direct,LLC.
|
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
/*global chrome */
|
/*global chrome */
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
@@ -35,10 +28,11 @@ import {
|
|||||||
FormControlLabel,
|
FormControlLabel,
|
||||||
Chip,
|
Chip,
|
||||||
CircularProgress,
|
CircularProgress,
|
||||||
|
Paper,
|
||||||
|
Grid,
|
||||||
|
Slider,
|
||||||
} from '@material-ui/core';
|
} from '@material-ui/core';
|
||||||
import Thread from './Thread';
|
import Thread from './Thread';
|
||||||
import { Carousel } from '@giphy/react-components';
|
|
||||||
import { GiphyFetch } from '@giphy/js-fetch-api';
|
|
||||||
import {
|
import {
|
||||||
SendMessageApi,
|
SendMessageApi,
|
||||||
LeaveRoomApi,
|
LeaveRoomApi,
|
||||||
@@ -48,8 +42,10 @@ import {
|
|||||||
PLAYER_SOURCE,
|
PLAYER_SOURCE,
|
||||||
LocalData,
|
LocalData,
|
||||||
PLAYER_STATUS,
|
PLAYER_STATUS,
|
||||||
emptyLocalData,
|
|
||||||
updateLocalData,
|
updateLocalData,
|
||||||
|
UpdateAdminOnly,
|
||||||
|
scrollThread,
|
||||||
|
removeLocalData,
|
||||||
} from './Api';
|
} from './Api';
|
||||||
import {
|
import {
|
||||||
Send,
|
Send,
|
||||||
@@ -69,24 +65,17 @@ import {
|
|||||||
Error,
|
Error,
|
||||||
FullscreenExit,
|
FullscreenExit,
|
||||||
Fullscreen,
|
Fullscreen,
|
||||||
|
VolumeDown,
|
||||||
|
VolumeUp,
|
||||||
|
CancelRounded,
|
||||||
} from '@material-ui/icons';
|
} from '@material-ui/icons';
|
||||||
import Create from './Create';
|
import Create from './Create';
|
||||||
import { goTo } from 'route-lite';
|
import { goTo } from 'route-lite';
|
||||||
import CallManager from './CallManager';
|
import CallManager from './CallManager';
|
||||||
import VideoListener from './VideoListener';
|
import VideoListener from './VideoListener';
|
||||||
|
import ReactGiphySearchbox from 'react-giphy-searchbox';
|
||||||
|
|
||||||
const giphyFetch = new GiphyFetch('ojJbIMUN6XRMn4mHiFFav3rMCpXUg8sq');
|
// const giphyFetch = new GiphyFetch('ojJbIMUN6XRMn4mHiFFav3rMCpXUg8sq');
|
||||||
const alerts = [
|
|
||||||
{
|
|
||||||
condition: () =>
|
|
||||||
getPlayerSource() === PLAYER_SOURCE.HBOMAX || getPlayerSource() === PLAYER_SOURCE.HBONOW,
|
|
||||||
message: 'Functionality may be buggy, HBO has a horrible design.',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
condition: () => getPlayerSource() === PLAYER_SOURCE.PEACOCK,
|
|
||||||
message: 'Functionality may be buggy, support on this site is in testing.',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
export default class Chat extends Component {
|
export default class Chat extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
@@ -95,6 +84,8 @@ export default class Chat extends Component {
|
|||||||
messages: [],
|
messages: [],
|
||||||
newMessage: '',
|
newMessage: '',
|
||||||
admin: null,
|
admin: null,
|
||||||
|
adminOnly: false,
|
||||||
|
adminModeUpdate: false,
|
||||||
users: [],
|
users: [],
|
||||||
usersOnCall: {},
|
usersOnCall: {},
|
||||||
gif: false,
|
gif: false,
|
||||||
@@ -107,6 +98,9 @@ export default class Chat extends Component {
|
|||||||
isFullscreen: document.fullscreen,
|
isFullscreen: document.fullscreen,
|
||||||
allowAutoRejoin:
|
allowAutoRejoin:
|
||||||
LocalData().allowAutoRejoin !== undefined ? LocalData().allowAutoRejoin : true,
|
LocalData().allowAutoRejoin !== undefined ? LocalData().allowAutoRejoin : true,
|
||||||
|
replyTo: null,
|
||||||
|
sendingMessages: [],
|
||||||
|
volumes: {},
|
||||||
};
|
};
|
||||||
this.port = null;
|
this.port = null;
|
||||||
this.gifClick = this.gifClick.bind(this);
|
this.gifClick = this.gifClick.bind(this);
|
||||||
@@ -115,9 +109,11 @@ export default class Chat extends Component {
|
|||||||
this.leaveParty = this.leaveParty.bind(this);
|
this.leaveParty = this.leaveParty.bind(this);
|
||||||
this.shareParty = this.shareParty.bind(this);
|
this.shareParty = this.shareParty.bind(this);
|
||||||
this.syncPlayer = this.syncPlayer.bind(this);
|
this.syncPlayer = this.syncPlayer.bind(this);
|
||||||
|
this.setReplyTo = this.setReplyTo.bind(this);
|
||||||
this.sendMessage = this.sendMessage.bind(this);
|
this.sendMessage = this.sendMessage.bind(this);
|
||||||
this.getCarousel = this.getCarousel.bind(this);
|
this.updateAdminOnly = this.updateAdminOnly.bind(this);
|
||||||
this.handlePhoneCall = this.handlePhoneCall.bind(this);
|
this.handlePhoneCall = this.handlePhoneCall.bind(this);
|
||||||
|
this.getReplyToContent = this.getReplyToContent.bind(this);
|
||||||
this.callEventListener = this.callEventListener.bind(this);
|
this.callEventListener = this.callEventListener.bind(this);
|
||||||
this.sendMessageInvoker = this.sendMessageInvoker.bind(this);
|
this.sendMessageInvoker = this.sendMessageInvoker.bind(this);
|
||||||
this.videoEventListener = this.videoEventListener.bind(this);
|
this.videoEventListener = this.videoEventListener.bind(this);
|
||||||
@@ -167,6 +163,7 @@ export default class Chat extends Component {
|
|||||||
this.port.postMessage({
|
this.port.postMessage({
|
||||||
type: 'INIT',
|
type: 'INIT',
|
||||||
roomId: LocalData().partyName,
|
roomId: LocalData().partyName,
|
||||||
|
roomPin: LocalData().partyPin,
|
||||||
});
|
});
|
||||||
// Listener
|
// Listener
|
||||||
this.port.onMessage.addListener((response) => {
|
this.port.onMessage.addListener((response) => {
|
||||||
@@ -175,22 +172,38 @@ export default class Chat extends Component {
|
|||||||
goTo(Create, this.props);
|
goTo(Create, this.props);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (response.messages) {
|
||||||
|
scrollThread();
|
||||||
|
}
|
||||||
|
|
||||||
// IF CHAT IS HIDDEN AND ALLOWS NOTIFICATION
|
// IF CHAT IS HIDDEN AND ALLOWS NOTIFICATION
|
||||||
if (!document.querySelector('body.visible') && this.state.allowChatNotification === true) {
|
if (!document.querySelector('body.visible') && this.state.allowChatNotification === true) {
|
||||||
if (response.messages && response.messages.length !== this.state.messages.length) {
|
if (response.messages && response.messages.length !== this.state.messages.length) {
|
||||||
const lastMessage = response.messages[response.messages.length - 1];
|
const lastMessage = response.messages[response.messages.length - 1];
|
||||||
var notificationMessage = '';
|
if (lastMessage.uid !== '<system>') {
|
||||||
if (lastMessage.uid !== '<system>') notificationMessage += lastMessage.name + ': ';
|
this.props.notify(
|
||||||
notificationMessage += lastMessage.text;
|
`${lastMessage.name}${
|
||||||
this.props.notify(notificationMessage);
|
lastMessage.type === 'giphy' ? ' sent a gif.' : ': ' + lastMessage.text
|
||||||
|
}`
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// ADMIN MODE UPDATE COMPLETE
|
||||||
|
if (response.adminOnly !== this.state.adminOnly) {
|
||||||
|
this.setState({ adminModeUpdate: false });
|
||||||
|
}
|
||||||
this.setState(response);
|
this.setState(response);
|
||||||
if (response.player) this.mVideoListener.doUpdate(response.player);
|
if (response.player) this.mVideoListener.doUpdate(response.player);
|
||||||
const pcc = document.querySelector('.thread-container');
|
|
||||||
if (pcc) pcc.scrollTop = pcc.scrollHeight;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 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');
|
||||||
|
giphyInjectScript.text = giphyInject;
|
||||||
|
document.head.appendChild(giphyInjectScript);
|
||||||
|
|
||||||
// DONE WITH MOUNTING TASKS
|
// DONE WITH MOUNTING TASKS
|
||||||
this.props.updateLoading(false);
|
this.props.updateLoading(false);
|
||||||
}
|
}
|
||||||
@@ -199,7 +212,10 @@ export default class Chat extends Component {
|
|||||||
this.leaveParty();
|
this.leaveParty();
|
||||||
}
|
}
|
||||||
videoEventListener(video) {
|
videoEventListener(video) {
|
||||||
this.syncPlayer(video);
|
const { adminOnly, admin } = this.state;
|
||||||
|
if (!adminOnly || (adminOnly && admin)) {
|
||||||
|
this.syncPlayer(video);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
callEventListener(event) {
|
callEventListener(event) {
|
||||||
this.setState(event);
|
this.setState(event);
|
||||||
@@ -234,10 +250,18 @@ export default class Chat extends Component {
|
|||||||
const data = {
|
const data = {
|
||||||
partyName: LocalData().partyName,
|
partyName: LocalData().partyName,
|
||||||
};
|
};
|
||||||
|
if (this.state.onCall)
|
||||||
|
this.mCallManager.toggleCall(
|
||||||
|
this.state.onCall,
|
||||||
|
this.state.conference,
|
||||||
|
this.state.admin,
|
||||||
|
this.state.adminOnly
|
||||||
|
);
|
||||||
DeleteRoomApi(data)
|
DeleteRoomApi(data)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
this.props.notify('Ended party');
|
this.props.notify('Ended party');
|
||||||
emptyLocalData();
|
removeLocalData('partyPin');
|
||||||
|
removeLocalData('partyName');
|
||||||
goTo(Create, this.props);
|
goTo(Create, this.props);
|
||||||
this.props.updateLoading(false);
|
this.props.updateLoading(false);
|
||||||
})
|
})
|
||||||
@@ -254,10 +278,18 @@ export default class Chat extends Component {
|
|||||||
partyName: LocalData().partyName,
|
partyName: LocalData().partyName,
|
||||||
userUid: LocalData().userUid,
|
userUid: LocalData().userUid,
|
||||||
};
|
};
|
||||||
|
if (this.state.onCall)
|
||||||
|
this.mCallManager.toggleCall(
|
||||||
|
this.state.onCall,
|
||||||
|
this.state.conference,
|
||||||
|
this.state.admin,
|
||||||
|
this.state.adminOnly
|
||||||
|
);
|
||||||
LeaveRoomApi(data)
|
LeaveRoomApi(data)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
this.props.notify('Left party');
|
this.props.notify('Left party');
|
||||||
emptyLocalData();
|
removeLocalData('partyPin');
|
||||||
|
removeLocalData('partyName');
|
||||||
goTo(Create, this.props);
|
goTo(Create, this.props);
|
||||||
this.props.updateLoading(false);
|
this.props.updateLoading(false);
|
||||||
})
|
})
|
||||||
@@ -279,7 +311,9 @@ export default class Chat extends Component {
|
|||||||
this.props.notify('Copied party invitation');
|
this.props.notify('Copied party invitation');
|
||||||
}
|
}
|
||||||
sendMessage(message) {
|
sendMessage(message) {
|
||||||
|
const { sendingMessages } = this.state;
|
||||||
const data = {
|
const data = {
|
||||||
|
id: `sending-${sendingMessages.length}`,
|
||||||
roomId: LocalData().partyName,
|
roomId: LocalData().partyName,
|
||||||
name: LocalData().userName,
|
name: LocalData().userName,
|
||||||
uid: LocalData().userUid,
|
uid: LocalData().userUid,
|
||||||
@@ -288,10 +322,30 @@ export default class Chat extends Component {
|
|||||||
type: '',
|
type: '',
|
||||||
};
|
};
|
||||||
if (this.state.gif === true) data.type = 'giphy';
|
if (this.state.gif === true) data.type = 'giphy';
|
||||||
SendMessageApi(data).catch((err) => {
|
if (this.state.replyTo !== null) data.replyTo = this.state.replyTo.id;
|
||||||
this.props.notify(err.message || err.statusText);
|
sendingMessages.push(data);
|
||||||
console.error('Send Message API error', err);
|
this.setState({
|
||||||
|
sendingMessages,
|
||||||
});
|
});
|
||||||
|
SendMessageApi(data)
|
||||||
|
.then(() => {
|
||||||
|
const { sendingMessages: sm } = this.state;
|
||||||
|
const rmi = sm.indexOf(data);
|
||||||
|
sm.splice(rmi, 1);
|
||||||
|
this.setState({ sendingMessages: sm });
|
||||||
|
scrollThread();
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
const { sendingMessages: sm } = this.state;
|
||||||
|
const rmi = sm.indexOf(data);
|
||||||
|
sm.splice(rmi, 1);
|
||||||
|
this.setState({ sendingMessages: sm });
|
||||||
|
scrollThread();
|
||||||
|
this.props.notify(err.message || err.statusText);
|
||||||
|
console.error('Send Message API error', err);
|
||||||
|
});
|
||||||
|
this.setState({ replyTo: null });
|
||||||
|
scrollThread();
|
||||||
}
|
}
|
||||||
sendMessageInvoker(overrideMessage) {
|
sendMessageInvoker(overrideMessage) {
|
||||||
if (overrideMessage) this.sendMessage(overrideMessage);
|
if (overrideMessage) this.sendMessage(overrideMessage);
|
||||||
@@ -301,17 +355,11 @@ export default class Chat extends Component {
|
|||||||
}
|
}
|
||||||
this.setState({ newMessage: '' });
|
this.setState({ newMessage: '' });
|
||||||
}
|
}
|
||||||
gifClick(iGif, ev) {
|
gifClick(iGif) {
|
||||||
ev.preventDefault();
|
|
||||||
this.sendMessageInvoker(iGif.images.original.url);
|
this.sendMessageInvoker(iGif.images.original.url);
|
||||||
}
|
}
|
||||||
getCarousel(offset) {
|
|
||||||
return this.state.newMessage === ''
|
|
||||||
? giphyFetch.trending({ offset, limit: 1 })
|
|
||||||
: giphyFetch.search(this.state.newMessage, { offset, limit: 1 });
|
|
||||||
}
|
|
||||||
handlePhoneCall() {
|
handlePhoneCall() {
|
||||||
const { onCall, conference, admin } = this.state;
|
const { onCall, conference, admin, adminOnly } = this.state;
|
||||||
if (window.navigator && onCall === false) {
|
if (window.navigator && onCall === false) {
|
||||||
try {
|
try {
|
||||||
const overlay = document.createElement('div');
|
const overlay = document.createElement('div');
|
||||||
@@ -327,7 +375,7 @@ export default class Chat extends Component {
|
|||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
document.getElementById('mic-permission-overlay').remove();
|
document.getElementById('mic-permission-overlay').remove();
|
||||||
this.mCallManager.toggleCall(onCall, conference, admin);
|
this.mCallManager.toggleCall(onCall, conference, admin, adminOnly);
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
document.getElementById('mic-permission-overlay').remove();
|
document.getElementById('mic-permission-overlay').remove();
|
||||||
@@ -336,9 +384,9 @@ export default class Chat extends Component {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(err);
|
console.error('Handle Phone Call Error', err);
|
||||||
}
|
}
|
||||||
} else this.mCallManager.toggleCall(onCall, conference, admin);
|
} else this.mCallManager.toggleCall(onCall, conference, admin, adminOnly);
|
||||||
}
|
}
|
||||||
handleMute() {
|
handleMute() {
|
||||||
this.mCallManager.toggleMute(this.state.muted);
|
this.mCallManager.toggleMute(this.state.muted);
|
||||||
@@ -363,6 +411,49 @@ export default class Chat extends Component {
|
|||||||
document.documentElement.requestFullscreen();
|
document.documentElement.requestFullscreen();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
updateAdminOnly() {
|
||||||
|
this.setState({ adminModeUpdate: true });
|
||||||
|
UpdateAdminOnly({
|
||||||
|
partyName: this.state.name,
|
||||||
|
adminOnly: !this.state.adminOnly,
|
||||||
|
}).catch((err) => {
|
||||||
|
this.props.notify(err.message || err.statusText);
|
||||||
|
console.error('Update Admin Only API error', err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
setReplyTo(message) {
|
||||||
|
this.setState({
|
||||||
|
replyTo: message,
|
||||||
|
});
|
||||||
|
scrollThread();
|
||||||
|
}
|
||||||
|
getReplyToContent() {
|
||||||
|
const { replyTo } = this.state;
|
||||||
|
if (replyTo) {
|
||||||
|
if (replyTo.type === 'giphy') {
|
||||||
|
return <img alt="gif" src={replyTo.text} />;
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<Typography variant="body2" gutterBottom>
|
||||||
|
{replyTo.text}
|
||||||
|
</Typography>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
setVideoVolume(v, id) {
|
||||||
|
const audioOuts = document.querySelectorAll('audio.vxt-audio');
|
||||||
|
if (audioOuts.length > 0) {
|
||||||
|
audioOuts.forEach((el) => {
|
||||||
|
if (el.id === `audio-${id}`) {
|
||||||
|
el.volume = v * 0.1;
|
||||||
|
const { volumes } = this.state;
|
||||||
|
volumes[id] = v;
|
||||||
|
this.setState({ volumes });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
admin,
|
admin,
|
||||||
@@ -379,7 +470,31 @@ export default class Chat extends Component {
|
|||||||
allowAutoRejoin,
|
allowAutoRejoin,
|
||||||
usersOnCall,
|
usersOnCall,
|
||||||
isFullscreen,
|
isFullscreen,
|
||||||
|
adminModeUpdate,
|
||||||
|
adminOnly,
|
||||||
|
replyTo,
|
||||||
|
sendingMessages,
|
||||||
|
volumes,
|
||||||
} = this.state;
|
} = this.state;
|
||||||
|
const alerts = [
|
||||||
|
{
|
||||||
|
condition: () =>
|
||||||
|
getPlayerSource() === PLAYER_SOURCE.HBOMAX || getPlayerSource() === PLAYER_SOURCE.HBONOW,
|
||||||
|
message: 'Functionality may be buggy, HBO has a horrible design.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
condition: () => getPlayerSource() === PLAYER_SOURCE.GOOGLEPLAY,
|
||||||
|
message: 'Functionality may be buggy, support on this site is in testing.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
condition: () => getPlayerSource() === PLAYER_SOURCE.CRUNCHYROLL,
|
||||||
|
message: 'Functionality may be buggy, support on this site is in testing.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
condition: () => adminOnly,
|
||||||
|
message: 'Party is currently in admin only mode.',
|
||||||
|
},
|
||||||
|
];
|
||||||
return (
|
return (
|
||||||
<div className="party-chat-container">
|
<div className="party-chat-container">
|
||||||
<div className="party-chat-header">
|
<div className="party-chat-header">
|
||||||
@@ -496,6 +611,32 @@ export default class Chat extends Component {
|
|||||||
}
|
}
|
||||||
labelPlacement="end"
|
labelPlacement="end"
|
||||||
/>
|
/>
|
||||||
|
{admin ? (
|
||||||
|
<FormControlLabel
|
||||||
|
className="notification-switch"
|
||||||
|
control={
|
||||||
|
<Switch
|
||||||
|
checked={adminOnly}
|
||||||
|
onChange={this.updateAdminOnly}
|
||||||
|
name="adminOnly"
|
||||||
|
color={adminOnly ? 'secondary' : 'primary'}
|
||||||
|
disabled={adminModeUpdate}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
label={
|
||||||
|
<span>
|
||||||
|
Admin Only Mode
|
||||||
|
<br />
|
||||||
|
<span style={{ color: '#8a8a8a' }}>
|
||||||
|
{adminOnly
|
||||||
|
? 'Only admin can update player and start calls right now'
|
||||||
|
: 'All party members can update player and start calls right now'}
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
}
|
||||||
|
labelPlacement="end"
|
||||||
|
/>
|
||||||
|
) : null}
|
||||||
<Typography className="party-controls-users-title" variant="overline">
|
<Typography className="party-controls-users-title" variant="overline">
|
||||||
PARTY MEMBERS
|
PARTY MEMBERS
|
||||||
</Typography>
|
</Typography>
|
||||||
@@ -514,17 +655,41 @@ export default class Chat extends Component {
|
|||||||
{Object.keys(usersOnCall).map((id) => {
|
{Object.keys(usersOnCall).map((id) => {
|
||||||
return usersOnCall[id].status === 'Connected' ||
|
return usersOnCall[id].status === 'Connected' ||
|
||||||
usersOnCall[id].status === 'Connecting' ? (
|
usersOnCall[id].status === 'Connecting' ? (
|
||||||
<Chip
|
<Tooltip
|
||||||
color={
|
interactive
|
||||||
usersOnCall[id].info.externalId === LocalData().userUid
|
title={
|
||||||
? 'secondary'
|
<Grid className="party-controls-users-volume" container spacing={2}>
|
||||||
: 'default'
|
<Grid item>
|
||||||
|
<VolumeDown />
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs>
|
||||||
|
<Slider
|
||||||
|
max={10}
|
||||||
|
min={0}
|
||||||
|
step={1}
|
||||||
|
color="secondary"
|
||||||
|
value={volumes[id] || 10}
|
||||||
|
onChangeCommitted={(e, v) => this.setVideoVolume(v, id)}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
<Grid item>
|
||||||
|
<VolumeUp />
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
}
|
}
|
||||||
className="party-controls-users-chip"
|
>
|
||||||
clickable
|
<Chip
|
||||||
size="small"
|
color={
|
||||||
label={usersOnCall[id].info.name || ' '}
|
usersOnCall[id].info.externalId === LocalData().userUid
|
||||||
/>
|
? 'secondary'
|
||||||
|
: 'default'
|
||||||
|
}
|
||||||
|
className="party-controls-users-chip"
|
||||||
|
clickable
|
||||||
|
size="small"
|
||||||
|
label={usersOnCall[id].info.name || ' '}
|
||||||
|
/>
|
||||||
|
</Tooltip>
|
||||||
) : null;
|
) : null;
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
@@ -570,7 +735,7 @@ export default class Chat extends Component {
|
|||||||
</Card>
|
</Card>
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
<div className="thread-container">
|
<div className="thread-wrapper">
|
||||||
<div className="alerts-container">
|
<div className="alerts-container">
|
||||||
{alerts.map((a) => {
|
{alerts.map((a) => {
|
||||||
if (a.condition() === true) {
|
if (a.condition() === true) {
|
||||||
@@ -585,8 +750,27 @@ export default class Chat extends Component {
|
|||||||
} else return null;
|
} else return null;
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
<Thread messages={messages} />
|
<Thread
|
||||||
|
setReplyTo={this.setReplyTo}
|
||||||
|
sendingMessages={sendingMessages}
|
||||||
|
sentMessages={messages}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<Paper
|
||||||
|
square
|
||||||
|
variant="outlined"
|
||||||
|
className={`replying-to-card ${replyTo !== null ? 'replying-to-card-up' : ''}`}
|
||||||
|
>
|
||||||
|
<div className="replying-to-content">
|
||||||
|
<Typography variant="overline" display="block" gutterBottom>
|
||||||
|
REPLYING TO
|
||||||
|
</Typography>
|
||||||
|
{this.getReplyToContent()}
|
||||||
|
</div>
|
||||||
|
<IconButton onClick={() => this.setReplyTo(null)}>
|
||||||
|
<CancelRounded />
|
||||||
|
</IconButton>
|
||||||
|
</Paper>
|
||||||
<div className="text-phone-panel">
|
<div className="text-phone-panel">
|
||||||
{gif || newMessage ? null : (
|
{gif || newMessage ? null : (
|
||||||
<Tooltip title="Fullscreen with Watch Party" aria-label="Fullscreen">
|
<Tooltip title="Fullscreen with Watch Party" aria-label="Fullscreen">
|
||||||
@@ -656,9 +840,13 @@ export default class Chat extends Component {
|
|||||||
value={newMessage}
|
value={newMessage}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
this.setState({ newMessage: e.target.value });
|
this.setState({ newMessage: e.target.value });
|
||||||
if (this.state.gif) {
|
scrollThread();
|
||||||
const carousel = document.querySelector('.giphy-carousel');
|
if (gif) {
|
||||||
setTimeout(() => carousel.scroll(carousel.scrollWidth, carousel.scrollHeight), 250);
|
window.postMessage({
|
||||||
|
watchPartyDirection: 'TO_SCRIPT',
|
||||||
|
type: 'WATCH_PARTY_SEARCH_GIF',
|
||||||
|
value: e.target.value,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
InputProps={{
|
InputProps={{
|
||||||
@@ -681,7 +869,17 @@ export default class Chat extends Component {
|
|||||||
<InputAdornment position="start">
|
<InputAdornment position="start">
|
||||||
<IconButton
|
<IconButton
|
||||||
className={`gif-button ${this.state.gif ? 'gif-close' : ''}`}
|
className={`gif-button ${this.state.gif ? 'gif-close' : ''}`}
|
||||||
onClick={() => this.setState({ gif: !gif })}
|
onClick={() => {
|
||||||
|
this.setState({ gif: !gif });
|
||||||
|
if (!gif) {
|
||||||
|
window.postMessage({
|
||||||
|
watchPartyDirection: 'TO_SCRIPT',
|
||||||
|
type: 'WATCH_PARTY_SEARCH_GIF',
|
||||||
|
value: newMessage,
|
||||||
|
});
|
||||||
|
scrollThread();
|
||||||
|
}
|
||||||
|
}}
|
||||||
edge="start"
|
edge="start"
|
||||||
>
|
>
|
||||||
{gif ? <Cancel /> : <Gif />}
|
{gif ? <Cancel /> : <Gif />}
|
||||||
@@ -691,15 +889,16 @@ export default class Chat extends Component {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{gif ? (
|
<ReactGiphySearchbox
|
||||||
<Carousel
|
apiKey="ojJbIMUN6XRMn4mHiFFav3rMCpXUg8sq"
|
||||||
fetchGifs={this.getCarousel}
|
onSelect={this.gifClick}
|
||||||
gifHeight={200}
|
masonryConfig={[{ columns: 2, imageWidth: '50%', gutter: 5 }]}
|
||||||
gutter={6}
|
searchFormClassName="giphy-search-form"
|
||||||
onGifClick={this.gifClick}
|
wrapperClassName={`giphy-wrapper ${gif ? '' : 'giphy-wrapper-down'}`}
|
||||||
hideAttribution
|
listWrapperClassName="giphy-list-wrapper"
|
||||||
/>
|
listItemClassName="giphy-list-item"
|
||||||
) : null}
|
poweredByGiphy
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,95 +0,0 @@
|
|||||||
/************************************************************************
|
|
||||||
Copyright (C) Ayushya Amitabh - All Rights Reserved
|
|
||||||
Unauthorized copying of this file, via any medium is strictly prohibited
|
|
||||||
Proprietary and confidential
|
|
||||||
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
|
||||||
https://www.chromewatchparty.com/copyright
|
|
||||||
=========================================================================
|
|
||||||
ALL CONTENT ON IN WATCH PARTY'S CHROME EXTENSION APP, UNLESS OTHERWISE
|
|
||||||
CITED ARE THE SOLE INTELECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE
|
|
||||||
COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
|
|
||||||
|
|
||||||
Netflix logo is a trademark and intellectual property of Netflix, Inc.
|
|
||||||
Disney+ logo is a trademark and intellectual property of The Walt Disney Company
|
|
||||||
Prime logo is a trademark and intellectual property of Amazon.com, Inc.
|
|
||||||
YouTube logo is a trademark and intellectual property of Google, Inc.
|
|
||||||
Hulu logo is a trademark and intellectual property of Hulu, LLC.
|
|
||||||
HBO Now and HBO Max logos are trademark and intellectual property of WarnerMedia Direct,LLC.
|
|
||||||
************************************************************************/
|
|
||||||
|
|
||||||
/************************************************************************
|
|
||||||
THE CODE BELOW WAS WRITTEN BY USER
|
|
||||||
https://stackoverflow.com/users/68808/tweezz
|
|
||||||
ON STACKOVERFLOW, WHICH CAN BE FOUND AT
|
|
||||||
https://stackoverflow.com/questions/6157929/how-to-simulate-a-mouse-click-using-javascript
|
|
||||||
************************************************************************/
|
|
||||||
|
|
||||||
export default function simulate(element, eventName) {
|
|
||||||
var options = extend(defaultOptions, arguments[2] || {});
|
|
||||||
var oEvent,
|
|
||||||
eventType = null;
|
|
||||||
|
|
||||||
for (var name in eventMatchers) {
|
|
||||||
if (eventMatchers[name].test(eventName)) {
|
|
||||||
eventType = name;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!eventType) throw new SyntaxError('Only HTMLEvents and MouseEvents interfaces are supported');
|
|
||||||
|
|
||||||
if (document.createEvent) {
|
|
||||||
oEvent = document.createEvent(eventType);
|
|
||||||
if (eventType == 'HTMLEvents') {
|
|
||||||
oEvent.initEvent(eventName, options.bubbles, options.cancelable);
|
|
||||||
} else {
|
|
||||||
oEvent.initMouseEvent(
|
|
||||||
eventName,
|
|
||||||
options.bubbles,
|
|
||||||
options.cancelable,
|
|
||||||
document.defaultView,
|
|
||||||
options.button,
|
|
||||||
options.pointerX,
|
|
||||||
options.pointerY,
|
|
||||||
options.pointerX,
|
|
||||||
options.pointerY,
|
|
||||||
options.ctrlKey,
|
|
||||||
options.altKey,
|
|
||||||
options.shiftKey,
|
|
||||||
options.metaKey,
|
|
||||||
options.button,
|
|
||||||
element
|
|
||||||
);
|
|
||||||
}
|
|
||||||
element.dispatchEvent(oEvent);
|
|
||||||
} else {
|
|
||||||
options.clientX = options.pointerX;
|
|
||||||
options.clientY = options.pointerY;
|
|
||||||
var evt = document.createEventObject();
|
|
||||||
oEvent = extend(evt, options);
|
|
||||||
element.fireEvent('on' + eventName, oEvent);
|
|
||||||
}
|
|
||||||
return element;
|
|
||||||
}
|
|
||||||
|
|
||||||
function extend(destination, source) {
|
|
||||||
for (var property in source) destination[property] = source[property];
|
|
||||||
return destination;
|
|
||||||
}
|
|
||||||
|
|
||||||
const eventMatchers = {
|
|
||||||
HTMLEvents: /^(?:load|unload|abort|error|select|change|submit|reset|focus|blur|resize|scroll)$/,
|
|
||||||
MouseEvents: /^(?:click|dblclick|mouse(?:down|up|over|move|out))$/,
|
|
||||||
};
|
|
||||||
|
|
||||||
const defaultOptions = {
|
|
||||||
pointerX: 0,
|
|
||||||
pointerY: 0,
|
|
||||||
button: 0,
|
|
||||||
ctrlKey: false,
|
|
||||||
altKey: false,
|
|
||||||
shiftKey: false,
|
|
||||||
metaKey: false,
|
|
||||||
bubbles: true,
|
|
||||||
cancelable: true,
|
|
||||||
};
|
|
||||||
@@ -5,19 +5,29 @@ Proprietary and confidential
|
|||||||
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
||||||
https://www.chromewatchparty.com/copyright
|
https://www.chromewatchparty.com/copyright
|
||||||
=========================================================================
|
=========================================================================
|
||||||
ALL CONTENT ON IN WATCH PARTY'S CHROME EXTENSION APP, UNLESS OTHERWISE
|
ALL CONTENT ON WATCH PARTY'S WEBSITE OR IN WATCH PARTY'S CHROME EXTENSION APP, UNLESS OTHERWISE
|
||||||
CITED ARE THE SOLE INTELECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE
|
CITED ARE THE SOLE INTELECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE
|
||||||
COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
|
COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
|
||||||
|
|
||||||
Netflix logo is a trademark and intellectual property of Netflix, Inc.
|
|
||||||
Disney+ logo is a trademark and intellectual property of The Walt Disney Company
|
|
||||||
Prime logo is a trademark and intellectual property of Amazon.com, Inc.
|
|
||||||
YouTube logo is a trademark and intellectual property of Google, Inc.
|
|
||||||
Hulu logo is a trademark and intellectual property of Hulu, LLC.
|
|
||||||
HBO Now and HBO Max logos are trademark and intellectual property of WarnerMedia Direct,LLC.
|
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
|
/*global chrome */
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import { Button, TextField, Typography, Paper, ButtonGroup } from '@material-ui/core';
|
import {
|
||||||
|
Button,
|
||||||
|
FormControlLabel,
|
||||||
|
Switch,
|
||||||
|
TextField,
|
||||||
|
Typography,
|
||||||
|
Paper,
|
||||||
|
ButtonGroup,
|
||||||
|
ExpansionPanel,
|
||||||
|
ExpansionPanelSummary,
|
||||||
|
ExpansionPanelDetails,
|
||||||
|
MobileStepper,
|
||||||
|
IconButton,
|
||||||
|
Card,
|
||||||
|
CardContent,
|
||||||
|
CardActions,
|
||||||
|
} from '@material-ui/core';
|
||||||
import {
|
import {
|
||||||
JoinRoomApi,
|
JoinRoomApi,
|
||||||
CreateRoomApi,
|
CreateRoomApi,
|
||||||
@@ -26,6 +36,7 @@ import {
|
|||||||
LocalData,
|
LocalData,
|
||||||
updateLocalData,
|
updateLocalData,
|
||||||
getUserUid,
|
getUserUid,
|
||||||
|
emptyLocalData,
|
||||||
} from './Api';
|
} from './Api';
|
||||||
import { goTo } from 'route-lite';
|
import { goTo } from 'route-lite';
|
||||||
import Chat from './Chat';
|
import Chat from './Chat';
|
||||||
@@ -34,7 +45,13 @@ import {
|
|||||||
InfoRounded,
|
InfoRounded,
|
||||||
MonetizationOnRounded,
|
MonetizationOnRounded,
|
||||||
RateReviewRounded,
|
RateReviewRounded,
|
||||||
|
Settings,
|
||||||
|
ExpandLess,
|
||||||
|
KeyboardArrowLeft,
|
||||||
|
KeyboardArrowRight,
|
||||||
|
Notifications,
|
||||||
} from '@material-ui/icons';
|
} from '@material-ui/icons';
|
||||||
|
import { Autocomplete } from '@material-ui/lab';
|
||||||
|
|
||||||
const CONSTANTS = {
|
const CONSTANTS = {
|
||||||
USER_NAME_LENGTH: 12,
|
USER_NAME_LENGTH: 12,
|
||||||
@@ -50,10 +67,26 @@ export default class Create extends Component {
|
|||||||
name: LocalData().partyName || '',
|
name: LocalData().partyName || '',
|
||||||
pin: LocalData().partyPin || '',
|
pin: LocalData().partyPin || '',
|
||||||
mode: defaultMode,
|
mode: defaultMode,
|
||||||
|
parties: [],
|
||||||
|
adminOnly: false,
|
||||||
|
alertStep:
|
||||||
|
this.props.status && this.props.status.importantAlert
|
||||||
|
? this.props.status.importantAlert
|
||||||
|
: 0,
|
||||||
|
allowAutoRejoin:
|
||||||
|
LocalData().allowAutoRejoin !== undefined ? LocalData().allowAutoRejoin : true,
|
||||||
|
allowChatNotification:
|
||||||
|
LocalData().allowChatNotification !== undefined ? LocalData().allowChatNotification : true,
|
||||||
|
expanded: 'alerts',
|
||||||
};
|
};
|
||||||
this.createCall = this.createCall.bind(this);
|
this.createCall = this.createCall.bind(this);
|
||||||
this.joinCall = this.joinCall.bind(this);
|
this.joinCall = this.joinCall.bind(this);
|
||||||
this.success = this.success.bind(this);
|
this.success = this.success.bind(this);
|
||||||
|
this.partyNameAutocompleteProcessor = this.partyNameAutocompleteProcessor.bind(this);
|
||||||
|
this.updateAllowAutoRejoin = this.updateAllowAutoRejoin.bind(this);
|
||||||
|
this.updateAllowChatNotification = this.updateAllowChatNotification.bind(this);
|
||||||
|
this.clearPartyHistory = this.clearPartyHistory.bind(this);
|
||||||
|
this.handleSteps = this.handleSteps.bind(this);
|
||||||
}
|
}
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
const { lastActive, userName, partyName, partyPin, allowAutoRejoin } = LocalData();
|
const { lastActive, userName, partyName, partyPin, allowAutoRejoin } = LocalData();
|
||||||
@@ -63,6 +96,14 @@ export default class Create extends Component {
|
|||||||
this.joinCall(userName, partyName, partyPin);
|
this.joinCall(userName, partyName, partyPin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
chrome.runtime.sendMessage(
|
||||||
|
{
|
||||||
|
type: 'GET_PARTIES',
|
||||||
|
},
|
||||||
|
(response) => {
|
||||||
|
this.setState({ parties: response });
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
partyNameChange(value) {
|
partyNameChange(value) {
|
||||||
if (value.length <= CONSTANTS.NAME_LENGTH) this.setState({ name: value });
|
if (value.length <= CONSTANTS.NAME_LENGTH) this.setState({ name: value });
|
||||||
@@ -121,6 +162,7 @@ export default class Create extends Component {
|
|||||||
time: 0,
|
time: 0,
|
||||||
url: window.location.href,
|
url: window.location.href,
|
||||||
},
|
},
|
||||||
|
adminOnly: this.state.adminOnly,
|
||||||
};
|
};
|
||||||
CreateRoomApi(apidata)
|
CreateRoomApi(apidata)
|
||||||
.then((res) => res.json())
|
.then((res) => res.json())
|
||||||
@@ -157,6 +199,7 @@ export default class Create extends Component {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
|
emptyLocalData();
|
||||||
console.error('Join Party API Error', err);
|
console.error('Join Party API Error', err);
|
||||||
this.props.notify(err.message || 'Something went wrong');
|
this.props.notify(err.message || 'Something went wrong');
|
||||||
this.props.updateLoading(false);
|
this.props.updateLoading(false);
|
||||||
@@ -167,8 +210,58 @@ export default class Create extends Component {
|
|||||||
this.props.updateLoading(false);
|
this.props.updateLoading(false);
|
||||||
goTo(Chat, this.props);
|
goTo(Chat, this.props);
|
||||||
}
|
}
|
||||||
|
partyNameAutocompleteProcessor(v) {
|
||||||
|
if (v !== null && v !== undefined && typeof v === 'object') {
|
||||||
|
if (v.name) this.partyNameChange(v.name);
|
||||||
|
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') {
|
||||||
|
this.partyNameChange(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
updateAllowChatNotification() {
|
||||||
|
updateLocalData({ allowChatNotification: !this.state.allowChatNotification });
|
||||||
|
this.setState({ allowChatNotification: !this.state.allowChatNotification });
|
||||||
|
}
|
||||||
|
updateAllowAutoRejoin() {
|
||||||
|
updateLocalData({ allowAutoRejoin: !this.state.allowAutoRejoin });
|
||||||
|
this.setState({ allowAutoRejoin: !this.state.allowAutoRejoin });
|
||||||
|
}
|
||||||
|
clearPartyHistory() {
|
||||||
|
this.setState({
|
||||||
|
parties: [],
|
||||||
|
});
|
||||||
|
chrome.runtime.sendMessage({ type: 'EMPTY_PARTIES' });
|
||||||
|
}
|
||||||
|
handleSteps(direction) {
|
||||||
|
const { alertStep } = this.state;
|
||||||
|
if (alertStep + direction < 0) return;
|
||||||
|
if (alertStep + direction >= this.props.status.alerts.length) return;
|
||||||
|
this.setState({ alertStep: alertStep + direction });
|
||||||
|
}
|
||||||
|
handleExpanders(e) {
|
||||||
|
const { expanded } = this.state;
|
||||||
|
if (e === expanded) this.setState({ expanded: '' });
|
||||||
|
else this.setState({ expanded: e });
|
||||||
|
}
|
||||||
render() {
|
render() {
|
||||||
const { mode, name, pin, userName } = this.state;
|
const {
|
||||||
|
mode,
|
||||||
|
name,
|
||||||
|
pin,
|
||||||
|
userName,
|
||||||
|
parties,
|
||||||
|
adminOnly,
|
||||||
|
allowAutoRejoin,
|
||||||
|
allowChatNotification,
|
||||||
|
alertStep,
|
||||||
|
expanded,
|
||||||
|
} = this.state;
|
||||||
|
const { status } = this.props;
|
||||||
return (
|
return (
|
||||||
<div className="party-create-container">
|
<div className="party-create-container">
|
||||||
<Typography
|
<Typography
|
||||||
@@ -213,15 +306,26 @@ export default class Create extends Component {
|
|||||||
userName ? `${userName.length}/${CONSTANTS.USER_NAME_LENGTH} Characters` : null
|
userName ? `${userName.length}/${CONSTANTS.USER_NAME_LENGTH} Characters` : null
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<TextField
|
<Autocomplete
|
||||||
color="secondary"
|
color="secondary"
|
||||||
size="small"
|
options={parties}
|
||||||
className="create-name addFocus"
|
getOptionLabel={(o) => o.name}
|
||||||
label="Party Name"
|
autoComplete
|
||||||
variant="outlined"
|
freeSolo
|
||||||
value={name}
|
value={{ name: name, pin: pin }}
|
||||||
onChange={(e) => this.partyNameChange(e.target.value)}
|
onInputChange={(e, v, r) => this.partyNameAutocompleteProcessor({ name: v, pin: pin })}
|
||||||
helperText={name ? `${name.length}/${CONSTANTS.NAME_LENGTH} Characters` : null}
|
onChange={(e, v) => this.partyNameAutocompleteProcessor(v)}
|
||||||
|
renderInput={(params) => (
|
||||||
|
<TextField
|
||||||
|
color="secondary"
|
||||||
|
size="small"
|
||||||
|
{...params}
|
||||||
|
className="create-name addFocus"
|
||||||
|
label="Party Name"
|
||||||
|
variant="outlined"
|
||||||
|
helperText={name ? `${name.length}/${CONSTANTS.NAME_LENGTH} Characters` : null}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
/>
|
/>
|
||||||
<TextField
|
<TextField
|
||||||
color="secondary"
|
color="secondary"
|
||||||
@@ -234,6 +338,31 @@ export default class Create extends Component {
|
|||||||
onChange={(e) => this.partyPinChange(e.target.value)}
|
onChange={(e) => this.partyPinChange(e.target.value)}
|
||||||
helperText={pin ? `${pin.length}/${CONSTANTS.PIN_LENGTH} Digits` : null}
|
helperText={pin ? `${pin.length}/${CONSTANTS.PIN_LENGTH} Digits` : null}
|
||||||
/>
|
/>
|
||||||
|
<FormControlLabel
|
||||||
|
className={`notification-switch admin-only-switch ${
|
||||||
|
mode !== 'create' ? 'admin-only-switch-hidden' : ''
|
||||||
|
}`}
|
||||||
|
control={
|
||||||
|
<Switch
|
||||||
|
checked={adminOnly}
|
||||||
|
onChange={() => this.setState({ adminOnly: !adminOnly })}
|
||||||
|
name="adminOnly"
|
||||||
|
color={adminOnly ? 'secondary' : 'primary'}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
label={
|
||||||
|
<span>
|
||||||
|
Admin Only Mode (can be changed later)
|
||||||
|
<br />
|
||||||
|
<span style={{ color: '#8a8a8a' }}>
|
||||||
|
{adminOnly
|
||||||
|
? 'Only admin will update currently playing and start calls'
|
||||||
|
: 'All members will update currently playing and start calls'}
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
}
|
||||||
|
labelPlacement="end"
|
||||||
|
/>
|
||||||
<Button
|
<Button
|
||||||
size="small"
|
size="small"
|
||||||
variant="contained"
|
variant="contained"
|
||||||
@@ -243,13 +372,133 @@ export default class Create extends Component {
|
|||||||
<span>{mode === 'create' ? 'Start Party' : 'Join Party'}</span> <ChevronRight />
|
<span>{mode === 'create' ? 'Start Party' : 'Join Party'}</span> <ChevronRight />
|
||||||
</Button>
|
</Button>
|
||||||
</Paper>
|
</Paper>
|
||||||
|
<ExpansionPanel expanded={expanded === 'alerts'} className="create-settings-card">
|
||||||
|
<ExpansionPanelSummary
|
||||||
|
onClick={() => this.handleExpanders('alerts')}
|
||||||
|
expandIcon={<ExpandLess />}
|
||||||
|
>
|
||||||
|
<Notifications />
|
||||||
|
<Typography className="create-settings-title" variant="button">
|
||||||
|
Alerts
|
||||||
|
</Typography>
|
||||||
|
</ExpansionPanelSummary>
|
||||||
|
<ExpansionPanelDetails>
|
||||||
|
{status ? (
|
||||||
|
<div className="alerts-stepper-container">
|
||||||
|
<Card className="alerts-stepper-card" elevation={10}>
|
||||||
|
<CardContent>
|
||||||
|
<Typography color="textSecondary" gutterBottom variant="overline">
|
||||||
|
{status.alerts[alertStep].title}
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="body2" component="p">
|
||||||
|
{status.alerts[alertStep].description}
|
||||||
|
</Typography>
|
||||||
|
</CardContent>
|
||||||
|
{status.alerts[alertStep].link && status.alerts[alertStep].linkText && (
|
||||||
|
<CardActions>
|
||||||
|
<Button href={status.alerts[alertStep].link} target="_blank" size="small">
|
||||||
|
{status.alerts[alertStep].linkText}
|
||||||
|
</Button>
|
||||||
|
</CardActions>
|
||||||
|
)}
|
||||||
|
</Card>
|
||||||
|
<MobileStepper
|
||||||
|
className="alerts-stepper-controls"
|
||||||
|
variant="dots"
|
||||||
|
color="secondary"
|
||||||
|
activeStep={alertStep}
|
||||||
|
backButton={
|
||||||
|
<IconButton disabled={alertStep === 0} onClick={() => this.handleSteps(-1)}>
|
||||||
|
<KeyboardArrowLeft />
|
||||||
|
</IconButton>
|
||||||
|
}
|
||||||
|
nextButton={
|
||||||
|
<IconButton
|
||||||
|
disabled={alertStep === status.alerts.length - 1}
|
||||||
|
onClick={() => this.handleSteps(1)}
|
||||||
|
>
|
||||||
|
<KeyboardArrowRight />
|
||||||
|
</IconButton>
|
||||||
|
}
|
||||||
|
steps={status.alerts ? status.alerts.length : 0}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<Typography color="textSecondary" gutterBottom variant="overline">
|
||||||
|
No alerts right now
|
||||||
|
</Typography>
|
||||||
|
)}
|
||||||
|
</ExpansionPanelDetails>
|
||||||
|
</ExpansionPanel>
|
||||||
|
<ExpansionPanel expanded={expanded === 'settings'} className="create-settings-card">
|
||||||
|
<ExpansionPanelSummary
|
||||||
|
onClick={() => this.handleExpanders('settings')}
|
||||||
|
expandIcon={<ExpandLess />}
|
||||||
|
>
|
||||||
|
<Settings />
|
||||||
|
<Typography className="create-settings-title" variant="button">
|
||||||
|
Settings
|
||||||
|
</Typography>
|
||||||
|
</ExpansionPanelSummary>
|
||||||
|
<ExpansionPanelDetails>
|
||||||
|
<FormControlLabel
|
||||||
|
className="notification-switch"
|
||||||
|
control={
|
||||||
|
<Switch
|
||||||
|
checked={allowChatNotification}
|
||||||
|
onChange={this.updateAllowChatNotification}
|
||||||
|
name="allowChatNotification"
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
label={
|
||||||
|
<span>
|
||||||
|
Allow chat notification when side panel is closed
|
||||||
|
<br />
|
||||||
|
<span style={{ color: '#8a8a8a' }}>
|
||||||
|
{allowChatNotification ? 'Notifications Enabled' : 'Notifications Disabled'}
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
}
|
||||||
|
labelPlacement="end"
|
||||||
|
/>
|
||||||
|
<FormControlLabel
|
||||||
|
className="notification-switch"
|
||||||
|
control={
|
||||||
|
<Switch
|
||||||
|
checked={allowAutoRejoin}
|
||||||
|
onChange={this.updateAllowAutoRejoin}
|
||||||
|
name="allowAutoRejoin"
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
label={
|
||||||
|
<span>
|
||||||
|
Allow Watch Party to auto rejoin (within 1 minute)
|
||||||
|
<br />
|
||||||
|
<span style={{ color: '#8a8a8a' }}>
|
||||||
|
{allowAutoRejoin ? 'Auto Rejoin Enabled' : 'Auto Rejoin Disabled'}
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
}
|
||||||
|
labelPlacement="end"
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
color="secondary"
|
||||||
|
fullWidth
|
||||||
|
variant="contained"
|
||||||
|
onClick={this.clearPartyHistory}
|
||||||
|
size="small"
|
||||||
|
>
|
||||||
|
CLEAR SAVED PARTY DETAILS
|
||||||
|
</Button>
|
||||||
|
</ExpansionPanelDetails>
|
||||||
|
</ExpansionPanel>
|
||||||
<Button
|
<Button
|
||||||
target="_blank"
|
target="_blank"
|
||||||
href={`http://www.chromewatchparty.com/changes/v${this.props.appVersion}`}
|
href={`http://www.chromewatchparty.com/changes/v${this.props.appVersion}`}
|
||||||
fullWidth
|
fullWidth
|
||||||
color="secondary"
|
color="secondary"
|
||||||
variant="outlined"
|
variant="contained"
|
||||||
size="large"
|
size="small"
|
||||||
className="whats-new-button"
|
className="whats-new-button"
|
||||||
>
|
>
|
||||||
See what's new in V{this.props.appVersion}
|
See what's new in V{this.props.appVersion}
|
||||||
|
|||||||
@@ -5,16 +5,9 @@ Proprietary and confidential
|
|||||||
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
||||||
https://www.chromewatchparty.com/copyright
|
https://www.chromewatchparty.com/copyright
|
||||||
=========================================================================
|
=========================================================================
|
||||||
ALL CONTENT ON IN WATCH PARTY'S CHROME EXTENSION APP, UNLESS OTHERWISE
|
ALL CONTENT ON WATCH PARTY'S WEBSITE OR IN WATCH PARTY'S CHROME EXTENSION APP, UNLESS OTHERWISE
|
||||||
CITED ARE THE SOLE INTELECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE
|
CITED ARE THE SOLE INTELECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE
|
||||||
COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
|
COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
|
||||||
|
|
||||||
Netflix logo is a trademark and intellectual property of Netflix, Inc.
|
|
||||||
Disney+ logo is a trademark and intellectual property of The Walt Disney Company
|
|
||||||
Prime logo is a trademark and intellectual property of Amazon.com, Inc.
|
|
||||||
YouTube logo is a trademark and intellectual property of Google, Inc.
|
|
||||||
Hulu logo is a trademark and intellectual property of Hulu, LLC.
|
|
||||||
HBO Now and HBO Max logos are trademark and intellectual property of WarnerMedia Direct,LLC.
|
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Typography } from '@material-ui/core';
|
import { Typography } from '@material-ui/core';
|
||||||
|
|||||||
@@ -5,23 +5,16 @@ Proprietary and confidential
|
|||||||
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
||||||
https://www.chromewatchparty.com/copyright
|
https://www.chromewatchparty.com/copyright
|
||||||
=========================================================================
|
=========================================================================
|
||||||
ALL CONTENT ON IN WATCH PARTY'S CHROME EXTENSION APP, UNLESS OTHERWISE
|
ALL CONTENT ON WATCH PARTY'S WEBSITE OR IN WATCH PARTY'S CHROME EXTENSION APP, UNLESS OTHERWISE
|
||||||
CITED ARE THE SOLE INTELECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE
|
CITED ARE THE SOLE INTELECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE
|
||||||
COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
|
COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
|
||||||
|
|
||||||
Netflix logo is a trademark and intellectual property of Netflix, Inc.
|
|
||||||
Disney+ logo is a trademark and intellectual property of The Walt Disney Company
|
|
||||||
Prime logo is a trademark and intellectual property of Amazon.com, Inc.
|
|
||||||
YouTube logo is a trademark and intellectual property of Google, Inc.
|
|
||||||
Hulu logo is a trademark and intellectual property of Hulu, LLC.
|
|
||||||
HBO Now and HBO Max logos are trademark and intellectual property of WarnerMedia Direct,LLC.
|
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { CircularProgress } from '@material-ui/core';
|
import { CircularProgress } from '@material-ui/core';
|
||||||
|
|
||||||
const Loading = () => (
|
const Loading = () => (
|
||||||
<div id="party-loading">
|
<div id="party-loading">
|
||||||
<CircularProgress />
|
<CircularProgress color="secondary" />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -5,106 +5,278 @@ Proprietary and confidential
|
|||||||
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
||||||
https://www.chromewatchparty.com/copyright
|
https://www.chromewatchparty.com/copyright
|
||||||
=========================================================================
|
=========================================================================
|
||||||
ALL CONTENT ON IN WATCH PARTY'S CHROME EXTENSION APP, UNLESS OTHERWISE
|
ALL CONTENT ON WATCH PARTY'S WEBSITE OR IN WATCH PARTY'S CHROME EXTENSION APP, UNLESS OTHERWISE
|
||||||
CITED ARE THE SOLE INTELECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE
|
CITED ARE THE SOLE INTELECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE
|
||||||
COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
|
COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
|
||||||
|
|
||||||
Netflix logo is a trademark and intellectual property of Netflix, Inc.
|
|
||||||
Disney+ logo is a trademark and intellectual property of The Walt Disney Company
|
|
||||||
Prime logo is a trademark and intellectual property of Amazon.com, Inc.
|
|
||||||
YouTube logo is a trademark and intellectual property of Google, Inc.
|
|
||||||
Hulu logo is a trademark and intellectual property of Hulu, LLC.
|
|
||||||
HBO Now and HBO Max logos are trademark and intellectual property of WarnerMedia Direct,LLC.
|
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
|
.thread-container * {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
font-family: "Roboto", sans-serif !important;
|
||||||
|
letter-spacing: 1.15px;
|
||||||
|
word-break: break-word !important;
|
||||||
|
}
|
||||||
|
.thread-container {
|
||||||
|
max-height: none;
|
||||||
|
padding: 0 15px;
|
||||||
|
padding-right: 0px !important;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
.thread-item {
|
.thread-item {
|
||||||
width: 100%;
|
color: white;
|
||||||
white-space: pre-wrap;
|
|
||||||
margin-top: 25px !important;
|
|
||||||
font-size: 12px !important;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
.thread-item.no-space {
|
|
||||||
margin-top: 0 !important;
|
|
||||||
}
|
|
||||||
.system-message {
|
|
||||||
display: block;
|
|
||||||
text-align: center;
|
|
||||||
width: 100%;
|
|
||||||
text-align: center;
|
|
||||||
font-size: 12px;
|
|
||||||
margin-top: 7.5px !important;
|
|
||||||
color: rgba(147, 147, 147, 0.8) !important;
|
|
||||||
}
|
|
||||||
.system-message.alert {
|
|
||||||
background-color: black;
|
|
||||||
border-radius: 1rem;
|
|
||||||
color: white !important;
|
|
||||||
padding: 5px 10px;
|
|
||||||
position: sticky;
|
|
||||||
top: 2px;
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
.my-message {
|
|
||||||
display: block;
|
|
||||||
width: fit-content;
|
width: fit-content;
|
||||||
text-align: right;
|
margin: 10px 0;
|
||||||
margin-left: auto !important;
|
width: 100%;
|
||||||
margin-right: 5px !important;
|
|
||||||
margin-top: 5px !important;
|
|
||||||
padding: 2.5px 10px !important;
|
|
||||||
border-radius: 13px;
|
|
||||||
max-width: 60%;
|
|
||||||
word-wrap: break-word;
|
|
||||||
background-color: rgb(49, 49, 49);
|
|
||||||
font-size: 14px !important;
|
|
||||||
}
|
|
||||||
img.my-message {
|
|
||||||
margin-right: 0 !important;
|
|
||||||
padding-right: 0 !important;
|
|
||||||
border-radius: 1rem;
|
|
||||||
max-width: 60%;
|
|
||||||
background: none;
|
|
||||||
border-radius: 2rem;
|
|
||||||
}
|
|
||||||
.party-message {
|
|
||||||
font-size: 14px !important;
|
|
||||||
display: block;
|
|
||||||
width: fit-content;
|
|
||||||
max-width: 60%;
|
|
||||||
word-wrap: break-word;
|
|
||||||
margin-top: 5px !important;
|
|
||||||
padding: 2.5px 10px !important;
|
|
||||||
border-radius: 13px;
|
|
||||||
background-color: rgb(88, 88, 88);
|
|
||||||
}
|
|
||||||
img.party-message {
|
|
||||||
border-radius: 1rem;
|
|
||||||
max-width: 60%;
|
|
||||||
background: none;
|
|
||||||
border-radius: 2rem;
|
|
||||||
margin-left: 0 !important;
|
|
||||||
padding-left: 0 !important;
|
|
||||||
}
|
|
||||||
.thread-item .name {
|
|
||||||
color: rgb(149, 149, 149);
|
|
||||||
font-size: 12px !important;
|
|
||||||
}
|
|
||||||
.time {
|
|
||||||
top: 0;
|
|
||||||
color: #3a3a3a;
|
|
||||||
position: absolute;
|
|
||||||
opacity: 0;
|
|
||||||
transition: all ease-in-out 0.3s;
|
transition: all ease-in-out 0.3s;
|
||||||
}
|
}
|
||||||
.party-message ~ .time {
|
.thread-item.highlight .thread-message img,
|
||||||
right: 0;
|
.thread-item.highlight .thread-message p {
|
||||||
|
border: 2px solid #c0f300;
|
||||||
}
|
}
|
||||||
.party-message:hover ~ .time {
|
.thread-item.highlight .thread-message img {
|
||||||
opacity: 1;
|
padding: 7.5px 10px;
|
||||||
}
|
}
|
||||||
.my-message ~ .time {
|
.thread-message {
|
||||||
|
width: 100%;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.thread-message .thread-overline {
|
||||||
|
height: 0;
|
||||||
|
overflow-y: visible;
|
||||||
|
font-size: 10px;
|
||||||
|
transition: all ease-in-out 0.3s;
|
||||||
|
transition-delay: 0.1s;
|
||||||
|
white-space: nowrap;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
opacity: 0;
|
||||||
|
color: #9f9f9f;
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: row-reverse;
|
||||||
|
}
|
||||||
|
.thread-message .thread-overline span {
|
||||||
|
flex: 1;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.thread-message .thread-overline .thread-reply-icon {
|
||||||
|
position: absolute;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 20px;
|
||||||
|
border-radius: 26px;
|
||||||
|
z-index: 999 !important;
|
||||||
|
white-space: break-spaces;
|
||||||
left: 0;
|
left: 0;
|
||||||
|
cursor: pointer;
|
||||||
|
bottom: 0;
|
||||||
|
transition: all ease-in-out 0.3s;
|
||||||
|
transition-delay: 0.1s;
|
||||||
|
width: 25px;
|
||||||
|
height: 25px;
|
||||||
|
padding: 0;
|
||||||
|
padding-bottom: 7px;
|
||||||
}
|
}
|
||||||
.my-message:hover ~ .time {
|
.thread-item:hover .thread-message .thread-overline {
|
||||||
|
height: 24px;
|
||||||
|
margin-bottom: 7px;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
.thread-message p {
|
||||||
|
max-width: 65%;
|
||||||
|
padding: 5px 15px;
|
||||||
|
background: #424242;
|
||||||
|
border-radius: 26px;
|
||||||
|
z-index: 9999 !important;
|
||||||
|
transition: all ease-in-out 0.3s;
|
||||||
|
transition-delay: 0.1s;
|
||||||
|
width: fit-content;
|
||||||
|
min-height: 25px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
line-height: 16px;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 100;
|
||||||
|
font-family: "Roboto";
|
||||||
|
letter-spacing: 1.5px;
|
||||||
|
white-space: break-spaces;
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
.thread-message img {
|
||||||
|
max-width: 55%;
|
||||||
|
border-radius: 26px;
|
||||||
|
transition: all ease-in-out 0.3s;
|
||||||
|
transition-delay: 0.1s;
|
||||||
|
z-index: 999;
|
||||||
|
}
|
||||||
|
.thread-item:hover .thread-message p,
|
||||||
|
.thread-item:hover .thread-message img {
|
||||||
|
margin-left: 40px;
|
||||||
|
}
|
||||||
|
.thread-message .thread-overline .thread-reply-icon:hover {
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
.thread-name {
|
||||||
|
font-size: 11px;
|
||||||
|
margin-top: 15px;
|
||||||
|
margin-bottom: 7px;
|
||||||
|
color: #adadad;
|
||||||
|
}
|
||||||
|
.thread-reply {
|
||||||
|
font-size: 11px;
|
||||||
|
margin-bottom: -20px;
|
||||||
|
padding: 7.5px 15px;
|
||||||
|
padding-bottom: 25px;
|
||||||
|
border-radius: 13px;
|
||||||
|
background: #222222;
|
||||||
|
width: fit-content;
|
||||||
|
max-width: 45%;
|
||||||
|
z-index: 999 !important;
|
||||||
|
transition: all ease-in-out 0.3s;
|
||||||
|
transition-delay: 0.1s;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.thread-reply-name {
|
||||||
|
color: #8a8a8a;
|
||||||
|
font-size: 10px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
margin-bottom: 5px !important;
|
||||||
|
}
|
||||||
|
.thread-reply p {
|
||||||
|
width: fit-content;
|
||||||
|
max-width: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
.thread-reply img {
|
||||||
|
max-height: 70px;
|
||||||
|
border-radius: 26px;
|
||||||
|
transition: all ease-in-out 0.3s;
|
||||||
|
transition-delay: 0.1s;
|
||||||
|
}
|
||||||
|
.thread-item:hover .thread-reply {
|
||||||
|
margin-bottom: 0;
|
||||||
|
padding-bottom: 7.5px;
|
||||||
|
}
|
||||||
|
.thread-reply:hover {
|
||||||
|
background: #111111;
|
||||||
|
}
|
||||||
|
.thread-item.continued-message .thread-name {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
M Y
|
||||||
|
M E S S A G E S
|
||||||
|
*/
|
||||||
|
.thread-item.my-message {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-end;
|
||||||
|
}
|
||||||
|
.thread-item.my-message .thread-name {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.thread-item.my-message .thread-message {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-end;
|
||||||
|
}
|
||||||
|
.thread-item.my-message .thread-message p {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
.thread-item.my-message .thread-message .thread-overline {
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
.thread-item.my-message .thread-message .thread-overline .thread-reply-icon {
|
||||||
|
right: 0;
|
||||||
|
left: unset;
|
||||||
|
}
|
||||||
|
.thread-item.my-message:hover .thread-message p,
|
||||||
|
.thread-item.my-message:hover .thread-message img {
|
||||||
|
margin-left: 0;
|
||||||
|
margin-right: 40px;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
S Y S T E M
|
||||||
|
M E S S A G E S
|
||||||
|
*/
|
||||||
|
.thread-item.system-message .thread-name,
|
||||||
|
.thread-item.system-message .thread-reply,
|
||||||
|
.thread-item.system-message img,
|
||||||
|
.thread-item.system-message .thread-overline {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.thread-item.system-message .thread-message p {
|
||||||
|
width: 100%;
|
||||||
|
margin: 0 auto;
|
||||||
|
background: none;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #9f9f9f;
|
||||||
|
text-align: center;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.thread-item.system-message:hover .thread-message p {
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
I N T E R A C T I V E
|
||||||
|
S Y S T E M
|
||||||
|
M E S S A G E S
|
||||||
|
*/
|
||||||
|
.thread-interactive-text {
|
||||||
|
display: flex !important;
|
||||||
|
flex-direction: column !important;
|
||||||
|
margin: 0 auto !important;
|
||||||
|
background-color: #222222 !important;
|
||||||
|
border-radius: 42px !important;
|
||||||
|
padding: 20px 35px !important;
|
||||||
|
transition: all ease-in-out 0.3s;
|
||||||
|
transition-delay: 0.1s;
|
||||||
|
}
|
||||||
|
.thread-interactive-text:hover {
|
||||||
|
background-color: #111111 !important;
|
||||||
|
}
|
||||||
|
.thread-interactive-question {
|
||||||
|
font-size: 10px !important;
|
||||||
|
letter-spacing: 2px !important;
|
||||||
|
color: #9f9f9f !important;
|
||||||
|
line-height: 1.5 !important;
|
||||||
|
padding: 7.5px 0px !important;
|
||||||
|
padding-top: 0 !important;
|
||||||
|
text-align: center !important;
|
||||||
|
}
|
||||||
|
.thread-interactive-answer > div {
|
||||||
|
border-radius: 26px;
|
||||||
|
}
|
||||||
|
.thread-interactive-thankyou {
|
||||||
|
text-align: center !important;
|
||||||
|
}
|
||||||
|
.thread-interactive-link {
|
||||||
|
color: inherit !important;
|
||||||
|
width: calc(100% + 70px) !important;
|
||||||
|
margin-left: -35px !important;
|
||||||
|
border-bottom-left-radius: 50px !important;
|
||||||
|
border-bottom-right-radius: 50px !important;
|
||||||
|
margin-bottom: -20px !important;
|
||||||
|
padding-bottom: 15px !important;
|
||||||
|
margin-top: 5px !important;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
S E N D I N G
|
||||||
|
M E S S A G E S
|
||||||
|
*/
|
||||||
|
.thread-item.my-message.sending-message .thread-message .thread-overline {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.thread-item.my-message.sending-message .thread-message p,
|
||||||
|
.thread-item.my-message.sending-message .thread-message img {
|
||||||
|
margin-left: 0 !important;
|
||||||
|
margin-right: 0 !important;
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,74 +5,191 @@ Proprietary and confidential
|
|||||||
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
||||||
https://www.chromewatchparty.com/copyright
|
https://www.chromewatchparty.com/copyright
|
||||||
=========================================================================
|
=========================================================================
|
||||||
ALL CONTENT ON IN WATCH PARTY'S CHROME EXTENSION APP, UNLESS OTHERWISE
|
ALL CONTENT ON WATCH PARTY'S WEBSITE OR IN WATCH PARTY'S CHROME EXTENSION APP, UNLESS OTHERWISE
|
||||||
CITED ARE THE SOLE INTELECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE
|
CITED ARE THE SOLE INTELECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE
|
||||||
COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
|
COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
|
||||||
|
|
||||||
Netflix logo is a trademark and intellectual property of Netflix, Inc.
|
|
||||||
Disney+ logo is a trademark and intellectual property of The Walt Disney Company
|
|
||||||
Prime logo is a trademark and intellectual property of Amazon.com, Inc.
|
|
||||||
YouTube logo is a trademark and intellectual property of Google, Inc.
|
|
||||||
Hulu logo is a trademark and intellectual property of Hulu, LLC.
|
|
||||||
HBO Now and HBO Max logos are trademark and intellectual property of WarnerMedia Direct,LLC.
|
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
import React from 'react';
|
import React, { Component } from 'react';
|
||||||
import { Typography } from '@material-ui/core';
|
import {
|
||||||
|
Typography,
|
||||||
|
IconButton,
|
||||||
|
Paper,
|
||||||
|
TextField,
|
||||||
|
InputAdornment,
|
||||||
|
Button,
|
||||||
|
} from '@material-ui/core';
|
||||||
|
import { Reply, Send } from '@material-ui/icons';
|
||||||
import './Thread.css';
|
import './Thread.css';
|
||||||
import { LocalData } from './Api';
|
import { LocalData, webhookFetcher } from './Api';
|
||||||
|
|
||||||
const Thread = (props) =>
|
export default class Thread extends Component {
|
||||||
props.messages.map((m, midx) => {
|
constructor(props) {
|
||||||
var { userUid } = LocalData();
|
super(props);
|
||||||
if (m.uid === '<system>') {
|
this.getTimeString = this.getTimeString.bind(this);
|
||||||
// SYSTEM MESSAGES
|
this.getReplyMessage = this.getReplyMessage.bind(this);
|
||||||
|
this.getMessageTextOrImage = this.getMessageTextOrImage.bind(this);
|
||||||
|
}
|
||||||
|
scrollToMessage(id) {
|
||||||
|
const pcc = document.querySelector('.thread-wrapper');
|
||||||
|
const msg = document.getElementById(id);
|
||||||
|
const alc = document.querySelector(
|
||||||
|
'#party-routes-wrapper > div.party-chat-container > div.thread-wrapper > div.alerts-container'
|
||||||
|
);
|
||||||
|
pcc.scrollTop = msg.offsetTop - pcc.offsetTop - alc.clientHeight - 10;
|
||||||
|
msg.classList.add('highlight');
|
||||||
|
setTimeout(() => msg.classList.remove('highlight'), 2000);
|
||||||
|
}
|
||||||
|
handleInteractiveMessageCall(msg) {
|
||||||
|
const thanksElement = document.createElement('div');
|
||||||
|
thanksElement.innerText = 'THANK YOU FOR THE FEEDBACK';
|
||||||
|
thanksElement.className = 'thread-interactive-thankyou';
|
||||||
|
if (msg.uid === '<system>') {
|
||||||
|
if (msg.endpoint) {
|
||||||
|
var bodyData = {
|
||||||
|
question: msg.text,
|
||||||
|
};
|
||||||
|
if (msg.type === 'interactive/text') {
|
||||||
|
const answerElement = document.getElementById(`reply-${msg.id}`);
|
||||||
|
bodyData.answer = answerElement ? answerElement.value : 'ANSWER_ELEM_NOT_FOUND';
|
||||||
|
answerElement.disabled = true;
|
||||||
|
answerElement.parentElement.parentElement.parentElement.firstElementChild.remove();
|
||||||
|
answerElement.parentElement.replaceWith(thanksElement);
|
||||||
|
}
|
||||||
|
webhookFetcher({
|
||||||
|
endpoint: msg.endpoint,
|
||||||
|
body: JSON.stringify(bodyData),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
getItemClassNames(uid, userUid, msgIdx, messages, isSending = false) {
|
||||||
|
const lastUid = msgIdx >= 1 ? messages[msgIdx - 1].uid : '';
|
||||||
|
return `thread-item ${uid === userUid ? 'my-message' : ''} ${
|
||||||
|
isSending ? 'sending-message' : ''
|
||||||
|
} ${uid === '<system>' ? 'system-message' : ''} ${lastUid === uid ? 'continued-message' : ''}`;
|
||||||
|
}
|
||||||
|
getMessageTextOrImage(msg) {
|
||||||
|
if (msg.type === 'giphy') {
|
||||||
|
return <img alt="gif" src={msg.text} />;
|
||||||
|
}
|
||||||
|
if (msg.type === 'interactive/text') {
|
||||||
return (
|
return (
|
||||||
<Typography variant="body2" className="thread-item system-message" key={m.id} disabled>
|
<Paper elevation={0} className="thread-interactive-text">
|
||||||
{m.text}
|
<Typography className="thread-interactive-question" variant="overline">
|
||||||
</Typography>
|
{msg.text}
|
||||||
);
|
|
||||||
} else if (m.uid === userUid) {
|
|
||||||
// OWN MESSAGE
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
className={`thread-item ${
|
|
||||||
midx > 0 ? (props.messages[midx - 1].uid !== m.uid ? '' : 'no-space') : ''
|
|
||||||
}`}
|
|
||||||
key={m.id}
|
|
||||||
>
|
|
||||||
{m.type === 'giphy' ? (
|
|
||||||
<img className="my-message" alt="giphy gif" src={m.text} />
|
|
||||||
) : (
|
|
||||||
<Typography variant="body1" className="my-message">
|
|
||||||
{m.text}
|
|
||||||
</Typography>
|
|
||||||
)}
|
|
||||||
<span className="time">{new Date(m.time.seconds * 1000).toLocaleTimeString()}</span>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
// OTHER USER MESSAGE
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
className={`thread-item ${
|
|
||||||
midx > 0 ? (props.messages[midx - 1].uid !== m.uid ? '' : 'no-space') : ''
|
|
||||||
}`}
|
|
||||||
key={m.id}
|
|
||||||
>
|
|
||||||
<Typography variant="caption" className="name">
|
|
||||||
{midx > 0 ? (props.messages[midx - 1].uid !== m.uid ? m.name : '') : m.name}
|
|
||||||
</Typography>
|
</Typography>
|
||||||
{m.type === 'giphy' ? (
|
<TextField
|
||||||
<img className="party-message" alt="giphy gif" src={m.text} />
|
className="thread-interactive-answer addFocus"
|
||||||
) : (
|
size="small"
|
||||||
<Typography variant="body1" className="party-message">
|
id={`reply-${msg.id}`}
|
||||||
{m.text}
|
multiline
|
||||||
</Typography>
|
variant="outlined"
|
||||||
)}
|
color="secondary"
|
||||||
<span className="time">{new Date(m.time.seconds * 1000).toLocaleTimeString()}</span>
|
InputProps={{
|
||||||
|
endAdornment: (
|
||||||
|
<InputAdornment position="end">
|
||||||
|
<IconButton onClick={() => this.handleInteractiveMessageCall(msg)}>
|
||||||
|
<Send />
|
||||||
|
</IconButton>
|
||||||
|
</InputAdornment>
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
rowsMax={2}
|
||||||
|
/>
|
||||||
|
</Paper>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (msg.type === 'interactive/link') {
|
||||||
|
return (
|
||||||
|
<Paper elevation={0} className="thread-interactive-text">
|
||||||
|
<Typography className="thread-interactive-question" variant="overline">
|
||||||
|
{msg.text}
|
||||||
|
</Typography>
|
||||||
|
<Button
|
||||||
|
className="thread-interactive-link"
|
||||||
|
fullWidth
|
||||||
|
target="_blank"
|
||||||
|
href={msg.endpoint}
|
||||||
|
color="secondary"
|
||||||
|
>
|
||||||
|
{msg.name}
|
||||||
|
</Button>
|
||||||
|
</Paper>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return <p>{msg.text}</p>;
|
||||||
|
}
|
||||||
|
getTimeString(time) {
|
||||||
|
return new Date(time.seconds * 1000).toLocaleTimeString();
|
||||||
|
}
|
||||||
|
getReplyMessage(rT, messages) {
|
||||||
|
if (rT !== undefined && rT !== null) {
|
||||||
|
const replyMessage = messages.filter((m) => m.id === rT)[0];
|
||||||
|
return (
|
||||||
|
<div className="thread-reply" onClick={() => this.scrollToMessage(replyMessage.id)}>
|
||||||
|
<p className="thread-reply-name">Reply to {replyMessage.name}:</p>
|
||||||
|
{this.getMessageTextOrImage(replyMessage)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
return null;
|
||||||
|
}
|
||||||
|
render() {
|
||||||
|
const { sendingMessages, setReplyTo, sentMessages } = this.props;
|
||||||
|
const { userUid } = LocalData();
|
||||||
|
return (
|
||||||
|
<div className="thread-container">
|
||||||
|
{sentMessages.length > 0
|
||||||
|
? sentMessages.map((msg, msgIdx) => (
|
||||||
|
<div
|
||||||
|
id={msg.id}
|
||||||
|
key={`msg-${msgIdx}`}
|
||||||
|
className={this.getItemClassNames(msg.uid, userUid, msgIdx, sentMessages)}
|
||||||
|
>
|
||||||
|
<div className="thread-name">{msg.name}</div>
|
||||||
|
{this.getReplyMessage(msg.replyTo, sentMessages)}
|
||||||
|
<div className="thread-message">
|
||||||
|
<div className="thread-overline">
|
||||||
|
<span>{this.getTimeString(msg.time)}</span>
|
||||||
|
<div className="thread-reply-icon">
|
||||||
|
<IconButton onClick={() => setReplyTo(msg)}>
|
||||||
|
<Reply />
|
||||||
|
</IconButton>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{this.getMessageTextOrImage(msg)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))
|
||||||
|
: null}
|
||||||
|
{sendingMessages.length > 0
|
||||||
|
? sendingMessages.map((msg, msgIdx) => (
|
||||||
|
<div
|
||||||
|
id={msg.id}
|
||||||
|
key={`msg-${msgIdx}`}
|
||||||
|
className={this.getItemClassNames(msg.uid, userUid, msgIdx, sendingMessages, true)}
|
||||||
|
>
|
||||||
|
<div className="thread-name">{msg.name}</div>
|
||||||
|
{this.getReplyMessage(msg.replyTo, sentMessages)}
|
||||||
|
<div className="thread-message">
|
||||||
|
<div className="thread-overline">
|
||||||
|
<span>{this.getTimeString(msg.time)}</span>
|
||||||
|
<div className="thread-reply-icon">
|
||||||
|
<IconButton onClick={() => setReplyTo(msg)}>
|
||||||
|
<Reply />
|
||||||
|
</IconButton>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{this.getMessageTextOrImage(msg)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))
|
||||||
|
: null}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export default Thread;
|
Thread.defaultProps = {
|
||||||
|
setReplyTo: () => {},
|
||||||
|
};
|
||||||
|
|||||||
@@ -5,19 +5,11 @@ Proprietary and confidential
|
|||||||
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
||||||
https://www.chromewatchparty.com/copyright
|
https://www.chromewatchparty.com/copyright
|
||||||
=========================================================================
|
=========================================================================
|
||||||
ALL CONTENT ON IN WATCH PARTY'S CHROME EXTENSION APP, UNLESS OTHERWISE
|
ALL CONTENT ON WATCH PARTY'S WEBSITE OR IN WATCH PARTY'S CHROME EXTENSION APP, UNLESS OTHERWISE
|
||||||
CITED ARE THE SOLE INTELECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE
|
CITED ARE THE SOLE INTELECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE
|
||||||
COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
|
COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
|
||||||
|
|
||||||
Netflix logo is a trademark and intellectual property of Netflix, Inc.
|
|
||||||
Disney+ logo is a trademark and intellectual property of The Walt Disney Company
|
|
||||||
Prime logo is a trademark and intellectual property of Amazon.com, Inc.
|
|
||||||
YouTube logo is a trademark and intellectual property of Google, Inc.
|
|
||||||
Hulu logo is a trademark and intellectual property of Hulu, LLC.
|
|
||||||
HBO Now and HBO Max logos are trademark and intellectual property of WarnerMedia Direct,LLC.
|
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
import { PLAYER_STATUS, getPlayerSource, PLAYER_SOURCE, LocalData } from './Api';
|
import { PLAYER_STATUS, getPlayerSource, PLAYER_SOURCE, LocalData } from './Api';
|
||||||
import simulate from './ClickSimulator';
|
|
||||||
|
|
||||||
const templateListener = (video) => console.log('MISSING VIDEO LISTENER');
|
const templateListener = (video) => console.log('MISSING VIDEO LISTENER');
|
||||||
|
|
||||||
@@ -39,6 +31,7 @@ export default class VideoListener {
|
|||||||
this.onpause = this.onpause.bind(this);
|
this.onpause = this.onpause.bind(this);
|
||||||
this.onplay = this.onplay.bind(this);
|
this.onplay = this.onplay.bind(this);
|
||||||
this.shouldPushSync = this.shouldPushSync.bind(this);
|
this.shouldPushSync = this.shouldPushSync.bind(this);
|
||||||
|
this.crunchyRollListener = this.crunchyRollListener.bind(this);
|
||||||
}
|
}
|
||||||
shouldPushSync() {
|
shouldPushSync() {
|
||||||
return (
|
return (
|
||||||
@@ -73,8 +66,13 @@ export default class VideoListener {
|
|||||||
this.isUpdating = true;
|
this.isUpdating = true;
|
||||||
if (this.video.element) {
|
if (this.video.element) {
|
||||||
// REMOVE LISTENER BEFORE SYNCING
|
// REMOVE LISTENER BEFORE SYNCING
|
||||||
this.video.element.removeEventListener('playing', this.onplay);
|
switch (this.video.source) {
|
||||||
this.video.element.removeEventListener('pause', this.onpause);
|
case PLAYER_SOURCE.CRUNCHYROLL:
|
||||||
|
window.removeEventListener('watchParty', this.crunchyRollListener);
|
||||||
|
default:
|
||||||
|
this.video.element.removeEventListener('playing', this.onplay);
|
||||||
|
this.video.element.removeEventListener('pause', this.onpause);
|
||||||
|
}
|
||||||
await this.timeout(250);
|
await this.timeout(250);
|
||||||
// SEEK
|
// SEEK
|
||||||
if (Math.abs(serverPlayer.time - this.video.element.currentTime) > 1.5) {
|
if (Math.abs(serverPlayer.time - this.video.element.currentTime) > 1.5) {
|
||||||
@@ -87,6 +85,7 @@ export default class VideoListener {
|
|||||||
await this.video.element
|
await this.video.element
|
||||||
.play()
|
.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;
|
this.video.element.currentTime = serverPlayer.time;
|
||||||
await this.timeout(500);
|
await this.timeout(500);
|
||||||
break;
|
break;
|
||||||
@@ -105,14 +104,27 @@ export default class VideoListener {
|
|||||||
this.video.element.currentTime = serverPlayer.time;
|
this.video.element.currentTime = serverPlayer.time;
|
||||||
break;
|
break;
|
||||||
case PLAYER_SOURCE.PEACOCK:
|
case PLAYER_SOURCE.PEACOCK:
|
||||||
const sliderHead = document.body.querySelector(
|
window.postMessage(
|
||||||
'.playback-scrubber-bar .rc-slider-handle'
|
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,
|
||||||
|
})
|
||||||
);
|
);
|
||||||
sliderHead.style.left =
|
|
||||||
((serverPlayer.time * 1000) / sliderHead.getAttribute('aria-valueMax')) * 100 + '%';
|
|
||||||
simulate(sliderHead, 'mousedown');
|
|
||||||
simulate(sliderHead, 'mouseup');
|
|
||||||
await this.timeout(500);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -126,9 +138,23 @@ export default class VideoListener {
|
|||||||
PLAYER_SOURCE.NETFLIX === this.video.source ||
|
PLAYER_SOURCE.NETFLIX === this.video.source ||
|
||||||
PLAYER_SOURCE.HBOMAX === this.video.source ||
|
PLAYER_SOURCE.HBOMAX === this.video.source ||
|
||||||
PLAYER_SOURCE.HBONOW === this.video.source
|
PLAYER_SOURCE.HBONOW === this.video.source
|
||||||
)
|
) {
|
||||||
window.postMessage({ type: 'PAUSE', time: serverPlayer.time }, '*');
|
window.postMessage({ type: 'PAUSE', time: serverPlayer.time }, '*');
|
||||||
else await this.video.element.pause();
|
} else if (
|
||||||
|
PLAYER_SOURCE.CRUNCHYROLL === this.video.source ||
|
||||||
|
PLAYER_SOURCE.PEACOCK === 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.pause();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case PLAYER_STATUS.PLAYING:
|
case PLAYER_STATUS.PLAYING:
|
||||||
if (
|
if (
|
||||||
@@ -136,20 +162,38 @@ export default class VideoListener {
|
|||||||
PLAYER_SOURCE.NETFLIX === this.video.source ||
|
PLAYER_SOURCE.NETFLIX === this.video.source ||
|
||||||
PLAYER_SOURCE.HBOMAX === this.video.source ||
|
PLAYER_SOURCE.HBOMAX === this.video.source ||
|
||||||
PLAYER_SOURCE.HBONOW === this.video.source
|
PLAYER_SOURCE.HBONOW === this.video.source
|
||||||
)
|
) {
|
||||||
window.postMessage({ type: 'PLAY', time: serverPlayer.time }, '*');
|
window.postMessage({ type: 'PLAY', time: serverPlayer.time }, '*');
|
||||||
else
|
} else if (
|
||||||
|
PLAYER_SOURCE.CRUNCHYROLL === this.video.source ||
|
||||||
|
PLAYER_SOURCE.PEACOCK === 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
|
await this.video.element
|
||||||
.play()
|
.play()
|
||||||
.catch((err) => console.error('WatchParty erred when syncing play.'));
|
.catch((err) => console.error('WatchParty erred when syncing play.'));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
await this.timeout(500);
|
await this.timeout(500);
|
||||||
// RE-ADD LISTENERS FOR FUTURE SYNC
|
// RE-ADD LISTENERS FOR FUTURE SYNC
|
||||||
this.video.element.addEventListener('playing', this.onplay);
|
switch (this.video.source) {
|
||||||
this.video.element.addEventListener('pause', this.onpause);
|
case PLAYER_SOURCE.CRUNCHYROLL:
|
||||||
|
window.addEventListener('watchParty', this.crunchyRollListener);
|
||||||
|
default:
|
||||||
|
this.video.element.addEventListener('playing', this.onplay);
|
||||||
|
this.video.element.addEventListener('pause', this.onpause);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
this.isUpdating = false;
|
this.isUpdating = false;
|
||||||
}
|
}
|
||||||
@@ -218,6 +262,20 @@ export default class VideoListener {
|
|||||||
return peacockshow === '' && peacockepisode === ''
|
return peacockshow === '' && peacockepisode === ''
|
||||||
? null
|
? null
|
||||||
: peacockshow + '\n' + peacockepisode;
|
: peacockshow + '\n' + peacockepisode;
|
||||||
|
case PLAYER_SOURCE.GOOGLEPLAY:
|
||||||
|
const playerIframe = document.querySelector(
|
||||||
|
'#yDmH0d > div.llhEMd.bYEzqc.LAhoGb.iWO5td > div > div.LhXUod.XL54pf.J9Nfi.iWO5td > span > div > div > iframe'
|
||||||
|
);
|
||||||
|
var googleplayshow = '';
|
||||||
|
if (playerIframe) {
|
||||||
|
const titleElement = playerIframe.contentWindow.document.querySelector('.playing-title');
|
||||||
|
googleplayshow = titleElement ? titleElement.innerText : '';
|
||||||
|
}
|
||||||
|
return googleplayshow === '' ? null : googleplayshow;
|
||||||
|
case PLAYER_SOURCE.CRUNCHYROLL:
|
||||||
|
const crunchyrollTitle = document.querySelector('#showmedia_about_media');
|
||||||
|
const crunchyrollshow = crunchyrollTitle ? crunchyrollTitle.innerText : '';
|
||||||
|
return crunchyrollshow === '' ? null : crunchyrollshow;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -236,21 +294,39 @@ export default class VideoListener {
|
|||||||
showName: await this.getShowName(),
|
showName: await this.getShowName(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
async crunchyRollListener(ev) {
|
||||||
|
if (
|
||||||
|
ev.detail.watchPartyDirection === 'TO_APP' &&
|
||||||
|
ev.detail.type === 'WATCH_PARTY_PLAYER_UPDATE'
|
||||||
|
) {
|
||||||
|
this.updateStatus({
|
||||||
|
status: ev.detail.status,
|
||||||
|
time: ev.detail.time,
|
||||||
|
showName: await this.getShowName(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
async firstTimeSync(videoElement) {
|
async firstTimeSync(videoElement) {
|
||||||
this.updateStatus({
|
this.updateStatus({
|
||||||
element: videoElement,
|
element: videoElement,
|
||||||
});
|
});
|
||||||
// if (videoElement.currentTime > 0 && !videoElement.paused) {
|
|
||||||
// this.updateStatus({
|
|
||||||
// time: videoElement.currentTime,
|
|
||||||
// status: PLAYER_STATUS.PLAYING,
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
this.updateStatus({
|
this.updateStatus({
|
||||||
showName: await this.getShowName(),
|
showName: await this.getShowName(),
|
||||||
});
|
});
|
||||||
videoElement.addEventListener('playing', this.onplay);
|
switch (this.video.source) {
|
||||||
videoElement.addEventListener('pause', this.onpause);
|
case PLAYER_SOURCE.CRUNCHYROLL:
|
||||||
|
window.postMessage(
|
||||||
|
JSON.stringify({
|
||||||
|
watchPartyDirection: 'TO_SCRIPT',
|
||||||
|
type: 'WATCH_PARTY_ADD_LISTENERS',
|
||||||
|
})
|
||||||
|
);
|
||||||
|
window.addEventListener('watchParty', this.crunchyRollListener);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
videoElement.addEventListener('playing', this.onplay);
|
||||||
|
videoElement.addEventListener('pause', this.onpause);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
async start() {
|
async start() {
|
||||||
this.updateStatus({ source: getPlayerSource(), showName: await this.getShowName() });
|
this.updateStatus({ source: getPlayerSource(), showName: await this.getShowName() });
|
||||||
@@ -271,9 +347,11 @@ export default class VideoListener {
|
|||||||
this.video.element
|
this.video.element
|
||||||
? null
|
? null
|
||||||
: () => {
|
: () => {
|
||||||
var nve = document
|
var nve = document.getElementsByClassName('AkiraPlayer')[0]
|
||||||
.getElementsByClassName('AkiraPlayer')[0]
|
? document
|
||||||
.getElementsByTagName('video')[0];
|
.getElementsByClassName('AkiraPlayer')[0]
|
||||||
|
.getElementsByTagName('video')[0]
|
||||||
|
: null;
|
||||||
if (
|
if (
|
||||||
nve !== null &&
|
nve !== null &&
|
||||||
(this.video.element !== nve || this.video.element === null)
|
(this.video.element !== nve || this.video.element === null)
|
||||||
@@ -289,9 +367,11 @@ export default class VideoListener {
|
|||||||
this.video.element
|
this.video.element
|
||||||
? null
|
? null
|
||||||
: () => {
|
: () => {
|
||||||
var nve = document
|
var nve = document.getElementsByClassName('AkiraPlayer')[0]
|
||||||
.getElementsByClassName('AkiraPlayer')[0]
|
? document
|
||||||
.getElementsByTagName('video')[0];
|
.getElementsByClassName('AkiraPlayer')[0]
|
||||||
|
.getElementsByTagName('video')[0]
|
||||||
|
: null;
|
||||||
if (nve !== null && (this.video.element !== nve || this.video.element === null)) {
|
if (nve !== null && (this.video.element !== nve || this.video.element === null)) {
|
||||||
this.firstTimeSync(nve);
|
this.firstTimeSync(nve);
|
||||||
}
|
}
|
||||||
@@ -430,8 +510,12 @@ export default class VideoListener {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PLAYER_SOURCE.PEACOCK:
|
case PLAYER_SOURCE.PEACOCK:
|
||||||
|
const peacockInject = `var watchPartyInteraction=function(e){if(e.source===window){const data=JSON.parse(e.data);const playerReactElement=document.querySelector(".video-player-component.playback-component > div");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(
|
const peacockVideoElement = document.querySelector(
|
||||||
'#mount > div > div > div > div > div > div.video-player-component.playback-component > div > video'
|
'.video-player-component.playback-component video'
|
||||||
);
|
);
|
||||||
if (peacockVideoElement) {
|
if (peacockVideoElement) {
|
||||||
this.firstTimeSync(peacockVideoElement);
|
this.firstTimeSync(peacockVideoElement);
|
||||||
@@ -441,7 +525,7 @@ export default class VideoListener {
|
|||||||
? null
|
? null
|
||||||
: () => {
|
: () => {
|
||||||
var pve = document.querySelector(
|
var pve = document.querySelector(
|
||||||
'#mount > div > div > div > div > div > div.video-player-component.playback-component > div > video'
|
'.video-player-component.playback-component video'
|
||||||
);
|
);
|
||||||
if (
|
if (
|
||||||
pve !== null &&
|
pve !== null &&
|
||||||
@@ -455,6 +539,55 @@ export default class VideoListener {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case PLAYER_SOURCE.GOOGLEPLAY:
|
||||||
|
const playerIframe = document.querySelector(
|
||||||
|
'#yDmH0d > div.llhEMd.bYEzqc.LAhoGb.iWO5td > div > div.LhXUod.XL54pf.J9Nfi.iWO5td > span > div > div > iframe'
|
||||||
|
);
|
||||||
|
if (playerIframe) {
|
||||||
|
const googlePlayVideoElement = playerIframe.contentWindow.document.querySelector('video');
|
||||||
|
if (googlePlayVideoElement) {
|
||||||
|
this.firstTimeSync(googlePlayVideoElement);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setInterval(
|
||||||
|
this.video.element
|
||||||
|
? null
|
||||||
|
: () => {
|
||||||
|
const pif = document.querySelector(
|
||||||
|
'#yDmH0d > div.llhEMd.bYEzqc.LAhoGb.iWO5td > div > div.LhXUod.XL54pf.J9Nfi.iWO5td > span > div > div > iframe'
|
||||||
|
);
|
||||||
|
if (pif) {
|
||||||
|
const gpve = pif.contentWindow.document.querySelector('video');
|
||||||
|
if (gpve) {
|
||||||
|
this.firstTimeSync(gpve);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
1000
|
||||||
|
);
|
||||||
|
}
|
||||||
|
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');
|
||||||
|
crunchyRollInjectScript.text = crunchyRollInject;
|
||||||
|
document.head.appendChild(crunchyRollInjectScript);
|
||||||
|
const crunchyrollIframe = document.getElementById('vilos-player');
|
||||||
|
if (crunchyrollIframe) {
|
||||||
|
this.firstTimeSync(crunchyrollIframe);
|
||||||
|
} else {
|
||||||
|
setInterval(
|
||||||
|
this.video.element
|
||||||
|
? null
|
||||||
|
: () => {
|
||||||
|
const cif = document.getElementById('vilos-player');
|
||||||
|
if (cif) {
|
||||||
|
this.firstTimeSync(cif);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
1000
|
||||||
|
);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case PLAYER_SOURCE.LOCAL:
|
case PLAYER_SOURCE.LOCAL:
|
||||||
const localVideoElement = document.getElementsByTagName('video')[0];
|
const localVideoElement = document.getElementsByTagName('video')[0];
|
||||||
if (localVideoElement) {
|
if (localVideoElement) {
|
||||||
@@ -466,9 +599,15 @@ export default class VideoListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
end() {
|
end() {
|
||||||
if (this.video.element) {
|
switch (this.video.source) {
|
||||||
this.video.element.removeEventListener('playing', this.onplay);
|
case PLAYER_SOURCE.CRUNCHYROLL:
|
||||||
this.video.element.removeEventListener('pause', this.onpause);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ Proprietary and confidential
|
|||||||
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
||||||
https://www.chromewatchparty.com/copyright
|
https://www.chromewatchparty.com/copyright
|
||||||
=========================================================================
|
=========================================================================
|
||||||
ALL CONTENT ON IN WATCH PARTY'S CHROME EXTENSION APP, UNLESS OTHERWISE
|
ALL CONTENT ON WATCH PARTY'S WEBSITE OR IN WATCH PARTY'S CHROME EXTENSION APP, UNLESS OTHERWISE
|
||||||
CITED ARE THE SOLE INTELECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE
|
CITED ARE THE SOLE INTELECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE
|
||||||
COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
|
COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
|
||||||
|
|
||||||
@@ -17,8 +17,8 @@ Hulu logo is a trademark and intellectual property of Hulu, LLC.
|
|||||||
HBO Now and HBO Max logos are trademark and intellectual property of WarnerMedia Direct,LLC.
|
HBO Now and HBO Max logos are trademark and intellectual property of WarnerMedia Direct,LLC.
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
:root {
|
:root {
|
||||||
--party-width: 400px;
|
--party-width: 425px;
|
||||||
--neg-party-width: -400px;
|
--neg-party-width: -425px;
|
||||||
--body-width: calc(100% - var(--party-width));
|
--body-width: calc(100% - var(--party-width));
|
||||||
}
|
}
|
||||||
body {
|
body {
|
||||||
@@ -35,7 +35,7 @@ body.visible {
|
|||||||
body.visible .watch-party-fab {
|
body.visible .watch-party-fab {
|
||||||
right: var(--party-width) !important;
|
right: var(--party-width) !important;
|
||||||
transform: translateX(0);
|
transform: translateX(0);
|
||||||
top: 1.5rem;
|
top: 22.5px !important;
|
||||||
border-top-right-radius: 0;
|
border-top-right-radius: 0;
|
||||||
border-bottom-right-radius: 0;
|
border-bottom-right-radius: 0;
|
||||||
background-color: #424242 !important;
|
background-color: #424242 !important;
|
||||||
@@ -47,12 +47,35 @@ body.visible .party-notification-container {
|
|||||||
max-width: var(--party-width);
|
max-width: var(--party-width);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#party-width-dragger {
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
padding: 15px 3.5px;
|
||||||
|
right: var(--party-width);
|
||||||
|
top: 50%;
|
||||||
|
background: #2d2d2d;
|
||||||
|
cursor: ew-resize;
|
||||||
|
font-size: 16px;
|
||||||
|
width: fit-content;
|
||||||
|
user-select: none;
|
||||||
|
transition: all ease-in-out 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.visible #party-width-dragger {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.hbo.visible #party-width-dragger {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
body.netflix.visible .AkiraPlayer, /* NETFLIX */
|
body.netflix.visible .AkiraPlayer, /* NETFLIX */
|
||||||
body.hulu.visible .Player__container,/* HULU */
|
body.hulu.visible .Player__container,/* HULU */
|
||||||
body.amazon-prime.visible #dv-web-player.dv-player-fullscreen, /* AMAZON PRIME */
|
body.amazon-prime.visible #dv-web-player.dv-player-fullscreen, /* AMAZON PRIME */
|
||||||
body.disney.visible #hudson-wrapper, /* DISNEY */
|
body.disney.visible #hudson-wrapper, /* DISNEY */
|
||||||
body.youtube.visible #content.ytd-app, /* YOUTUBE */
|
body.youtube.visible #content.ytd-app, /* YOUTUBE */
|
||||||
body.youtube.visible #masthead-container /* YOUTUBE HEADER */ {
|
body.youtube.visible #masthead-container, /* YOUTUBE HEADER */
|
||||||
|
body.googleplay.visible div.llhEMd.bYEzqc.LAhoGb.iWO5td /* GOOGLE PLAY MOVIES */ {
|
||||||
max-width: var(--body-width) !important;
|
max-width: var(--body-width) !important;
|
||||||
}
|
}
|
||||||
/* HULU MINIMIZED VIDEO */
|
/* HULU MINIMIZED VIDEO */
|
||||||
@@ -130,16 +153,79 @@ body.peacock.visible .playback-header__container {
|
|||||||
position: relative;
|
position: relative;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
|
/* GOOGLE PLAY STYLING */
|
||||||
|
body.googleplay.visible {
|
||||||
|
-webkit-font-smoothing: initial !important;
|
||||||
|
}
|
||||||
|
body.googleplay.visible div.llhEMd.bYEzqc.LAhoGb.iWO5td > div.mjANdc.eEPege {
|
||||||
|
padding: 0 !important;
|
||||||
|
}
|
||||||
|
body.googleplay.visible
|
||||||
|
div.llhEMd.bYEzqc.LAhoGb.iWO5td
|
||||||
|
> div.mjANdc.eEPege
|
||||||
|
> div.LhXUod.XL54pf.J9Nfi.iWO5td,
|
||||||
|
body.googleplay.visible
|
||||||
|
div.llhEMd.bYEzqc.LAhoGb.iWO5td
|
||||||
|
> div
|
||||||
|
> div.LhXUod.XL54pf.J9Nfi.iWO5td
|
||||||
|
> span
|
||||||
|
> div
|
||||||
|
> div
|
||||||
|
> iframe {
|
||||||
|
min-height: 100%;
|
||||||
|
width: 100% !important;
|
||||||
|
height: 100% !important;
|
||||||
|
}
|
||||||
|
body.googleplay.visible
|
||||||
|
div.llhEMd.bYEzqc.LAhoGb.iWO5td
|
||||||
|
> div
|
||||||
|
> div.LhXUod.XL54pf.J9Nfi.iWO5td
|
||||||
|
> span
|
||||||
|
> div,
|
||||||
|
body.googleplay.visible
|
||||||
|
div.llhEMd.bYEzqc.LAhoGb.iWO5td
|
||||||
|
> div
|
||||||
|
> div.LhXUod.XL54pf.J9Nfi.iWO5td
|
||||||
|
> span
|
||||||
|
> div
|
||||||
|
> div {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
/* CRUNCHYROLL STYLING */
|
||||||
|
body.crunchyroll.visible #party-routes-wrapper input {
|
||||||
|
border: initial !important;
|
||||||
|
}
|
||||||
|
body.crunchyroll.visible header {
|
||||||
|
z-index: 0 !important;
|
||||||
|
}
|
||||||
|
body.crunchyroll.visible #showmedia_video {
|
||||||
|
position: fixed;
|
||||||
|
z-index: 99999;
|
||||||
|
width: calc(100% - var(--party-width));
|
||||||
|
background: black;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
body.crunchyroll.visible #showmedia_video_box {
|
||||||
|
width: 100% !important;
|
||||||
|
height: 100% !important;
|
||||||
|
}
|
||||||
|
body.crunchyroll.visible #showmedia_video_player {
|
||||||
|
display: flex !important;
|
||||||
|
align-items: center !important;
|
||||||
|
}
|
||||||
|
body.crunchyroll.visible #vilos-player {
|
||||||
|
max-height: 42vw !important;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
body.hulu #party_wrapper *,
|
||||||
FULL SCREEN BUTTON REMOVER
|
body.peacock #party_wrapper *,
|
||||||
*/
|
body.disney #party_wrapper * {
|
||||||
body.netflix
|
box-sizing: inherit;
|
||||||
.touchable.PlayerControls--control-element.nfp-button-control.default-control-button.button-nfplayerFullscreen,
|
|
||||||
body.hulu .controls__view-mode-button-normal-icon.player-svgicon,
|
|
||||||
body.disney .control-icon-btn.fullscreen-icon,
|
|
||||||
body.amazon .fyysciv.f1lobqlo.fk0j80b {
|
|
||||||
display: none;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#party-loading {
|
#party-loading {
|
||||||
@@ -179,13 +265,13 @@ body.amazon .fyysciv.f1lobqlo.fk0j80b {
|
|||||||
background-color: rgb(27, 27, 27);
|
background-color: rgb(27, 27, 27);
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
right: var(--neg-party-width);
|
right: var(--neg-party-width);
|
||||||
transition: all ease-in-out 0.3s;
|
|
||||||
width: var(--party-width);
|
width: var(--party-width);
|
||||||
height: 100%;
|
height: 100%;
|
||||||
color: white;
|
color: white;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
z-index: 9999;
|
z-index: 9999;
|
||||||
|
transition: all ease-in-out 0.3s !important;
|
||||||
}
|
}
|
||||||
#party-routes-wrapper.visible {
|
#party-routes-wrapper.visible {
|
||||||
right: 0;
|
right: 0;
|
||||||
@@ -216,11 +302,11 @@ body.amazon .fyysciv.f1lobqlo.fk0j80b {
|
|||||||
.watch-party-fab {
|
.watch-party-fab {
|
||||||
z-index: 9999;
|
z-index: 9999;
|
||||||
position: fixed !important;
|
position: fixed !important;
|
||||||
bottom: 1rem !important;
|
top: calc(100% - 75px) !important;
|
||||||
right: -2rem !important;
|
right: -2rem !important;
|
||||||
border: 1px solid white;
|
border: 1px solid white;
|
||||||
background-color: black !important;
|
background-color: black !important;
|
||||||
/* background-image: url('/android-icon-192x192.png'); */
|
transition: all ease-in-out 0.3s !important;
|
||||||
background-image: url('chrome-extension://__MSG_@@extension_id__/android-icon-192x192.png');
|
background-image: url('chrome-extension://__MSG_@@extension_id__/android-icon-192x192.png');
|
||||||
background-position: center;
|
background-position: center;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
@@ -243,10 +329,13 @@ body.amazon .fyysciv.f1lobqlo.fk0j80b {
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
max-height: 100% !important;
|
||||||
|
overflow-y: auto !important;
|
||||||
background: #424242;
|
background: #424242;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
.party-create-container .brand-title {
|
.party-create-container .brand-title {
|
||||||
|
font-size: 18px !important;
|
||||||
padding: 36px;
|
padding: 36px;
|
||||||
letter-spacing: 3.5px !important;
|
letter-spacing: 3.5px !important;
|
||||||
}
|
}
|
||||||
@@ -260,6 +349,7 @@ body.amazon .fyysciv.f1lobqlo.fk0j80b {
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
background: #424242;
|
background: #424242;
|
||||||
|
box-shadow: none !important;
|
||||||
}
|
}
|
||||||
.create-input-card * {
|
.create-input-card * {
|
||||||
font-size: 12px !important;
|
font-size: 12px !important;
|
||||||
@@ -271,9 +361,6 @@ body.amazon .fyysciv.f1lobqlo.fk0j80b {
|
|||||||
.party-create-container .create-input-card .create-pin {
|
.party-create-container .create-input-card .create-pin {
|
||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem;
|
||||||
}
|
}
|
||||||
.party-create-container .create-input-card {
|
|
||||||
background-color: #2d2d2d;
|
|
||||||
}
|
|
||||||
.create-bottom-card {
|
.create-bottom-card {
|
||||||
background-color: #202020;
|
background-color: #202020;
|
||||||
padding: 30px 15px;
|
padding: 30px 15px;
|
||||||
@@ -288,12 +375,12 @@ body.amazon .fyysciv.f1lobqlo.fk0j80b {
|
|||||||
.create-bottom-card a:hover {
|
.create-bottom-card a:hover {
|
||||||
color: #c0f300;
|
color: #c0f300;
|
||||||
}
|
}
|
||||||
.thread-container {
|
.thread-wrapper {
|
||||||
max-height: 100%;
|
max-height: 100%;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem;
|
||||||
padding: 0 15px;
|
padding: 0;
|
||||||
margin-top: 1rem;
|
margin-top: 1rem;
|
||||||
}
|
}
|
||||||
.room-title {
|
.room-title {
|
||||||
@@ -303,17 +390,6 @@ body.amazon .fyysciv.f1lobqlo.fk0j80b {
|
|||||||
padding-right: 1rem !important;
|
padding-right: 1rem !important;
|
||||||
font-size: 18px !important;
|
font-size: 18px !important;
|
||||||
}
|
}
|
||||||
.thread-container::-webkit-scrollbar {
|
|
||||||
width: 5px;
|
|
||||||
}
|
|
||||||
.thread-container::-webkit-scrollbar-track {
|
|
||||||
background-color: rgb(90, 90, 90);
|
|
||||||
border-radius: 1rem;
|
|
||||||
}
|
|
||||||
.thread-container::-webkit-scrollbar-thumb {
|
|
||||||
background-color: rgb(180, 180, 180);
|
|
||||||
border-radius: 13px;
|
|
||||||
}
|
|
||||||
textarea::-webkit-scrollbar {
|
textarea::-webkit-scrollbar {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
@@ -430,40 +506,6 @@ textarea::-webkit-scrollbar {
|
|||||||
color: inherit !important;
|
color: inherit !important;
|
||||||
font-size: 10px !important;
|
font-size: 10px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.giphy-carousel::before {
|
|
||||||
position: relative;
|
|
||||||
bottom: 90px;
|
|
||||||
margin-left: 40px;
|
|
||||||
content: url('./Giphy.png');
|
|
||||||
}
|
|
||||||
.giphy-carousel {
|
|
||||||
margin-top: 1rem;
|
|
||||||
min-height: fit-content;
|
|
||||||
padding-bottom: 3rem;
|
|
||||||
}
|
|
||||||
.giphy-carousel img {
|
|
||||||
border-radius: 1rem;
|
|
||||||
transform: scale(0.85);
|
|
||||||
transition: all ease-in-out 0.2s;
|
|
||||||
opacity: 0.7;
|
|
||||||
}
|
|
||||||
.giphy-carousel img:hover {
|
|
||||||
opacity: 1;
|
|
||||||
transform: scale(0.9);
|
|
||||||
}
|
|
||||||
|
|
||||||
.giphy-carousel::-webkit-scrollbar {
|
|
||||||
width: 5px;
|
|
||||||
height: 12px;
|
|
||||||
}
|
|
||||||
.giphy-carousel::-webkit-scrollbar-track {
|
|
||||||
background-color: rgb(90, 90, 90);
|
|
||||||
}
|
|
||||||
.giphy-carousel::-webkit-scrollbar-thumb {
|
|
||||||
background-color: #c0f300;
|
|
||||||
border-radius: 13px;
|
|
||||||
}
|
|
||||||
.message-send svg {
|
.message-send svg {
|
||||||
transform: scale(0.55);
|
transform: scale(0.55);
|
||||||
transition: all ease 0.5s !important;
|
transition: all ease 0.5s !important;
|
||||||
@@ -478,6 +520,7 @@ textarea::-webkit-scrollbar {
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
margin: 0 15px 15px 15px;
|
margin: 0 15px 15px 15px;
|
||||||
|
margin-bottom: 0px;
|
||||||
border-radius: 26px;
|
border-radius: 26px;
|
||||||
}
|
}
|
||||||
.text-phone-panel .icon-button {
|
.text-phone-panel .icon-button {
|
||||||
@@ -487,18 +530,24 @@ textarea::-webkit-scrollbar {
|
|||||||
}
|
}
|
||||||
.text-phone-panel .gif-button.gif-close {
|
.text-phone-panel .gif-button.gif-close {
|
||||||
padding: 12px 0 !important;
|
padding: 12px 0 !important;
|
||||||
|
max-height: 100%;
|
||||||
|
margin-left: -5px;
|
||||||
}
|
}
|
||||||
.text-phone-panel .gif-button {
|
.text-phone-panel .gif-button {
|
||||||
border-radius: 0 !important;
|
border-radius: 0 !important;
|
||||||
height: 1.75em !important;
|
height: 1.75em !important;
|
||||||
|
padding: 0 6px;
|
||||||
|
border-radius: 26px !important;
|
||||||
|
border-top-right-radius: 0 !important;
|
||||||
|
border-bottom-right-radius: 0 !important;
|
||||||
}
|
}
|
||||||
.text-phone-panel .gif-button svg {
|
.text-phone-panel .gif-button svg {
|
||||||
width: 1.75em !important;
|
width: 32px !important;
|
||||||
height: 1.75em !important;
|
height: 32px !important;
|
||||||
}
|
}
|
||||||
.text-phone-panel .gif-button.gif-close svg {
|
.text-phone-panel .gif-button.gif-close svg {
|
||||||
width: 2em !important;
|
height: 25px !important;
|
||||||
height: 1.5em !important;
|
width: 25px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.MuiTooltip-popper {
|
.MuiTooltip-popper {
|
||||||
@@ -533,6 +582,18 @@ body.amazon-prime .notification-switch .MuiSwitch-thumb {
|
|||||||
|
|
||||||
.alerts-container {
|
.alerts-container {
|
||||||
margin: 5px 0;
|
margin: 5px 0;
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
padding: 5px 0;
|
||||||
|
z-index: 999 !important;
|
||||||
|
background: #1b1b1b;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert-card {
|
||||||
|
border: none !important;
|
||||||
|
border-radius: 26px !important;
|
||||||
|
margin: 0px 10px !important;
|
||||||
|
margin-bottom: 5px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.alert-card-content {
|
.alert-card-content {
|
||||||
@@ -548,6 +609,10 @@ body.amazon-prime .notification-switch .MuiSwitch-thumb {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
|
flex: 1;
|
||||||
|
text-align: center !important;
|
||||||
|
justify-content: center;
|
||||||
|
max-width: 90% !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
#mic-permission-overlay {
|
#mic-permission-overlay {
|
||||||
@@ -586,5 +651,262 @@ body.amazon-prime .notification-switch .MuiSwitch-thumb {
|
|||||||
font-size: 14px !important;
|
font-size: 14px !important;
|
||||||
letter-spacing: 1.75px !important;
|
letter-spacing: 1.75px !important;
|
||||||
font-weight: 300 !important;
|
font-weight: 300 !important;
|
||||||
|
color: black !important;
|
||||||
|
border-radius: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.MuiAutocomplete-popper {
|
||||||
|
z-index: 99999 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.MuiAutocomplete-popper * {
|
||||||
|
color: white !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-only-switch {
|
||||||
|
margin-bottom: 20px !important;
|
||||||
|
transition: all ease-in 0.3s !important;
|
||||||
|
height: 70px !important;
|
||||||
|
margin-top: 0 !important;
|
||||||
|
overflow: hidden;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
.admin-only-switch.admin-only-switch-hidden {
|
||||||
|
height: 0 !important;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.replying-to-card {
|
||||||
|
display: flex !important;
|
||||||
|
padding: 15px 20px 500px 20px !important;
|
||||||
|
border: none !important;
|
||||||
|
border-top-left-radius: 26px !important;
|
||||||
|
border-top-right-radius: 26px !important;
|
||||||
|
margin-bottom: -554px !important;
|
||||||
|
opacity: 0 !important;
|
||||||
|
transition: all ease-in-out 0.3s !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.replying-to-card.replying-to-card-up {
|
||||||
|
margin-bottom: -480px !important;
|
||||||
|
opacity: 1 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.replying-to-content {
|
||||||
|
flex: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.replying-to-content img {
|
||||||
|
max-height: 75px;
|
||||||
|
border-radius: 26px;
|
||||||
|
}
|
||||||
|
.replying-to-content p {
|
||||||
|
font-size: 11px;
|
||||||
|
letter-spacing: 1.2px;
|
||||||
|
font-weight: 100;
|
||||||
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
|
white-space: nowrap;
|
||||||
|
max-width: 100%;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
.replying-to-card button {
|
||||||
|
align-self: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.giphy-wrapper.giphy-wrapper-down {
|
||||||
|
padding-top: 30px;
|
||||||
|
margin-bottom: -350px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.giphy-wrapper.giphy-wrapper-down .giphy-list-wrapper {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.giphy-wrapper {
|
||||||
|
padding-top: 0px;
|
||||||
|
transition: all ease-in-out 0.3s;
|
||||||
|
position: relative;
|
||||||
|
box-sizing: content-box !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.giphy-list-wrapper {
|
||||||
|
max-height: 350px !important;
|
||||||
|
overflow-y: auto !important;
|
||||||
|
overflow-x: hidden;
|
||||||
|
padding: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.giphy-list-wrapper > div {
|
||||||
|
box-sizing: border-box !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.thread-wrapper::-webkit-scrollbar,
|
||||||
|
.giphy-list-wrapper::-webkit-scrollbar {
|
||||||
|
width: 5px;
|
||||||
|
background-color: transparent;
|
||||||
|
transition: all ease-in-out 0.3s;
|
||||||
|
}
|
||||||
|
.thread-wrapper::-webkit-scrollbar:hover,
|
||||||
|
.giphy-list-wrapper::-webkit-scrollbar:hover {
|
||||||
|
background-color: #424242;
|
||||||
|
}
|
||||||
|
.thread-wrapper::-webkit-scrollbar-track,
|
||||||
|
.giphy-list-wrapper::-webkit-scrollbar-track {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
.thread-wrapper::-webkit-scrollbar-thumb,
|
||||||
|
.giphy-list-wrapper::-webkit-scrollbar-thumb {
|
||||||
|
background-color: #bef300ad;
|
||||||
|
border-radius: 26px !important;
|
||||||
|
}
|
||||||
|
.thread-wrapper::-webkit-scrollbar-thumb:hover,
|
||||||
|
.giphy-list-wrapper::-webkit-scrollbar-thumb:hover {
|
||||||
|
background-color: #c0f300;
|
||||||
|
}
|
||||||
|
|
||||||
|
.giphy-search-form {
|
||||||
|
height: 0;
|
||||||
|
width: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
button.giphy-list-item {
|
||||||
|
display: inline-block;
|
||||||
|
position: relative !important;
|
||||||
|
height: fit-content;
|
||||||
|
vertical-align: top;
|
||||||
|
top: unset !important;
|
||||||
|
overflow: hidden;
|
||||||
|
background: unset !important;
|
||||||
|
left: unset !important;
|
||||||
|
cursor: pointer;
|
||||||
|
outline: none !important;
|
||||||
|
border: none !important;
|
||||||
|
opacity: 0.3;
|
||||||
|
transition: all ease-in-out 0.3s;
|
||||||
|
width: 50%;
|
||||||
|
max-width: 200px;
|
||||||
|
max-height: 100px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.giphy-list-item:hover {
|
||||||
|
opacity: 1;
|
||||||
|
max-height: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.giphy-list-item img {
|
||||||
|
height: 100%;
|
||||||
|
margin: 5px;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.giphy-wrapper > div:nth-child(3) {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
color: black;
|
||||||
|
padding: 5px 15px;
|
||||||
|
padding-right: 25px;
|
||||||
|
border-top-right-radius: 26px;
|
||||||
|
padding-top: 15px;
|
||||||
|
border-top: 1px solid gray;
|
||||||
|
border-right: 1px solid gray;
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
background-color: rgba(255, 255, 255, 0.2);
|
||||||
|
transition: all ease-in-out 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.giphy-wrapper > div:nth-child(3):hover {
|
||||||
|
background-color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.giphy-wrapper > div:nth-child(3) > img {
|
||||||
|
filter: invert(1);
|
||||||
|
vertical-align: unset;
|
||||||
|
max-height: 20px;
|
||||||
|
filter: drop-shadow(0px 0px 0px black);
|
||||||
|
mix-blend-mode: darken;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.giphy-wrapper > .giphy-list-wrapper > div > div:nth-child(1) {
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.create-settings-card {
|
||||||
|
margin: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.create-settings-card .create-settings-title {
|
||||||
|
margin-left: 15px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.create-settings-card .MuiExpansionPanelDetails-root {
|
||||||
|
flex-direction: column !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.create-settings-card button {
|
||||||
|
font-size: 12px !important;
|
||||||
|
margin-top: 25px !important;
|
||||||
|
text-align: center !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alerts-stepper-container {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alerts-stepper-card {
|
||||||
|
margin-bottom: 15px;
|
||||||
|
border-radius: 26px !important;
|
||||||
|
background: #202020 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alerts-stepper-card span {
|
||||||
|
font-size: 11px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alerts-stepper-card p {
|
||||||
|
font-size: 14px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alerts-stepper-card .MuiCardActions-root {
|
||||||
|
padding-left: 0 !important;
|
||||||
|
padding-right: 0 !important;
|
||||||
|
padding-bottom: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alerts-stepper-card .MuiCardActions-root a {
|
||||||
|
flex: 1;
|
||||||
|
border-top-left-radius: 0 !important;
|
||||||
|
border-top-right-radius: 0 !important;
|
||||||
|
border-bottom-left-radius: 26px !important;
|
||||||
|
border-bottom-right-radius: 26px !important;
|
||||||
|
padding: 10px;
|
||||||
color: #c0f300 !important;
|
color: #c0f300 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.alerts-stepper-controls {
|
||||||
|
position: relative !important;
|
||||||
|
background: transparent !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alerts-stepper-controls .MuiMobileStepper-dot.MuiMobileStepper-dotActive {
|
||||||
|
background-color: #c0f300 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alerts-stepper-controls button {
|
||||||
|
margin-top: 0 !important;
|
||||||
|
padding: 5px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.party-controls-users-volume {
|
||||||
|
min-width: 150px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.party-controls-users-volume .MuiGrid-root.MuiGrid-item {
|
||||||
|
display: flex !important;
|
||||||
|
justify-content: center !important;
|
||||||
|
align-items: center !important;
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,16 +5,9 @@ Proprietary and confidential
|
|||||||
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
||||||
https://www.chromewatchparty.com/copyright
|
https://www.chromewatchparty.com/copyright
|
||||||
=========================================================================
|
=========================================================================
|
||||||
ALL CONTENT ON IN WATCH PARTY'S CHROME EXTENSION APP, UNLESS OTHERWISE
|
ALL CONTENT ON WATCH PARTY'S WEBSITE OR IN WATCH PARTY'S CHROME EXTENSION APP, UNLESS OTHERWISE
|
||||||
CITED ARE THE SOLE INTELECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE
|
CITED ARE THE SOLE INTELECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE
|
||||||
COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
|
COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
|
||||||
|
|
||||||
Netflix logo is a trademark and intellectual property of Netflix, Inc.
|
|
||||||
Disney+ logo is a trademark and intellectual property of The Walt Disney Company
|
|
||||||
Prime logo is a trademark and intellectual property of Amazon.com, Inc.
|
|
||||||
YouTube logo is a trademark and intellectual property of Google, Inc.
|
|
||||||
Hulu logo is a trademark and intellectual property of Hulu, LLC.
|
|
||||||
HBO Now and HBO Max logos are trademark and intellectual property of WarnerMedia Direct,LLC.
|
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
@@ -86,7 +79,7 @@ switch (getPlayerSource()) {
|
|||||||
break;
|
break;
|
||||||
case PLAYER_SOURCE.HBONOW:
|
case PLAYER_SOURCE.HBONOW:
|
||||||
case PLAYER_SOURCE.HBOMAX:
|
case PLAYER_SOURCE.HBOMAX:
|
||||||
const hboClickInject = `var hboInputFix=function(ev){if(ev.target.tagName==='INPUT'||ev.target.tagName==='TEXTAREA'){ev.target.focus();}ev.stopImmediatePropagation();ev.stopPropagation();};document.addEventListener('keydown',hboInputFix,{capture:true});var hboClickFix=function(ev){if(document.querySelector('body.visible')){if(ev.clientX > window.innerWidth - 400){if(ev.target.tagName==='INPUT'||ev.target.tagName==='TEXTAREA'){ev.target.focus();}ev.preventDefault();ev.stopPropagation();ev.stopImmediatePropagation();}}};document.addEventListener("mousedown",hboClickFix,{capture:true});`;
|
const hboClickInject = `var hboInputFix=function(ev){if(ev.target.tagName==='INPUT'||ev.target.tagName==='TEXTAREA'){ev.target.focus();}ev.stopImmediatePropagation();ev.stopPropagation();};document.addEventListener('keydown',hboInputFix,{capture:true});var hboClickFix=function(ev){if(document.querySelector('body.visible')){if(ev.clientX > window.innerWidth - (parseInt(document.documentElement.style.getPropertyValue('--party-width').slice(0,-2)) + 50) ){if(ev.target.tagName==='INPUT'||ev.target.tagName==='TEXTAREA'){ev.target.focus();}ev.preventDefault();ev.stopPropagation();ev.stopImmediatePropagation();}}};document.addEventListener("mousedown",hboClickFix,{capture:true});`;
|
||||||
const hboClickInjectScript = document.createElement('script');
|
const hboClickInjectScript = document.createElement('script');
|
||||||
hboClickInjectScript.text = hboClickInject;
|
hboClickInjectScript.text = hboClickInject;
|
||||||
document.head.appendChild(hboClickInjectScript);
|
document.head.appendChild(hboClickInjectScript);
|
||||||
@@ -95,6 +88,12 @@ switch (getPlayerSource()) {
|
|||||||
case PLAYER_SOURCE.PEACOCK:
|
case PLAYER_SOURCE.PEACOCK:
|
||||||
document.body.classList.add('peacock');
|
document.body.classList.add('peacock');
|
||||||
break;
|
break;
|
||||||
|
case PLAYER_SOURCE.GOOGLEPLAY:
|
||||||
|
document.body.classList.add('googleplay');
|
||||||
|
break;
|
||||||
|
case PLAYER_SOURCE.CRUNCHYROLL:
|
||||||
|
document.body.classList.add('crunchyroll');
|
||||||
|
break;
|
||||||
case PLAYER_SOURCE.LOCAL:
|
case PLAYER_SOURCE.LOCAL:
|
||||||
document.body.classList.add('local');
|
document.body.classList.add('local');
|
||||||
break;
|
break;
|
||||||
|
|||||||
|
After Width: | Height: | Size: 81 KiB |
|
After Width: | Height: | Size: 68 KiB |
|
After Width: | Height: | Size: 72 KiB |
|
After Width: | Height: | Size: 45 KiB |
|
After Width: | Height: | Size: 64 KiB |
|
Before Width: | Height: | Size: 57 KiB |
|
After Width: | Height: | Size: 67 KiB |
|
Before Width: | Height: | Size: 66 KiB |
|
After Width: | Height: | Size: 89 KiB |
|
After Width: | Height: | Size: 77 KiB |
|
After Width: | Height: | Size: 88 KiB |
|
After Width: | Height: | Size: 90 KiB |
|
After Width: | Height: | Size: 65 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 7.9 KiB |
|
Before Width: | Height: | Size: 51 KiB |
|
Before Width: | Height: | Size: 62 KiB |
|
Before Width: | Height: | Size: 76 KiB |
|
Before Width: | Height: | Size: 88 KiB |
|
Before Width: | Height: | Size: 85 KiB |
|
Before Width: | Height: | Size: 75 KiB |
@@ -1,13 +1,21 @@
|
|||||||
const FunctionModules = require('./modules/index');
|
const FunctionModules = require('./modules/index');
|
||||||
const FunctionModules2 = require('./modules2/index');
|
const FunctionModules2 = require('./modules2/index');
|
||||||
|
const Webhooks = require('./webhooks/index');
|
||||||
const express = require('express');
|
const express = require('express');
|
||||||
const cors = require('cors');
|
const cors = require('cors');
|
||||||
|
|
||||||
|
// WEBHOOKS
|
||||||
|
const webhooks = express();
|
||||||
|
webhooks.use(cors({ origin: true }));
|
||||||
|
webhooks.all('/conferenceEnded', Webhooks.conferenceEnd);
|
||||||
|
webhooks.all('/scheduledCleanup', Webhooks.scheduledCleanUp);
|
||||||
|
webhooks.all('/ask', Webhooks.ask);
|
||||||
|
|
||||||
// VERSION 1
|
// VERSION 1
|
||||||
const app = express();
|
const app = express();
|
||||||
app.use(cors({ origin: true }));
|
app.use(cors({ origin: true }));
|
||||||
app.use(FunctionModules.authenticator);
|
app.use(FunctionModules.authenticator);
|
||||||
app.get('/validator', FunctionModules.tokenValidator);
|
app.get('/validator/:partyName', FunctionModules.tokenValidator);
|
||||||
app.get('/refresher/:token', FunctionModules.tokenRefresher);
|
app.get('/refresher/:token', FunctionModules.tokenRefresher);
|
||||||
app.post('/create', FunctionModules.createRoom);
|
app.post('/create', FunctionModules.createRoom);
|
||||||
app.post('/join', FunctionModules.joinRoom);
|
app.post('/join', FunctionModules.joinRoom);
|
||||||
@@ -16,6 +24,7 @@ app.post('/updatePlayer', FunctionModules.updatePlayer);
|
|||||||
app.post('/updateVoxeet', FunctionModules.updateVoxeet);
|
app.post('/updateVoxeet', FunctionModules.updateVoxeet);
|
||||||
app.delete('/leave/:rid/users/:uid', FunctionModules.leaveRoom);
|
app.delete('/leave/:rid/users/:uid', FunctionModules.leaveRoom);
|
||||||
app.delete('/delete/:rid', FunctionModules.deleteRoom);
|
app.delete('/delete/:rid', FunctionModules.deleteRoom);
|
||||||
|
app.put('/updateAdminOnly/:rid/:adminOnly', FunctionModules.updateAdminOnly);
|
||||||
|
|
||||||
// VERSION 2
|
// VERSION 2
|
||||||
const app2 = express();
|
const app2 = express();
|
||||||
@@ -34,4 +43,5 @@ app2.delete('/delete/:rid', FunctionModules2.deleteRoom);
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
v1: app,
|
v1: app,
|
||||||
v2: app2,
|
v2: app2,
|
||||||
|
webhooks,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
const FunctionModules = require('./modules/index');
|
|
||||||
const functions = require('firebase-functions');
|
const functions = require('firebase-functions');
|
||||||
const secret = require('./FirebaseSecret.json');
|
const secret = require('./FirebaseSecret.json');
|
||||||
const admin = require('firebase-admin');
|
const admin = require('firebase-admin');
|
||||||
@@ -15,7 +14,5 @@ admin.initializeApp(FIREBASE_OPTIONS);
|
|||||||
exports.widgets = functions.https.onRequest(REST.v1);
|
exports.widgets = functions.https.onRequest(REST.v1);
|
||||||
// VERSION 2
|
// VERSION 2
|
||||||
exports.widgets2 = functions.https.onRequest(REST.v2);
|
exports.widgets2 = functions.https.onRequest(REST.v2);
|
||||||
|
// WEBHOOKS
|
||||||
exports.scheduledCleanUp = functions.pubsub
|
exports.webhooks = functions.https.onRequest(REST.webhooks);
|
||||||
.schedule('every 60 minutes')
|
|
||||||
.onRun(FunctionModules.scheduledCleanUp);
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ module.exports = (req, res, next) => {
|
|||||||
bodydata.uid = user.uid;
|
bodydata.uid = user.uid;
|
||||||
req.body = JSON.stringify(bodydata);
|
req.body = JSON.stringify(bodydata);
|
||||||
}
|
}
|
||||||
if (req.method === 'GET' || req.method === 'DELETE') {
|
if (req.method === 'GET' || req.method === 'DELETE' || req.method === 'PUT') {
|
||||||
req.body = JSON.stringify({ uid: user.uid });
|
req.body = JSON.stringify({ uid: user.uid });
|
||||||
}
|
}
|
||||||
return next();
|
return next();
|
||||||
|
|||||||
@@ -1,32 +0,0 @@
|
|||||||
const admin = require('firebase-admin');
|
|
||||||
|
|
||||||
module.exports = async (roomId) => {
|
|
||||||
admin
|
|
||||||
.firestore()
|
|
||||||
.collection('rooms')
|
|
||||||
.doc(roomId)
|
|
||||||
.collection('messages')
|
|
||||||
.listDocuments()
|
|
||||||
.then((messages) => messages.forEach((message) => message.delete()))
|
|
||||||
.catch((err) => {
|
|
||||||
console.error(`Failed to run auto clean up (delete room messages) @ ${roomId}`, err);
|
|
||||||
});
|
|
||||||
admin
|
|
||||||
.firestore()
|
|
||||||
.collection('rooms')
|
|
||||||
.doc(roomId)
|
|
||||||
.collection('users')
|
|
||||||
.listDocuments()
|
|
||||||
.then((users) => users.forEach((user) => user.delete()))
|
|
||||||
.catch((err) => {
|
|
||||||
console.error(`Failed to run auto clean up (delete room users) @ ${roomId}`, err);
|
|
||||||
});
|
|
||||||
admin
|
|
||||||
.firestore()
|
|
||||||
.collection('rooms')
|
|
||||||
.doc(roomId)
|
|
||||||
.delete()
|
|
||||||
.catch((err) => {
|
|
||||||
console.error(`Failed to run auto clean up (delete room) @ ${roomId}`, err);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
@@ -24,6 +24,7 @@ module.exports = async (req, res) => {
|
|||||||
createdAt: new Date(),
|
createdAt: new Date(),
|
||||||
updatedAt: new Date(),
|
updatedAt: new Date(),
|
||||||
adminUid: bodydata.uid,
|
adminUid: bodydata.uid,
|
||||||
|
adminOnly: bodydata.adminOnly,
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
res.status(500).send({ message: 'Unable to start party.' });
|
res.status(500).send({ message: 'Unable to start party.' });
|
||||||
@@ -46,23 +47,6 @@ module.exports = async (req, res) => {
|
|||||||
err
|
err
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
await admin
|
|
||||||
.firestore()
|
|
||||||
.collection('rooms')
|
|
||||||
.doc(bodydata.partyName)
|
|
||||||
.collection('messages')
|
|
||||||
.add({
|
|
||||||
uid: '<system>',
|
|
||||||
name: '',
|
|
||||||
text: `Voice calls are unavailable temporarily. Voice calls will be back within 12 hours.`,
|
|
||||||
time: new Date(),
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
console.error(
|
|
||||||
`Failed to add system voice call message : \n\t Room: ${bodydata.partyName}`,
|
|
||||||
err
|
|
||||||
);
|
|
||||||
});
|
|
||||||
await admin
|
await admin
|
||||||
.firestore()
|
.firestore()
|
||||||
.collection('rooms')
|
.collection('rooms')
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ const admin = require('firebase-admin');
|
|||||||
|
|
||||||
module.exports = async (req, res) => {
|
module.exports = async (req, res) => {
|
||||||
console.log('Requested Delete - Room - ', req.params.rid);
|
console.log('Requested Delete - Room - ', req.params.rid);
|
||||||
console.log(req.body);
|
|
||||||
const isAdmin = await admin
|
const isAdmin = await admin
|
||||||
.firestore()
|
.firestore()
|
||||||
.collection('rooms')
|
.collection('rooms')
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
const authenticator = require('./authenticator');
|
const authenticator = require('./authenticator');
|
||||||
const cleanUpRoom = require('./cleanUpRoom');
|
|
||||||
const scheduledCleanUp = require('./scheduledCleanUp');
|
|
||||||
const createRoom = require('./createRoom');
|
const createRoom = require('./createRoom');
|
||||||
const joinRoom = require('./joinRoom');
|
const joinRoom = require('./joinRoom');
|
||||||
const sendMessage = require('./sendMessage');
|
const sendMessage = require('./sendMessage');
|
||||||
@@ -11,6 +9,7 @@ const updatePlayer = require('./updatePlayer');
|
|||||||
const tokenValidator = require('./tokenValidator');
|
const tokenValidator = require('./tokenValidator');
|
||||||
const tokenRefresher = require('./tokenRefresher');
|
const tokenRefresher = require('./tokenRefresher');
|
||||||
const updateVoxeet = require('./updateVoxeet');
|
const updateVoxeet = require('./updateVoxeet');
|
||||||
|
const updateAdminOnly = require('./updateAdminOnly');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
authenticator,
|
authenticator,
|
||||||
@@ -20,10 +19,9 @@ module.exports = {
|
|||||||
updatePlayer,
|
updatePlayer,
|
||||||
leaveRoom,
|
leaveRoom,
|
||||||
deleteRoom,
|
deleteRoom,
|
||||||
scheduledCleanUp,
|
|
||||||
cleanUpRoom,
|
|
||||||
timeDiff,
|
timeDiff,
|
||||||
tokenValidator,
|
tokenValidator,
|
||||||
tokenRefresher,
|
tokenRefresher,
|
||||||
updateVoxeet,
|
updateVoxeet,
|
||||||
|
updateAdminOnly,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
const admin = require('firebase-admin');
|
const admin = require('firebase-admin');
|
||||||
const { firestore } = require('firebase-admin');
|
|
||||||
|
|
||||||
module.exports = async (req, res) => {
|
module.exports = async (req, res) => {
|
||||||
const bodydata = JSON.parse(req.body);
|
const bodydata = JSON.parse(req.body);
|
||||||
@@ -137,7 +136,7 @@ module.exports = async (req, res) => {
|
|||||||
.update({
|
.update({
|
||||||
player: {
|
player: {
|
||||||
showName: null,
|
showName: null,
|
||||||
source: null,
|
source: bodydata.source,
|
||||||
status: 'NOT_PLAYING',
|
status: 'NOT_PLAYING',
|
||||||
time: 0,
|
time: 0,
|
||||||
updatedBy: bodydata.uid,
|
updatedBy: bodydata.uid,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
const admin = require('firebase-admin');
|
const admin = require('firebase-admin');
|
||||||
|
|
||||||
module.exports = async (req, res) => {
|
module.exports = async (req, res) => {
|
||||||
const { name, text, uid, roomId, type } = JSON.parse(req.body);
|
const { name, text, uid, roomId, type, replyTo } = JSON.parse(req.body);
|
||||||
|
|
||||||
const roomExists = await admin
|
const roomExists = await admin
|
||||||
.firestore()
|
.firestore()
|
||||||
@@ -21,6 +21,7 @@ module.exports = async (req, res) => {
|
|||||||
time: new Date(),
|
time: new Date(),
|
||||||
uid,
|
uid,
|
||||||
type: type || '',
|
type: type || '',
|
||||||
|
replyTo: replyTo || null,
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
console.error(`Failed to send message to party : \n\t Room: ${roomId} \n\t ${uid}`, err);
|
console.error(`Failed to send message to party : \n\t Room: ${roomId} \n\t ${uid}`, err);
|
||||||
|
|||||||
@@ -1,21 +1,20 @@
|
|||||||
const VoxeetSecret = require('../VoxeetSecret.json');
|
const VoxeetSecret = require('../VoxeetSecret.json');
|
||||||
module.exports = async (req, res) => {
|
module.exports = async (req, res) => {
|
||||||
res.status(403).send({ message: 'Voice calls are unavailable temporarily.' });
|
const { key, secret } = VoxeetSecret;
|
||||||
// const { key, secret } = VoxeetSecret;
|
const credentials = btoa(encodeURI(key) + ':' + encodeURI(secret));
|
||||||
// const credentials = btoa(encodeURI(key) + ':' + encodeURI(secret));
|
const headers = {
|
||||||
// const headers = {
|
'Content-Type': 'application/json',
|
||||||
// 'Content-Type': 'application/json',
|
'Cache-Control': 'no-cache',
|
||||||
// 'Cache-Control': 'no-cache',
|
Authorization: 'Basic ' + credentials,
|
||||||
// Authorization: 'Basic ' + credentials,
|
};
|
||||||
// };
|
const oauth = await fetch(VoxeetSecret.refreshURL, {
|
||||||
// const oauth = await fetch(VoxeetSecret.refreshURL, {
|
method: 'POST',
|
||||||
// method: 'POST',
|
headers,
|
||||||
// headers,
|
body: JSON.stringify({
|
||||||
// body: JSON.stringify({
|
refresh_token: req.params.token,
|
||||||
// refresh_token: req.params.token,
|
}),
|
||||||
// }),
|
})
|
||||||
// })
|
.then((oauthResponse) => oauthResponse.json())
|
||||||
// .then((oauthResponse) => oauthResponse.json())
|
.catch((err) => res.status(500).send(err));
|
||||||
// .catch((err) => res.status(500).send(err));
|
if (oauth) res.status(200).send(oauth);
|
||||||
// if (oauth) res.status(200).send(oauth);
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,22 +1,64 @@
|
|||||||
const VoxeetSecret = require('../VoxeetSecret.json');
|
const VoxeetSecret = require('../VoxeetSecret.json');
|
||||||
|
const admin = require('firebase-admin');
|
||||||
const fetch = require('node-fetch');
|
const fetch = require('node-fetch');
|
||||||
|
|
||||||
module.exports = async (req, res) => {
|
module.exports = async (req, res) => {
|
||||||
res.status(403).send({ message: 'Voice calls are unavailable temporarily.' });
|
const bodyData = JSON.parse(req.body);
|
||||||
// const { key, secret } = VoxeetSecret;
|
const { key, secret } = VoxeetSecret;
|
||||||
// const credentials = Buffer.from(encodeURI(key) + ':' + encodeURI(secret)).toString('base64');
|
const credentials = Buffer.from(encodeURI(key) + ':' + encodeURI(secret)).toString('base64');
|
||||||
// const headers = {
|
const headers = {
|
||||||
// 'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
// 'Cache-Control': 'no-cache',
|
'Cache-Control': 'no-cache',
|
||||||
// Authorization: 'Basic ' + credentials,
|
Authorization: 'Basic ' + credentials,
|
||||||
// };
|
};
|
||||||
// const oauth = await fetch(VoxeetSecret.validateURL, {
|
const oauth = await fetch(VoxeetSecret.validateURL, {
|
||||||
// method: 'POST',
|
method: 'POST',
|
||||||
// headers,
|
headers,
|
||||||
// body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
// grant_type: 'client_credentials',
|
grant_type: 'client_credentials',
|
||||||
// }),
|
}),
|
||||||
// })
|
}).then((oauthResponse) => oauthResponse.json())
|
||||||
// .then((oauthResponse) => oauthResponse.json())
|
.catch((err) => res.status(500).send({err, message: 'Unable to generate token for call'}));
|
||||||
// .catch((err) => res.status(500).send(err));
|
|
||||||
// if (oauth) res.status(200).send(oauth);
|
const [exists, conferencePending, conference, adminOnly, adminUid] = await admin
|
||||||
|
.firestore()
|
||||||
|
.collection('rooms')
|
||||||
|
.doc(req.params.partyName)
|
||||||
|
.get()
|
||||||
|
.then(snap => {
|
||||||
|
const data = snap.exists ? snap.data() : {};
|
||||||
|
return [snap.exists, data.conferencePending, data.conference, data.adminOnly, data.adminUid];
|
||||||
|
});
|
||||||
|
|
||||||
|
if (exists === true) {
|
||||||
|
if (conference === undefined || conference === null) {
|
||||||
|
if (conferencePending === undefined || conferencePending === null) {
|
||||||
|
if (!adminOnly || (adminOnly && (adminUid === bodyData.uid)) ) {
|
||||||
|
await admin
|
||||||
|
.firestore()
|
||||||
|
.collection('rooms')
|
||||||
|
.doc(req.params.partyName)
|
||||||
|
.update({
|
||||||
|
conferencePending: bodyData.uid
|
||||||
|
});
|
||||||
|
await admin
|
||||||
|
.firestore()
|
||||||
|
.collection('rooms')
|
||||||
|
.doc(req.params.partyName)
|
||||||
|
.collection('messages')
|
||||||
|
.add({
|
||||||
|
uid: '<system>',
|
||||||
|
name: '',
|
||||||
|
text: 'A call session is being created (will be available soon).',
|
||||||
|
time: new Date(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (oauth) res.status(200).send(oauth);
|
||||||
|
} else {
|
||||||
|
res.status(400).send({ message: 'Unable to get party for call.' });
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
const admin = require('firebase-admin');
|
||||||
|
|
||||||
|
module.exports = async (req, res) => {
|
||||||
|
const bodydata = JSON.parse(req.body);
|
||||||
|
const isAdmin = await admin
|
||||||
|
.firestore()
|
||||||
|
.collection('rooms')
|
||||||
|
.doc(req.params.rid)
|
||||||
|
.collection('users')
|
||||||
|
.doc(bodydata.uid)
|
||||||
|
.get()
|
||||||
|
.then((v) => {
|
||||||
|
if (v.exists) {
|
||||||
|
return v.data().admin;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.err('Failed to get party to update adminOnly', err);
|
||||||
|
return res.status(404).send({ message: 'Failed to get party.' });
|
||||||
|
});
|
||||||
|
if (!isAdmin) {
|
||||||
|
console.log('[UNAUTHORIZED] Requested Admin Mode Update - Room - ', req.params.rid);
|
||||||
|
res.status(401).send({ message: 'Not authorized to update admin only mode for this party.' });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const adminOnly = req.params.adminOnly === 'true';
|
||||||
|
await admin.firestore().collection('rooms').doc(req.params.rid).update({
|
||||||
|
adminOnly
|
||||||
|
}).catch((err) => {
|
||||||
|
console.err('Failed to update adminOnly for party', err);
|
||||||
|
res.status(409).send({ message: 'Failed to update party.' });
|
||||||
|
});
|
||||||
|
res.status(200).send({ message: 'Updated admin only mode for party' });
|
||||||
|
return;
|
||||||
|
};
|
||||||
@@ -2,18 +2,7 @@ const admin = require('firebase-admin');
|
|||||||
|
|
||||||
module.exports = async (req, res) => {
|
module.exports = async (req, res) => {
|
||||||
const { player, roomId, uid, showChanged, userName } = JSON.parse(req.body);
|
const { player, roomId, uid, showChanged, userName } = JSON.parse(req.body);
|
||||||
// const statusString =
|
if (!roomId) return res.status(204).send({ message: 'Party name not sent.' });
|
||||||
// player.status === 'PLAYING'
|
|
||||||
// ? 'started playing from'
|
|
||||||
// : player.status === 'PAUSED'
|
|
||||||
// ? 'paused at'
|
|
||||||
// : player.status === 'NOT_PLAYING'
|
|
||||||
// ? 'stopped at'
|
|
||||||
// : 'is at';
|
|
||||||
// const timeString =
|
|
||||||
// player.time > 3600
|
|
||||||
// ? new Date(player.time * 1000).toISOString().substr(11, 8)
|
|
||||||
// : new Date(player.time * 1000).toISOString().substr(14, 5);
|
|
||||||
const [roomExists, roomData] = await admin
|
const [roomExists, roomData] = await admin
|
||||||
.firestore()
|
.firestore()
|
||||||
.collection('rooms')
|
.collection('rooms')
|
||||||
@@ -30,18 +19,20 @@ module.exports = async (req, res) => {
|
|||||||
.get()
|
.get()
|
||||||
.then((userSnap) => userSnap.exists);
|
.then((userSnap) => userSnap.exists);
|
||||||
if (userExists) {
|
if (userExists) {
|
||||||
if (showChanged === true) {
|
if (showChanged === true && player.showName) {
|
||||||
await admin
|
if (roomData.player.showName !== player.showName) {
|
||||||
.firestore()
|
await admin
|
||||||
.collection('rooms')
|
.firestore()
|
||||||
.doc(roomId)
|
.collection('rooms')
|
||||||
.collection('messages')
|
.doc(roomId)
|
||||||
.add({
|
.collection('messages')
|
||||||
uid: '<system>',
|
.add({
|
||||||
name: '',
|
uid: '<system>',
|
||||||
text: `${userName} changed \n${player.showName ? 'to ' + player.showName : ''}`,
|
name: '',
|
||||||
time: new Date(),
|
text: `${userName} changed \n${player.showName ? 'to ' + player.showName : ''}`,
|
||||||
});
|
time: new Date(),
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (roomData.status !== player.status) {
|
if (roomData.status !== player.status) {
|
||||||
await admin
|
await admin
|
||||||
@@ -55,23 +46,6 @@ module.exports = async (req, res) => {
|
|||||||
console.error(`Failed to update player : \n\t Room: ${roomId} \n\t ${uid}`, err);
|
console.error(`Failed to update player : \n\t Room: ${roomId} \n\t ${uid}`, err);
|
||||||
res.status(500).send({ message: "Uh oh party could't be synced", err });
|
res.status(500).send({ message: "Uh oh party could't be synced", err });
|
||||||
});
|
});
|
||||||
// await admin
|
|
||||||
// .firestore()
|
|
||||||
// .collection('rooms')
|
|
||||||
// .doc(roomId)
|
|
||||||
// .collection('messages')
|
|
||||||
// .add({
|
|
||||||
// uid: '<system>',
|
|
||||||
// name: '',
|
|
||||||
// text: `${userName} ${statusString} ${timeString}`,
|
|
||||||
// time: new Date(),
|
|
||||||
// })
|
|
||||||
// .catch((err) => {
|
|
||||||
// console.error(
|
|
||||||
// `Failed to add system update player message : \n\t Room: ${roomId} \n\t ${uid}`,
|
|
||||||
// err
|
|
||||||
// );
|
|
||||||
// });
|
|
||||||
return res.status(200).send({ message: 'Synced party player' });
|
return res.status(200).send({ message: 'Synced party player' });
|
||||||
} else {
|
} else {
|
||||||
return res.status(208).send({ message: 'Player already up to date' });
|
return res.status(208).send({ message: 'Player already up to date' });
|
||||||
|
|||||||
@@ -1,47 +1,89 @@
|
|||||||
const admin = require('firebase-admin');
|
const admin = require("firebase-admin");
|
||||||
|
|
||||||
module.exports = async (req, res) => {
|
module.exports = async (req, res) => {
|
||||||
const { conference, partyName, partyPin, userName } = JSON.parse(req.body);
|
const { conference, partyName, partyPin, userName, uid } = JSON.parse(
|
||||||
|
req.body
|
||||||
|
);
|
||||||
// GET ROOM PIN
|
// GET ROOM PIN
|
||||||
const roomPin = await admin
|
const [exists, roomPin, conferencePending, partyConference] = await admin
|
||||||
.firestore()
|
.firestore()
|
||||||
.collection('rooms')
|
.collection("rooms")
|
||||||
.doc(partyName)
|
.doc(partyName)
|
||||||
.get()
|
.get()
|
||||||
.then((roomSnap) => (roomSnap.exists ? roomSnap.data().pin : null));
|
.then((roomSnap) => {
|
||||||
|
const data = roomSnap.exists ? roomSnap.data() : {};
|
||||||
|
return [
|
||||||
|
roomSnap.exists,
|
||||||
|
data.pin,
|
||||||
|
data.conferencePending,
|
||||||
|
data.conference,
|
||||||
|
];
|
||||||
|
});
|
||||||
// CHECK IF ROOM EXISTS
|
// CHECK IF ROOM EXISTS
|
||||||
if (roomPin) {
|
if (exists === true) {
|
||||||
// CHECK FOR CORRECT PIN
|
if (roomPin) {
|
||||||
if (roomPin === partyPin) {
|
// CHECK FOR CORRECT PIN
|
||||||
// UPDATE CONFERENCE DETAILS
|
if (roomPin === partyPin) {
|
||||||
await admin
|
if (conferencePending) {
|
||||||
.firestore()
|
if (conferencePending === uid) {
|
||||||
.collection('rooms')
|
// UPDATE CONFERENCE DETAILS
|
||||||
.doc(partyName)
|
await admin
|
||||||
.update({ conference })
|
.firestore()
|
||||||
.catch((err) =>
|
.collection("rooms")
|
||||||
res.status(500).send({ message: 'Unable to update the call details', error: err })
|
.doc(partyName)
|
||||||
);
|
.update({ conference })
|
||||||
// ADD SYSTEM MESSAGE
|
.catch((err) =>
|
||||||
await admin
|
res.status(500).send({
|
||||||
.firestore()
|
message: "Unable to update the call details",
|
||||||
.collection('rooms')
|
error: err,
|
||||||
.doc(partyName)
|
})
|
||||||
.collection('messages')
|
);
|
||||||
.add({
|
// REMOVE PENDING STATUS
|
||||||
uid: '<system>',
|
await admin
|
||||||
name: '',
|
.firestore()
|
||||||
text: `${userName} started the call.`,
|
.collection("rooms")
|
||||||
time: new Date(),
|
.doc(partyName)
|
||||||
})
|
.update({
|
||||||
.catch((err) => console.error('Failed to add update conference message', err));
|
conferencePending: admin.firestore.FieldValue.delete(),
|
||||||
res.status(200).send({ message: 'Started the conference' });
|
})
|
||||||
} else {
|
.catch((err) =>
|
||||||
// WRONG ROOM PIN
|
console.error("Failed to remove pending status", err)
|
||||||
return res.status(401).send({ message: 'Wrong party pin, try rejoining' });
|
);
|
||||||
|
// ADD SYSTEM MESSAGE
|
||||||
|
await admin
|
||||||
|
.firestore()
|
||||||
|
.collection("rooms")
|
||||||
|
.doc(partyName)
|
||||||
|
.collection("messages")
|
||||||
|
.add({
|
||||||
|
uid: "<system>",
|
||||||
|
name: "",
|
||||||
|
text: `${userName} started the call, everyone can join now.`,
|
||||||
|
time: new Date(),
|
||||||
|
})
|
||||||
|
.catch((err) =>
|
||||||
|
console.error("Failed to add update conference message", err)
|
||||||
|
);
|
||||||
|
res.status(200).send({ message: "Started the conference" });
|
||||||
|
} else {
|
||||||
|
res.status(409).send({
|
||||||
|
message: "Looks like someone is already starting a call",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else if (partyConference) {
|
||||||
|
res.status(409).send({
|
||||||
|
message: "Call already exists",
|
||||||
|
conference: partyConference,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// WRONG ROOM PIN
|
||||||
|
res.status(401).send({ message: "Wrong party pin, try rejoining" });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// ROOM DOESN'T EXIST
|
// ROOM DOESN'T EXIST
|
||||||
return res.status(404).send({ message: 'Party Not Found' });
|
res.status(404).send({ message: "Party Not Found" });
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,21 +1,27 @@
|
|||||||
const admin = require('firebase-admin');
|
const admin = require("firebase-admin");
|
||||||
|
|
||||||
module.exports = async (req, res) => {
|
module.exports = async (req, res) => {
|
||||||
const bodydata = JSON.parse(req.body);
|
const bodydata = JSON.parse(req.body);
|
||||||
console.log('Requested Create - UID - ', bodydata.uid);
|
console.log("Requested Create - UID - ", bodydata.uid);
|
||||||
if (!bodydata.userName) res.status(400).send({ message: 'Missing user name' });
|
if (!bodydata.userName)
|
||||||
if (!bodydata.partyName) res.status(400).send({ message: 'Missing party name' });
|
res.status(400).send({ message: "Missing user name" });
|
||||||
if (!bodydata.partyPin) res.status(400).send({ message: 'Missing party pin' });
|
if (!bodydata.partyName)
|
||||||
|
res.status(400).send({ message: "Missing party name" });
|
||||||
|
if (!bodydata.partyPin)
|
||||||
|
res.status(400).send({ message: "Missing party pin" });
|
||||||
const roomNameTaken = await admin
|
const roomNameTaken = await admin
|
||||||
.firestore()
|
.firestore()
|
||||||
.collection('rooms')
|
.collection("rooms")
|
||||||
.doc(bodydata.partyName.replace('/', '\\'))
|
.doc(bodydata.partyName.replace("/", "\\"))
|
||||||
.get()
|
.get()
|
||||||
.then((docSnap) => docSnap.exists);
|
.then((docSnap) => docSnap.exists);
|
||||||
if (roomNameTaken) return res.status(409).send({ message: 'That party name is already taken' });
|
if (roomNameTaken)
|
||||||
|
return res
|
||||||
|
.status(409)
|
||||||
|
.send({ message: "That party name is already taken" });
|
||||||
await admin
|
await admin
|
||||||
.firestore()
|
.firestore()
|
||||||
.collection('rooms')
|
.collection("rooms")
|
||||||
.doc(bodydata.partyName)
|
.doc(bodydata.partyName)
|
||||||
.set({
|
.set({
|
||||||
name: bodydata.partyName,
|
name: bodydata.partyName,
|
||||||
@@ -26,17 +32,17 @@ module.exports = async (req, res) => {
|
|||||||
adminUid: bodydata.uid,
|
adminUid: bodydata.uid,
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
res.status(500).send({ message: 'Unable to start party.' });
|
res.status(500).send({ message: "Unable to start party." });
|
||||||
console.error(err);
|
console.error(err);
|
||||||
});
|
});
|
||||||
await admin
|
await admin
|
||||||
.firestore()
|
.firestore()
|
||||||
.collection('rooms')
|
.collection("rooms")
|
||||||
.doc(bodydata.partyName)
|
.doc(bodydata.partyName)
|
||||||
.collection('messages')
|
.collection("messages")
|
||||||
.add({
|
.add({
|
||||||
uid: '<system>',
|
uid: "<system>",
|
||||||
name: '',
|
name: "",
|
||||||
text: `${bodydata.userName} started the party.`,
|
text: `${bodydata.userName} started the party.`,
|
||||||
time: new Date(),
|
time: new Date(),
|
||||||
})
|
})
|
||||||
@@ -48,9 +54,9 @@ module.exports = async (req, res) => {
|
|||||||
});
|
});
|
||||||
await admin
|
await admin
|
||||||
.firestore()
|
.firestore()
|
||||||
.collection('rooms')
|
.collection("rooms")
|
||||||
.doc(bodydata.partyName)
|
.doc(bodydata.partyName)
|
||||||
.collection('users')
|
.collection("users")
|
||||||
.doc(bodydata.uid)
|
.doc(bodydata.uid)
|
||||||
.set({
|
.set({
|
||||||
admin: true,
|
admin: true,
|
||||||
@@ -62,5 +68,34 @@ module.exports = async (req, res) => {
|
|||||||
err
|
err
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
res.status(201).send({ roomId: bodydata.partyName, message: 'Started a party!' });
|
|
||||||
|
admin
|
||||||
|
.firestore()
|
||||||
|
.collection("rooms")
|
||||||
|
.doc(bodydata.partyName)
|
||||||
|
.collection("messages")
|
||||||
|
.add({
|
||||||
|
uid: "<system>",
|
||||||
|
name: "",
|
||||||
|
text: `Big update coming on Monday (Aug. 10). Watch Party will be unavailable during the afternoon as we upgrade our services. See what's new at whatsnew.chromewatchparty.com`,
|
||||||
|
time: new Date(),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (player.source === "peacocktv.") {
|
||||||
|
admin
|
||||||
|
.firestore()
|
||||||
|
.collection("rooms")
|
||||||
|
.doc(bodydata.partyName)
|
||||||
|
.collection("messages")
|
||||||
|
.add({
|
||||||
|
uid: "<system>",
|
||||||
|
name: "",
|
||||||
|
text: `Sync may not work flawlessly with PeacockTV till Monday's update. Please stick with us as we address this issue.`,
|
||||||
|
time: new Date(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
res
|
||||||
|
.status(201)
|
||||||
|
.send({ roomId: bodydata.partyName, message: "Started a party!" });
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ module.exports = async (req, res) => {
|
|||||||
.update({
|
.update({
|
||||||
player: {
|
player: {
|
||||||
showName: null,
|
showName: null,
|
||||||
source: roomSource,
|
source: bodydata.source,
|
||||||
status: 'NOT_PLAYING',
|
status: 'NOT_PLAYING',
|
||||||
time: 0,
|
time: 0,
|
||||||
updatedBy: bodydata.uid,
|
updatedBy: bodydata.uid,
|
||||||
|
|||||||
@@ -32,17 +32,19 @@ module.exports = async (req, res) => {
|
|||||||
.then((userSnap) => userSnap.exists);
|
.then((userSnap) => userSnap.exists);
|
||||||
if (userExists) {
|
if (userExists) {
|
||||||
if (showChanged === true && player.showName) {
|
if (showChanged === true && player.showName) {
|
||||||
await admin
|
if (player.showName !== roomData.player.showName) {
|
||||||
.firestore()
|
await admin
|
||||||
.collection('rooms')
|
.firestore()
|
||||||
.doc(roomId)
|
.collection('rooms')
|
||||||
.collection('messages')
|
.doc(roomId)
|
||||||
.add({
|
.collection('messages')
|
||||||
uid: '<system>',
|
.add({
|
||||||
name: '',
|
uid: '<system>',
|
||||||
text: `${userName} changed \n${player.showName ? 'to ' + player.showName : ''}`,
|
name: '',
|
||||||
time: new Date(),
|
text: `${userName} changed \n${player.showName ? 'to ' + player.showName : ''}`,
|
||||||
});
|
time: new Date(),
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (roomData.status !== player.status) {
|
if (roomData.status !== player.status) {
|
||||||
await admin
|
await admin
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "watch-party-api",
|
"name": "watch-party-api",
|
||||||
"version": "1.2.1",
|
"version": "1.6.0",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -1909,9 +1909,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"lodash": {
|
"lodash": {
|
||||||
"version": "4.17.15",
|
"version": "4.17.19",
|
||||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
|
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz",
|
||||||
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A=="
|
"integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ=="
|
||||||
},
|
},
|
||||||
"lodash.at": {
|
"lodash.at": {
|
||||||
"version": "4.6.0",
|
"version": "4.6.0",
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
module.exports = async (req, res) => {
|
||||||
|
const { question, answer } = JSON.parse(req.body);
|
||||||
|
console.info(`[RECEIVED]\tWEBHOOKS/ASK\tQ:${question}\tA:${answer}`);
|
||||||
|
res.status(200).send({ message: 'Got answer.' });
|
||||||
|
};
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
const admin = require("firebase-admin");
|
||||||
|
|
||||||
|
module.exports = async (partyName) => {
|
||||||
|
// DELETE MESSAGES
|
||||||
|
const partyMessagesRef = admin
|
||||||
|
.firestore()
|
||||||
|
.collection("rooms")
|
||||||
|
.doc(partyName)
|
||||||
|
.collection("messages");
|
||||||
|
const partyMessagesQuery = partyMessagesRef.orderBy("time").limit(200);
|
||||||
|
await deleteCollection(partyMessagesQuery);
|
||||||
|
// DELETE USERS
|
||||||
|
const partyUsersRef = admin
|
||||||
|
.firestore()
|
||||||
|
.collection("rooms")
|
||||||
|
.doc(partyName)
|
||||||
|
.collection("users");
|
||||||
|
const partyUsersQuery = partyUsersRef.orderBy("time").limit(200);
|
||||||
|
await deleteCollection(partyUsersQuery);
|
||||||
|
// DELETE PARTY DOC
|
||||||
|
await admin.firestore().collection("rooms").doc(partyName).delete();
|
||||||
|
};
|
||||||
|
|
||||||
|
async function deleteCollection(query) {
|
||||||
|
const db = admin.firestore();
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
deleteQueryBatch(db, query, resolve).catch(reject);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function deleteQueryBatch(db, query, resolve) {
|
||||||
|
const snapshot = await query.get();
|
||||||
|
const batchSize = snapshot.size;
|
||||||
|
if (batchSize === 0) {
|
||||||
|
resolve();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const batch = admin.firestore().batch();
|
||||||
|
snapshot.docs.forEach((doc) => {
|
||||||
|
batch.delete(doc.ref);
|
||||||
|
});
|
||||||
|
await batch.commit();
|
||||||
|
process.nextTick(() => {
|
||||||
|
deleteQueryBatch(db, query, resolve);
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
const admin = require("firebase-admin");
|
||||||
|
|
||||||
|
module.exports = async (req, res) => {
|
||||||
|
console.info(
|
||||||
|
`[START]\tWEBHOOKS/Conference End\tID:${req.body.conference.confId}\tParty:${req.body.conference.confAlias}`
|
||||||
|
);
|
||||||
|
// MAKE SURE CORRECT EVENT TYPE
|
||||||
|
if (req.body.eventType === "Conference.Ended") {
|
||||||
|
// MAKE SURE IT'S NOT A DUPLICATE FROM CREATE CONFLICT
|
||||||
|
if (req.body.participants.length > 0) {
|
||||||
|
// MAKE SURE ELIGIBLE FOR DELETE
|
||||||
|
if (req.body.confAlias.startsWith("AUTODELETE_")) {
|
||||||
|
const partyName = req.body.confAlias.replace(/AUTODELETE_/, "");
|
||||||
|
const existingConference = await admin
|
||||||
|
.firestore()
|
||||||
|
.collection("rooms")
|
||||||
|
.doc(partyName)
|
||||||
|
.get()
|
||||||
|
.then((snap) => (snap.exists ? snap.data().conference : null));
|
||||||
|
// MAKE SURE EXISTS AND HAS NOT BEEN REPLACED
|
||||||
|
if (
|
||||||
|
existingConference &&
|
||||||
|
existingConference._id === req.body.conference.confId
|
||||||
|
) {
|
||||||
|
// REMOVE CONFERENCE DETAILS
|
||||||
|
await admin
|
||||||
|
.firestore()
|
||||||
|
.collection("rooms")
|
||||||
|
.doc(partyName)
|
||||||
|
.update({ conference: admin.firestore.FieldValue.delete() })
|
||||||
|
.then(() => {
|
||||||
|
console.info(
|
||||||
|
`[DONE]\tWEBHOOKS/Conference End\tID:${req.body.conference.confId}\tParty:${req.body.conference.confAlias}`
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.error(
|
||||||
|
`[ERROR]\tWEBHOOKS/Conference End/Firebase Error\tID:${
|
||||||
|
req.body.conference.confId
|
||||||
|
}\tParty:${
|
||||||
|
req.body.conference.confAlias
|
||||||
|
}\tError:${JSON.stringify(err)}`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
console.info(
|
||||||
|
`[DONE]\tWEBHOOKS/Conference End/Conference Was Already Replaced\tID:${req.body.conference.confId}\tParty:${req.body.conference.confAlias}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
res.status(200).send({ message: "Processed conference end" });
|
||||||
|
} else {
|
||||||
|
console.info(
|
||||||
|
`[DONE]\tWEBHOOKS/Conference End/Not Eligible For Autodelete\tID:${req.body.conference.confId}\tParty:${req.body.conference.confAlias}`
|
||||||
|
);
|
||||||
|
res.status(200).send({ message: "Processed conference end" });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.info(
|
||||||
|
`[DONE]\tWEBHOOKS/Conference End/End Of Duplicate Conference\tID:${req.body.conference.confId}\tParty:${req.body.conference.confAlias}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.error(
|
||||||
|
`[ERROR]\tWEBHOOKS/Conference End/Wrong Event Type\tID:${req.body.conference.confId}\tParty:${req.body.conference.confAlias}`
|
||||||
|
);
|
||||||
|
res.status(400).send({ message: "Wrong event type" });
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
};
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
const conferenceEnd = require('./conferenceEnd');
|
||||||
|
const scheduledCleanUp = require('./scheduledCleanUp');
|
||||||
|
const ask = require('./ask');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
conferenceEnd,
|
||||||
|
scheduledCleanUp,
|
||||||
|
ask,
|
||||||
|
};
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
const admin = require('firebase-admin');
|
const admin = require("firebase-admin");
|
||||||
const cleanUpRoom = require('./cleanUpRoom');
|
const cleanUpRoom = require("./cleanUpRoom");
|
||||||
|
|
||||||
const timeDiff = (ds1, ds2) => {
|
const timeDiff = (ds1, ds2) => {
|
||||||
const d1 = new Date(ds1);
|
const d1 = new Date(ds1);
|
||||||
@@ -9,11 +9,12 @@ const timeDiff = (ds1, ds2) => {
|
|||||||
return Math.abs(Math.round(diff));
|
return Math.abs(Math.round(diff));
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = async () => {
|
module.exports = async (req, res) => {
|
||||||
const startedTime = new Date();
|
const startedTime = new Date();
|
||||||
|
res.status(200).send({ message: "Started processing" });
|
||||||
const roomList = await admin
|
const roomList = await admin
|
||||||
.firestore()
|
.firestore()
|
||||||
.collection('rooms')
|
.collection("rooms")
|
||||||
.listDocuments()
|
.listDocuments()
|
||||||
.then((rL) => rL)
|
.then((rL) => rL)
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
@@ -29,11 +30,11 @@ module.exports = async () => {
|
|||||||
if (
|
if (
|
||||||
// MORE THAN 24 HOURS AND NOT IN USE
|
// MORE THAN 24 HOURS AND NOT IN USE
|
||||||
(timeDiff(roomSnap.createTime.toDate(), startedTime) >= 24 &&
|
(timeDiff(roomSnap.createTime.toDate(), startedTime) >= 24 &&
|
||||||
timeDiff(roomSnap.updateTime.toDate(), startedTime) >= 12) ||
|
timeDiff(roomSnap.updateTime.toDate(), startedTime) >= 4) ||
|
||||||
// LESS THAN 24 HOURS BUT NOT IN USE
|
// LESS THAN 24 HOURS BUT NOT IN USE
|
||||||
timeDiff(roomSnap.updateTime.toDate(), startedTime) >= 12
|
timeDiff(roomSnap.updateTime.toDate(), startedTime) >= 12
|
||||||
) {
|
) {
|
||||||
await cleanUpRoom(roomSnap.id);
|
cleanUpRoom(roomSnap.id);
|
||||||
console.info(`Deleted room ${roomSnap.id} from auto cleanup`);
|
console.info(`Deleted room ${roomSnap.id} from auto cleanup`);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@@ -45,4 +46,5 @@ module.exports = async () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
return;
|
||||||
};
|
};
|
||||||
@@ -4,6 +4,11 @@ Copyright (C) Ayushya Amitabh - All Rights Reserved
|
|||||||
Unauthorized copying of this file, via any medium is strictly prohibited
|
Unauthorized copying of this file, via any medium is strictly prohibited
|
||||||
Proprietary and confidential
|
Proprietary and confidential
|
||||||
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
||||||
|
https://www.chromewatchparty.com/copyright
|
||||||
|
=========================================================================
|
||||||
|
ALL CONTENT ON WATCH PARTY'S WEBSITE OR IN WATCH PARTY'S CHROME EXTENSION APP, UNLESS OTHERWISE
|
||||||
|
CITED ARE THE SOLE INTELECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE
|
||||||
|
COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
|
||||||
------------------------------------------------------------------------->
|
------------------------------------------------------------------------->
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
|
|||||||
@@ -4,6 +4,11 @@ Copyright (C) Ayushya Amitabh - All Rights Reserved
|
|||||||
Unauthorized copying of this file, via any medium is strictly prohibited
|
Unauthorized copying of this file, via any medium is strictly prohibited
|
||||||
Proprietary and confidential
|
Proprietary and confidential
|
||||||
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
||||||
|
https://www.chromewatchparty.com/copyright
|
||||||
|
=========================================================================
|
||||||
|
ALL CONTENT ON WATCH PARTY'S WEBSITE OR IN WATCH PARTY'S CHROME EXTENSION APP, UNLESS OTHERWISE
|
||||||
|
CITED ARE THE SOLE INTELECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE
|
||||||
|
COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
|
||||||
------------------------------------------------------------------------->
|
------------------------------------------------------------------------->
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
|
|||||||
@@ -4,12 +4,27 @@ Copyright (C) Ayushya Amitabh - All Rights Reserved
|
|||||||
Unauthorized copying of this file, via any medium is strictly prohibited
|
Unauthorized copying of this file, via any medium is strictly prohibited
|
||||||
Proprietary and confidential
|
Proprietary and confidential
|
||||||
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
||||||
|
https://www.chromewatchparty.com/copyright
|
||||||
|
=========================================================================
|
||||||
|
ALL CONTENT ON WATCH PARTY'S WEBSITE OR IN WATCH PARTY'S CHROME EXTENSION APP, UNLESS OTHERWISE
|
||||||
|
CITED ARE THE SOLE INTELECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE
|
||||||
|
COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
|
||||||
------------------------------------------------------------------------->
|
------------------------------------------------------------------------->
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta http-equiv="refresh" content="0; URL='https://request.chromewatchparty.com'" />
|
<meta http-equiv="refresh" content="0; URL='https://request.chromewatchparty.com'" />
|
||||||
<title>Watch Party | Beta</title>
|
<title>Watch Party | Beta</title>
|
||||||
</head>
|
</head>
|
||||||
|
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||||||
|
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-87498806-2">
|
||||||
|
</script>
|
||||||
|
<script>
|
||||||
|
window.dataLayer = window.dataLayer || [];
|
||||||
|
function gtag(){dataLayer.push(arguments);}
|
||||||
|
gtag('js', new Date());
|
||||||
|
|
||||||
|
gtag('config', 'UA-87498806-2');
|
||||||
|
</script>
|
||||||
<body>
|
<body>
|
||||||
Redirecting...
|
Redirecting...
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@@ -4,48 +4,119 @@ Copyright (C) Ayushya Amitabh - All Rights Reserved
|
|||||||
Unauthorized copying of this file, via any medium is strictly prohibited
|
Unauthorized copying of this file, via any medium is strictly prohibited
|
||||||
Proprietary and confidential
|
Proprietary and confidential
|
||||||
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
||||||
|
https://www.chromewatchparty.com/copyright
|
||||||
=========================================================================
|
=========================================================================
|
||||||
ALL CONTENT ON THIS WEBSITE, UNLESS OTHERWISE CITED ARE THE SOLE
|
ALL CONTENT ON WATCH PARTY'S WEBSITE OR IN WATCH PARTY'S CHROME EXTENSION APP, UNLESS OTHERWISE
|
||||||
INTELECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE COPIED, EDITED,
|
CITED ARE THE SOLE INTELECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE
|
||||||
OR REPRODUCED WITHOUT PERMISSION.
|
COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
|
||||||
|
|
||||||
Netflix logo is a trademark and intellectual property of Netflix, Inc.
|
|
||||||
Disney+ logo is a trademark and intellectual property of The Walt Disney Company
|
|
||||||
Prime logo is a trademark and intellectual property of Amazon.com, Inc.
|
|
||||||
YouTube logo is a trademark and intellectual property of Google, Inc.
|
|
||||||
Hulu logo is a trademark and intellectual property of Hulu, LLC.
|
|
||||||
HBO Now and HBO Max logos are trademark and intellectual property of WarnerMedia Direct,LLC.
|
|
||||||
Peacock TV logo is a trademark and intellectual property of Peacock TV & NBC Universal.
|
|
||||||
------------------------------------------------------------------------->
|
------------------------------------------------------------------------->
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<link rel="apple-touch-icon" sizes="57x57" href="../icons/apple-icon-57x57.png" />
|
<link
|
||||||
<link rel="apple-touch-icon" sizes="60x60" href="../icons/apple-icon-60x60.png" />
|
rel="apple-touch-icon"
|
||||||
<link rel="apple-touch-icon" sizes="72x72" href="../icons/apple-icon-72x72.png" />
|
sizes="57x57"
|
||||||
<link rel="apple-touch-icon" sizes="76x76" href="../icons/apple-icon-76x76.png" />
|
href="../icons/apple-icon-57x57.png"
|
||||||
<link rel="apple-touch-icon" sizes="114x114" href="../icons/apple-icon-114x114.png" />
|
/>
|
||||||
<link rel="apple-touch-icon" sizes="120x120" href="../icons/apple-icon-120x120.png" />
|
<link
|
||||||
<link rel="apple-touch-icon" sizes="144x144" href="../icons/apple-icon-144x144.png" />
|
rel="apple-touch-icon"
|
||||||
<link rel="apple-touch-icon" sizes="152x152" href="../icons/apple-icon-152x152.png" />
|
sizes="60x60"
|
||||||
<link rel="apple-touch-icon" sizes="180x180" href="../icons/apple-icon-180x180.png" />
|
href="../icons/apple-icon-60x60.png"
|
||||||
<link rel="icon" type="image/png" sizes="192x192" href="../icons/android-icon-192x192.png" />
|
/>
|
||||||
<link rel="icon" type="image/png" sizes="32x32" href="../icons/favicon-32x32.png" />
|
<link
|
||||||
<link rel="icon" type="image/png" sizes="96x96" href="../icons/favicon-96x96.png" />
|
rel="apple-touch-icon"
|
||||||
<link rel="icon" type="image/png" sizes="16x16" href="../icons/favicon-16x16.png" />
|
sizes="72x72"
|
||||||
|
href="../icons/apple-icon-72x72.png"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="apple-touch-icon"
|
||||||
|
sizes="76x76"
|
||||||
|
href="../icons/apple-icon-76x76.png"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="apple-touch-icon"
|
||||||
|
sizes="114x114"
|
||||||
|
href="../icons/apple-icon-114x114.png"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="apple-touch-icon"
|
||||||
|
sizes="120x120"
|
||||||
|
href="../icons/apple-icon-120x120.png"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="apple-touch-icon"
|
||||||
|
sizes="144x144"
|
||||||
|
href="../icons/apple-icon-144x144.png"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="apple-touch-icon"
|
||||||
|
sizes="152x152"
|
||||||
|
href="../icons/apple-icon-152x152.png"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="apple-touch-icon"
|
||||||
|
sizes="180x180"
|
||||||
|
href="../icons/apple-icon-180x180.png"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="icon"
|
||||||
|
type="image/png"
|
||||||
|
sizes="192x192"
|
||||||
|
href="../icons/android-icon-192x192.png"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="icon"
|
||||||
|
type="image/png"
|
||||||
|
sizes="32x32"
|
||||||
|
href="../icons/favicon-32x32.png"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="icon"
|
||||||
|
type="image/png"
|
||||||
|
sizes="96x96"
|
||||||
|
href="../icons/favicon-96x96.png"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="icon"
|
||||||
|
type="image/png"
|
||||||
|
sizes="16x16"
|
||||||
|
href="../icons/favicon-16x16.png"
|
||||||
|
/>
|
||||||
<link rel="icon" href="../icons/favicon.ico" />
|
<link rel="icon" href="../icons/favicon.ico" />
|
||||||
<link rel="manifest" href="../manifest.json" />
|
<link rel="manifest" href="../manifest.json" />
|
||||||
<meta name="msapplication-TileImage" content="../icons/ms-icon-144x144.png" />
|
<meta
|
||||||
|
name="msapplication-TileImage"
|
||||||
|
content="../icons/ms-icon-144x144.png"
|
||||||
|
/>
|
||||||
<link rel="stylesheet" type="text/css" href="../font.css" />
|
<link rel="stylesheet" type="text/css" href="../font.css" />
|
||||||
<link rel="stylesheet" type="text/css" href="../styles/index.css" />
|
<link rel="stylesheet" type="text/css" href="../styles/index.css" />
|
||||||
<script src="../scripts/Stickied.js"></script>
|
<script src="../scripts/Stickied.js"></script>
|
||||||
<title>Watch Party | Changelog</title>
|
<title>Watch Party | Changelog</title>
|
||||||
</head>
|
</head>
|
||||||
|
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||||||
|
<script
|
||||||
|
async
|
||||||
|
src="https://www.googletagmanager.com/gtag/js?id=UA-87498806-2"
|
||||||
|
></script>
|
||||||
|
<script>
|
||||||
|
window.dataLayer = window.dataLayer || [];
|
||||||
|
function gtag() {
|
||||||
|
dataLayer.push(arguments);
|
||||||
|
}
|
||||||
|
gtag("js", new Date());
|
||||||
|
|
||||||
|
gtag("config", "UA-87498806-2");
|
||||||
|
</script>
|
||||||
<body class="copyright">
|
<body class="copyright">
|
||||||
<div class="landing">
|
<div class="landing">
|
||||||
<div class="logo-circle"></div>
|
<div class="logo-circle"></div>
|
||||||
<div class="logo-circle"></div>
|
<div class="logo-circle"></div>
|
||||||
<div class="logo-circle"></div>
|
<div class="logo-circle"></div>
|
||||||
<h1 data-font="serif" class="logo"><a href="../">WATCH PARTY</a> | CHANGELOG</h1>
|
<h1 data-font="serif" class="logo duplicate">
|
||||||
|
<a href="../">WATCH PARTY</a> | CHANGELOG
|
||||||
|
</h1>
|
||||||
|
<h1 data-font="serif" class="logo">
|
||||||
|
<a href="../">WATCH PARTY</a> | CHANGELOG
|
||||||
|
</h1>
|
||||||
<h5 data-font="sans" class="logo-tag">
|
<h5 data-font="sans" class="logo-tag">
|
||||||
WATCH YOUR FAVORITES,<br />WITH YOUR FAVORITE PEOPLE
|
WATCH YOUR FAVORITES,<br />WITH YOUR FAVORITE PEOPLE
|
||||||
</h5>
|
</h5>
|
||||||
@@ -61,26 +132,37 @@ Peacock TV logo is a trademark and intellectual property of Peacock TV & NBC Uni
|
|||||||
<div
|
<div
|
||||||
class="supported-logo"
|
class="supported-logo"
|
||||||
style="background-image: url(../media/versions/160.png);"
|
style="background-image: url(../media/versions/160.png);"
|
||||||
data-upcoming-support="Work In Progress"
|
data-upcoming-support="See Changes"
|
||||||
></div>
|
></div>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<footer data-font="sans">
|
<footer data-font="sans">
|
||||||
<p class="title built-with">
|
<p class="title built-with">
|
||||||
<a href="../copyright/">COPYRIGHT</a> © 2020 AYUSHYA AMITABH. ALL RIGHTS RESERVED.
|
<a href="../copyright/">COPYRIGHT</a> © 2020 AYUSHYA AMITABH. ALL
|
||||||
|
RIGHTS RESERVED.
|
||||||
</p>
|
</p>
|
||||||
<p class="title built-with">
|
<p class="title built-with">
|
||||||
BUILT WITH 💚 FOR <a href="https://www.google.com/chrome/">GOOGLE CHROME</a> USING
|
BUILT WITH 💚 FOR
|
||||||
|
<a href="https://www.google.com/chrome/">GOOGLE CHROME</a> USING
|
||||||
<a href="https://firebase.google.com/">FIREBASE</a>,
|
<a href="https://firebase.google.com/">FIREBASE</a>,
|
||||||
<a href="https://material-ui.com/">MATERIAL-UI</a>,
|
<a href="https://material-ui.com/">MATERIAL-UI</a>,
|
||||||
<a href="https://reactjs.org/">REACT JS</a>, <a href="https://nodejs.org/en/">NODE JS</a>,
|
<a href="https://reactjs.org/">REACT JS</a>,
|
||||||
<a href="https://giphy.com/">GIPHY</a>, & <a href="https://dolby.io/">DOLBY VOXEET</a>.
|
<a href="https://nodejs.org/en/">NODE JS</a>,
|
||||||
|
<a href="https://giphy.com/">GIPHY</a>, &
|
||||||
|
<a href="https://dolby.io/">DOLBY VOXEET</a>.
|
||||||
</p>
|
</p>
|
||||||
<a data-font="sans-bold" href="https://paypal.me/Ayushya" class="link-button">
|
<a
|
||||||
|
data-font="sans-bold"
|
||||||
|
href="https://paypal.me/Ayushya"
|
||||||
|
class="link-button"
|
||||||
|
>
|
||||||
Support Watch Party
|
Support Watch Party
|
||||||
</a>
|
</a>
|
||||||
<a data-font="sans-bold" href="https://request.chromewatchparty.com" class="link-button"
|
<a
|
||||||
|
data-font="sans-bold"
|
||||||
|
href="https://request.chromewatchparty.com"
|
||||||
|
class="link-button"
|
||||||
>Get Chrome Extension</a
|
>Get Chrome Extension</a
|
||||||
>
|
>
|
||||||
<a
|
<a
|
||||||
|
|||||||
@@ -4,81 +4,190 @@ Copyright (C) Ayushya Amitabh - All Rights Reserved
|
|||||||
Unauthorized copying of this file, via any medium is strictly prohibited
|
Unauthorized copying of this file, via any medium is strictly prohibited
|
||||||
Proprietary and confidential
|
Proprietary and confidential
|
||||||
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
||||||
|
https://www.chromewatchparty.com/copyright
|
||||||
=========================================================================
|
=========================================================================
|
||||||
ALL CONTENT ON THIS WEBSITE, UNLESS OTHERWISE CITED ARE THE SOLE
|
ALL CONTENT ON WATCH PARTY'S WEBSITE OR IN WATCH PARTY'S CHROME EXTENSION APP, UNLESS OTHERWISE
|
||||||
INTELECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE COPIED, EDITED,
|
CITED ARE THE SOLE INTELECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE
|
||||||
OR REPRODUCED WITHOUT PERMISSION.
|
COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
|
||||||
|
|
||||||
Netflix logo is a trademark and intellectual property of Netflix, Inc.
|
|
||||||
Disney+ logo is a trademark and intellectual property of The Walt Disney Company
|
|
||||||
Prime logo is a trademark and intellectual property of Amazon.com, Inc.
|
|
||||||
YouTube logo is a trademark and intellectual property of Google, Inc.
|
|
||||||
Hulu logo is a trademark and intellectual property of Hulu, LLC.
|
|
||||||
HBO Now and HBO Max logos are trademark and intellectual property of WarnerMedia Direct,LLC.
|
|
||||||
Peacock TV logo is a trademark and intellectual property of Peacock TV & NBC Universal.
|
|
||||||
------------------------------------------------------------------------->
|
------------------------------------------------------------------------->
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<link rel="apple-touch-icon" sizes="57x57" href="../../icons/apple-icon-57x57.png" />
|
<link
|
||||||
<link rel="apple-touch-icon" sizes="60x60" href="../../icons/apple-icon-60x60.png" />
|
rel="apple-touch-icon"
|
||||||
<link rel="apple-touch-icon" sizes="72x72" href="../../icons/apple-icon-72x72.png" />
|
sizes="57x57"
|
||||||
<link rel="apple-touch-icon" sizes="76x76" href="../../icons/apple-icon-76x76.png" />
|
href="../../icons/apple-icon-57x57.png"
|
||||||
<link rel="apple-touch-icon" sizes="114x114" href="../../icons/apple-icon-114x114.png" />
|
/>
|
||||||
<link rel="apple-touch-icon" sizes="120x120" href="../../icons/apple-icon-120x120.png" />
|
<link
|
||||||
<link rel="apple-touch-icon" sizes="144x144" href="../../icons/apple-icon-144x144.png" />
|
rel="apple-touch-icon"
|
||||||
<link rel="apple-touch-icon" sizes="152x152" href="../../icons/apple-icon-152x152.png" />
|
sizes="60x60"
|
||||||
<link rel="apple-touch-icon" sizes="180x180" href="../../icons/apple-icon-180x180.png" />
|
href="../../icons/apple-icon-60x60.png"
|
||||||
<link rel="icon" type="image/png" sizes="192x192" href="../../icons/android-icon-192x192.png" />
|
/>
|
||||||
<link rel="icon" type="image/png" sizes="32x32" href="../../icons/favicon-32x32.png" />
|
<link
|
||||||
<link rel="icon" type="image/png" sizes="96x96" href="../../icons/favicon-96x96.png" />
|
rel="apple-touch-icon"
|
||||||
<link rel="icon" type="image/png" sizes="16x16" href="../../icons/favicon-16x16.png" />
|
sizes="72x72"
|
||||||
|
href="../../icons/apple-icon-72x72.png"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="apple-touch-icon"
|
||||||
|
sizes="76x76"
|
||||||
|
href="../../icons/apple-icon-76x76.png"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="apple-touch-icon"
|
||||||
|
sizes="114x114"
|
||||||
|
href="../../icons/apple-icon-114x114.png"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="apple-touch-icon"
|
||||||
|
sizes="120x120"
|
||||||
|
href="../../icons/apple-icon-120x120.png"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="apple-touch-icon"
|
||||||
|
sizes="144x144"
|
||||||
|
href="../../icons/apple-icon-144x144.png"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="apple-touch-icon"
|
||||||
|
sizes="152x152"
|
||||||
|
href="../../icons/apple-icon-152x152.png"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="apple-touch-icon"
|
||||||
|
sizes="180x180"
|
||||||
|
href="../../icons/apple-icon-180x180.png"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="icon"
|
||||||
|
type="image/png"
|
||||||
|
sizes="192x192"
|
||||||
|
href="../../icons/android-icon-192x192.png"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="icon"
|
||||||
|
type="image/png"
|
||||||
|
sizes="32x32"
|
||||||
|
href="../../icons/favicon-32x32.png"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="icon"
|
||||||
|
type="image/png"
|
||||||
|
sizes="96x96"
|
||||||
|
href="../../icons/favicon-96x96.png"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="icon"
|
||||||
|
type="image/png"
|
||||||
|
sizes="16x16"
|
||||||
|
href="../../icons/favicon-16x16.png"
|
||||||
|
/>
|
||||||
<link rel="icon" href="../../icons/favicon.ico" />
|
<link rel="icon" href="../../icons/favicon.ico" />
|
||||||
<link rel="manifest" href="../../manifest.json" />
|
<link rel="manifest" href="../../manifest.json" />
|
||||||
<meta name="msapplication-TileImage" content="../../icons/ms-icon-144x144.png" />
|
<meta
|
||||||
|
name="msapplication-TileImage"
|
||||||
|
content="../../icons/ms-icon-144x144.png"
|
||||||
|
/>
|
||||||
<link rel="stylesheet" type="text/css" href="../../font.css" />
|
<link rel="stylesheet" type="text/css" href="../../font.css" />
|
||||||
<link rel="stylesheet" type="text/css" href="../../styles/index.css" />
|
<link rel="stylesheet" type="text/css" href="../../styles/index.css" />
|
||||||
<script src="../../scripts/Stickied.js"></script>
|
<script src="../../scripts/Stickied.js"></script>
|
||||||
<title>Watch Party | V1.5.2</title>
|
<title>Watch Party | V1.5.2</title>
|
||||||
</head>
|
</head>
|
||||||
|
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||||||
|
<script
|
||||||
|
async
|
||||||
|
src="https://www.googletagmanager.com/gtag/js?id=UA-87498806-2"
|
||||||
|
></script>
|
||||||
|
<script>
|
||||||
|
window.dataLayer = window.dataLayer || [];
|
||||||
|
function gtag() {
|
||||||
|
dataLayer.push(arguments);
|
||||||
|
}
|
||||||
|
gtag("js", new Date());
|
||||||
|
|
||||||
|
gtag("config", "UA-87498806-2");
|
||||||
|
</script>
|
||||||
<body class="copyright welcome">
|
<body class="copyright welcome">
|
||||||
<div class="landing">
|
<div class="landing">
|
||||||
<div class="logo-circle"></div>
|
<div class="logo-circle"></div>
|
||||||
<div class="logo-circle"></div>
|
<div class="logo-circle"></div>
|
||||||
<div class="logo-circle"></div>
|
<div class="logo-circle"></div>
|
||||||
<h1 data-font="serif" class="logo"><a href="../../">WATCH PARTY</a> | V1.5.2</h1>
|
<h1 data-font="serif" class="logo duplicate">
|
||||||
|
<a href="../../">WATCH PARTY</a> | V1.5.2
|
||||||
|
</h1>
|
||||||
|
<h1 data-font="serif" class="logo">
|
||||||
|
<a href="../../">WATCH PARTY</a> | V1.5.2
|
||||||
|
</h1>
|
||||||
<h5 data-font="sans" class="logo-tag">
|
<h5 data-font="sans" class="logo-tag">
|
||||||
WATCH YOUR FAVORITES,<br />WITH YOUR FAVORITE PEOPLE
|
WATCH YOUR FAVORITES,<br />WITH YOUR FAVORITE PEOPLE
|
||||||
</h5>
|
</h5>
|
||||||
</div>
|
</div>
|
||||||
<div class="features">
|
<div class="features">
|
||||||
<p data-font="sans-bold" class="title subtitle">CHANGES MADE IN FEATURES</p>
|
<p data-font="sans-bold" class="title subtitle">
|
||||||
|
CHANGES MADE IN FEATURES
|
||||||
|
</p>
|
||||||
<div class="feature-card">
|
<div class="feature-card">
|
||||||
<div class="feature-icon" id="sync"></div>
|
<div class="feature-icon" id="sync">
|
||||||
|
<video
|
||||||
|
loop
|
||||||
|
muted
|
||||||
|
autoplay
|
||||||
|
src="../../media/features/Sync.mp4"
|
||||||
|
></video>
|
||||||
|
</div>
|
||||||
<p data-font="sans" class="feature-text">
|
<p data-font="sans" class="feature-text">
|
||||||
Fixed Netflix bug to autodetect player.
|
Fixed Netflix bug to autodetect player.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="feature-card">
|
<div class="feature-card">
|
||||||
<div class="feature-icon" id="phone"></div>
|
<div class="feature-icon" id="phone">
|
||||||
|
<video
|
||||||
|
loop
|
||||||
|
muted
|
||||||
|
autoplay
|
||||||
|
src="../../media/features/Phone.mp4"
|
||||||
|
></video>
|
||||||
|
</div>
|
||||||
<p data-font="sans" class="feature-text">
|
<p data-font="sans" class="feature-text">
|
||||||
Added mic permission overlay, and add proper loading icon to show a connecting call.
|
Added mic permission overlay, and add proper loading icon to show a
|
||||||
|
connecting call.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="feature-card">
|
<div class="feature-card">
|
||||||
<div class="feature-icon" id="chat"></div>
|
<div class="feature-icon" id="chat">
|
||||||
|
<video
|
||||||
|
loop
|
||||||
|
muted
|
||||||
|
autoplay
|
||||||
|
src="../../media/features/Chat.mp4"
|
||||||
|
></video>
|
||||||
|
</div>
|
||||||
<p data-font="sans" class="feature-text">
|
<p data-font="sans" class="feature-text">
|
||||||
Gif scrollbar is now easier to grab and scroll.
|
Gif scrollbar is now easier to grab and scroll.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="feature-card">
|
<div class="feature-card">
|
||||||
<div class="feature-icon" id="hideable"></div>
|
<div class="feature-icon" id="hideable">
|
||||||
|
<video
|
||||||
|
loop
|
||||||
|
muted
|
||||||
|
autoplay
|
||||||
|
src="../../media/features/Hideable.mp4"
|
||||||
|
></video>
|
||||||
|
</div>
|
||||||
<p data-font="sans" class="feature-text">
|
<p data-font="sans" class="feature-text">
|
||||||
Fullscreen support, use the button in the sidebar to have access to Watch Party in
|
Fullscreen support, use the button in the sidebar to have access to
|
||||||
fullscreen
|
Watch Party in fullscreen
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="feature-card">
|
<div class="feature-card">
|
||||||
<div class="feature-icon" id="custom"></div>
|
<div class="feature-icon" id="custom">
|
||||||
|
<video
|
||||||
|
loop
|
||||||
|
muted
|
||||||
|
autoplay
|
||||||
|
src="../../media/features/Custom.mp4"
|
||||||
|
></video>
|
||||||
|
</div>
|
||||||
<p data-font="sans" class="feature-text">
|
<p data-font="sans" class="feature-text">
|
||||||
Added auto rejoin (as long you return within 1 minute)
|
Added auto rejoin (as long you return within 1 minute)
|
||||||
</p>
|
</p>
|
||||||
@@ -120,13 +229,14 @@ Peacock TV logo is a trademark and intellectual property of Peacock TV & NBC Uni
|
|||||||
</div>
|
</div>
|
||||||
<div class="tip">
|
<div class="tip">
|
||||||
<p data-font="sans-bold">
|
<p data-font="sans-bold">
|
||||||
> Netflix player update (fixes issue when player was not detected if video started before
|
> Netflix player update (fixes issue when player was not detected if
|
||||||
party)
|
video started before party)
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="tip">
|
<div class="tip">
|
||||||
<p data-font="sans-bold">
|
<p data-font="sans-bold">
|
||||||
> Room migrate fix (allows party creators to move their parties to new sites)
|
> Room migrate fix (allows party creators to move their parties to new
|
||||||
|
sites)
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="tip">
|
<div class="tip">
|
||||||
@@ -149,19 +259,30 @@ Peacock TV logo is a trademark and intellectual property of Peacock TV & NBC Uni
|
|||||||
</div>
|
</div>
|
||||||
<footer data-font="sans">
|
<footer data-font="sans">
|
||||||
<p class="title built-with">
|
<p class="title built-with">
|
||||||
<a href="../../copyright/">COPYRIGHT</a> © 2020 AYUSHYA AMITABH. ALL RIGHTS RESERVED.
|
<a href="../../copyright/">COPYRIGHT</a> © 2020 AYUSHYA AMITABH.
|
||||||
|
ALL RIGHTS RESERVED.
|
||||||
</p>
|
</p>
|
||||||
<p class="title built-with">
|
<p class="title built-with">
|
||||||
BUILT WITH 💚 FOR <a href="https://www.google.com/chrome/">GOOGLE CHROME</a> USING
|
BUILT WITH 💚 FOR
|
||||||
|
<a href="https://www.google.com/chrome/">GOOGLE CHROME</a> USING
|
||||||
<a href="https://firebase.google.com/">FIREBASE</a>,
|
<a href="https://firebase.google.com/">FIREBASE</a>,
|
||||||
<a href="https://material-ui.com/">MATERIAL-UI</a>,
|
<a href="https://material-ui.com/">MATERIAL-UI</a>,
|
||||||
<a href="https://reactjs.org/">REACT JS</a>, <a href="https://nodejs.org/en/">NODE JS</a>,
|
<a href="https://reactjs.org/">REACT JS</a>,
|
||||||
<a href="https://giphy.com/">GIPHY</a>, & <a href="https://dolby.io/">DOLBY VOXEET</a>.
|
<a href="https://nodejs.org/en/">NODE JS</a>,
|
||||||
|
<a href="https://giphy.com/">GIPHY</a>, &
|
||||||
|
<a href="https://dolby.io/">DOLBY VOXEET</a>.
|
||||||
</p>
|
</p>
|
||||||
<a data-font="sans-bold" href="https://paypal.me/Ayushya" class="link-button">
|
<a
|
||||||
|
data-font="sans-bold"
|
||||||
|
href="https://paypal.me/Ayushya"
|
||||||
|
class="link-button"
|
||||||
|
>
|
||||||
Support Watch Party
|
Support Watch Party
|
||||||
</a>
|
</a>
|
||||||
<a data-font="sans-bold" href="https://request.chromewatchparty.com" class="link-button"
|
<a
|
||||||
|
data-font="sans-bold"
|
||||||
|
href="https://request.chromewatchparty.com"
|
||||||
|
class="link-button"
|
||||||
>Get Chrome Extension</a
|
>Get Chrome Extension</a
|
||||||
>
|
>
|
||||||
<a
|
<a
|
||||||
|
|||||||
@@ -4,83 +4,285 @@ Copyright (C) Ayushya Amitabh - All Rights Reserved
|
|||||||
Unauthorized copying of this file, via any medium is strictly prohibited
|
Unauthorized copying of this file, via any medium is strictly prohibited
|
||||||
Proprietary and confidential
|
Proprietary and confidential
|
||||||
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
||||||
|
https://www.chromewatchparty.com/copyright
|
||||||
=========================================================================
|
=========================================================================
|
||||||
ALL CONTENT ON THIS WEBSITE, UNLESS OTHERWISE CITED ARE THE SOLE
|
ALL CONTENT ON WATCH PARTY'S WEBSITE OR IN WATCH PARTY'S CHROME EXTENSION APP, UNLESS OTHERWISE
|
||||||
INTELECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE COPIED, EDITED,
|
CITED ARE THE SOLE INTELECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE
|
||||||
OR REPRODUCED WITHOUT PERMISSION.
|
COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
|
||||||
|
|
||||||
Netflix logo is a trademark and intellectual property of Netflix, Inc.
|
|
||||||
Disney+ logo is a trademark and intellectual property of The Walt Disney Company
|
|
||||||
Prime logo is a trademark and intellectual property of Amazon.com, Inc.
|
|
||||||
YouTube logo is a trademark and intellectual property of Google, Inc.
|
|
||||||
Hulu logo is a trademark and intellectual property of Hulu, LLC.
|
|
||||||
HBO Now and HBO Max logos are trademark and intellectual property of WarnerMedia Direct,LLC.
|
|
||||||
Peacock TV logo is a trademark and intellectual property of Peacock TV & NBC Universal.
|
|
||||||
------------------------------------------------------------------------->
|
------------------------------------------------------------------------->
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<link rel="apple-touch-icon" sizes="57x57" href="../../icons/apple-icon-57x57.png" />
|
<link
|
||||||
<link rel="apple-touch-icon" sizes="60x60" href="../../icons/apple-icon-60x60.png" />
|
rel="apple-touch-icon"
|
||||||
<link rel="apple-touch-icon" sizes="72x72" href="../../icons/apple-icon-72x72.png" />
|
sizes="57x57"
|
||||||
<link rel="apple-touch-icon" sizes="76x76" href="../../icons/apple-icon-76x76.png" />
|
href="../../icons/apple-icon-57x57.png"
|
||||||
<link rel="apple-touch-icon" sizes="114x114" href="../../icons/apple-icon-114x114.png" />
|
/>
|
||||||
<link rel="apple-touch-icon" sizes="120x120" href="../../icons/apple-icon-120x120.png" />
|
<link
|
||||||
<link rel="apple-touch-icon" sizes="144x144" href="../../icons/apple-icon-144x144.png" />
|
rel="apple-touch-icon"
|
||||||
<link rel="apple-touch-icon" sizes="152x152" href="../../icons/apple-icon-152x152.png" />
|
sizes="60x60"
|
||||||
<link rel="apple-touch-icon" sizes="180x180" href="../../icons/apple-icon-180x180.png" />
|
href="../../icons/apple-icon-60x60.png"
|
||||||
<link rel="icon" type="image/png" sizes="192x192" href="../../icons/android-icon-192x192.png" />
|
/>
|
||||||
<link rel="icon" type="image/png" sizes="32x32" href="../../icons/favicon-32x32.png" />
|
<link
|
||||||
<link rel="icon" type="image/png" sizes="96x96" href="../../icons/favicon-96x96.png" />
|
rel="apple-touch-icon"
|
||||||
<link rel="icon" type="image/png" sizes="16x16" href="../../icons/favicon-16x16.png" />
|
sizes="72x72"
|
||||||
|
href="../../icons/apple-icon-72x72.png"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="apple-touch-icon"
|
||||||
|
sizes="76x76"
|
||||||
|
href="../../icons/apple-icon-76x76.png"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="apple-touch-icon"
|
||||||
|
sizes="114x114"
|
||||||
|
href="../../icons/apple-icon-114x114.png"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="apple-touch-icon"
|
||||||
|
sizes="120x120"
|
||||||
|
href="../../icons/apple-icon-120x120.png"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="apple-touch-icon"
|
||||||
|
sizes="144x144"
|
||||||
|
href="../../icons/apple-icon-144x144.png"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="apple-touch-icon"
|
||||||
|
sizes="152x152"
|
||||||
|
href="../../icons/apple-icon-152x152.png"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="apple-touch-icon"
|
||||||
|
sizes="180x180"
|
||||||
|
href="../../icons/apple-icon-180x180.png"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="icon"
|
||||||
|
type="image/png"
|
||||||
|
sizes="192x192"
|
||||||
|
href="../../icons/android-icon-192x192.png"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="icon"
|
||||||
|
type="image/png"
|
||||||
|
sizes="32x32"
|
||||||
|
href="../../icons/favicon-32x32.png"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="icon"
|
||||||
|
type="image/png"
|
||||||
|
sizes="96x96"
|
||||||
|
href="../../icons/favicon-96x96.png"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="icon"
|
||||||
|
type="image/png"
|
||||||
|
sizes="16x16"
|
||||||
|
href="../../icons/favicon-16x16.png"
|
||||||
|
/>
|
||||||
<link rel="icon" href="../../icons/favicon.ico" />
|
<link rel="icon" href="../../icons/favicon.ico" />
|
||||||
<link rel="manifest" href="../../manifest.json" />
|
<link rel="manifest" href="../../manifest.json" />
|
||||||
<meta name="msapplication-TileImage" content="../../icons/ms-icon-144x144.png" />
|
<meta
|
||||||
|
name="msapplication-TileImage"
|
||||||
|
content="../../icons/ms-icon-144x144.png"
|
||||||
|
/>
|
||||||
<link rel="stylesheet" type="text/css" href="../../font.css" />
|
<link rel="stylesheet" type="text/css" href="../../font.css" />
|
||||||
<link rel="stylesheet" type="text/css" href="../../styles/index.css" />
|
<link rel="stylesheet" type="text/css" href="../../styles/index.css" />
|
||||||
<script src="../../scripts/Stickied.js"></script>
|
<script src="../../scripts/Stickied.js"></script>
|
||||||
<title>Watch Party | V1.6.0</title>
|
<title>Watch Party | V1.6.0</title>
|
||||||
</head>
|
</head>
|
||||||
|
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||||||
|
<script
|
||||||
|
async
|
||||||
|
src="https://www.googletagmanager.com/gtag/js?id=UA-87498806-2"
|
||||||
|
></script>
|
||||||
|
<script>
|
||||||
|
window.dataLayer = window.dataLayer || [];
|
||||||
|
function gtag() {
|
||||||
|
dataLayer.push(arguments);
|
||||||
|
}
|
||||||
|
gtag("js", new Date());
|
||||||
|
|
||||||
|
gtag("config", "UA-87498806-2");
|
||||||
|
</script>
|
||||||
<body class="copyright welcome">
|
<body class="copyright welcome">
|
||||||
<div class="landing">
|
<div class="landing">
|
||||||
<div class="logo-circle"></div>
|
<div class="logo-circle"></div>
|
||||||
<div class="logo-circle"></div>
|
<div class="logo-circle"></div>
|
||||||
<div class="logo-circle"></div>
|
<div class="logo-circle"></div>
|
||||||
<h1 data-font="serif" class="logo"><a href="../../">WATCH PARTY</a> | V1.6.0</h1>
|
<h1 data-font="serif" class="logo duplicate">
|
||||||
|
<a href="../../">WATCH PARTY</a> | V1.6.0
|
||||||
|
</h1>
|
||||||
|
<h1 data-font="serif" class="logo">
|
||||||
|
<a href="../../">WATCH PARTY</a> | V1.6.0
|
||||||
|
</h1>
|
||||||
<h5 data-font="sans" class="logo-tag">
|
<h5 data-font="sans" class="logo-tag">
|
||||||
WATCH YOUR FAVORITES,<br />WITH YOUR FAVORITE PEOPLE
|
WATCH YOUR FAVORITES,<br />WITH YOUR FAVORITE PEOPLE
|
||||||
</h5>
|
</h5>
|
||||||
</div>
|
</div>
|
||||||
<div class="features">
|
<div class="features">
|
||||||
<p data-font="sans-bold" class="title subtitle">PLANNED CHANGES</p>
|
<p data-font="sans-bold" class="title subtitle">
|
||||||
|
CHANGES MADE IN FEATURES
|
||||||
|
</p>
|
||||||
<div class="feature-card">
|
<div class="feature-card">
|
||||||
<div class="feature-icon" id="sync"></div>
|
<div class="feature-icon" id="sync">
|
||||||
|
<video
|
||||||
|
loop
|
||||||
|
muted
|
||||||
|
autoplay
|
||||||
|
src="../../media/features/Sync.mp4"
|
||||||
|
></video>
|
||||||
|
</div>
|
||||||
<p data-font="sans" class="feature-text">
|
<p data-font="sans" class="feature-text">
|
||||||
Add support for Crunchyroll
|
Add support for Crunchyroll & Google Play Movies & TV
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="feature-card">
|
||||||
|
<div class="feature-icon">
|
||||||
|
<video
|
||||||
|
loop
|
||||||
|
muted
|
||||||
|
autoplay
|
||||||
|
src="../../media/features/Phone.mp4"
|
||||||
|
></video>
|
||||||
|
</div>
|
||||||
|
<p data-font="sans" class="feature-text">
|
||||||
|
Anyone can start calls now, and calls are more reliable.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="feature-card">
|
||||||
|
<div class="feature-icon">
|
||||||
|
<video
|
||||||
|
loop
|
||||||
|
muted
|
||||||
|
autoplay
|
||||||
|
src="../../media/features/Chat.mp4"
|
||||||
|
></video>
|
||||||
|
</div>
|
||||||
|
<p data-font="sans" class="feature-text">
|
||||||
|
Revamped chat and gif UI, now with replies
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="feature-card">
|
||||||
|
<div class="feature-icon">
|
||||||
|
<video
|
||||||
|
loop
|
||||||
|
muted
|
||||||
|
autoplay
|
||||||
|
src="../../media/features/Hideable.mp4"
|
||||||
|
></video>
|
||||||
|
</div>
|
||||||
|
<p data-font="sans" class="feature-text">
|
||||||
|
Sidebar is now resizable and has better fullscreen support
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="feature-card">
|
||||||
|
<div class="feature-icon">
|
||||||
|
<video
|
||||||
|
loop
|
||||||
|
muted
|
||||||
|
autoplay
|
||||||
|
src="../../media/features/Custom.mp4"
|
||||||
|
></video>
|
||||||
|
</div>
|
||||||
|
<p data-font="sans" class="feature-text">
|
||||||
|
Autocomplete and cross-site party name and pin history
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="tips" class="landing">
|
<div id="tips" class="landing">
|
||||||
<p data-font="sans-bold" class="title">
|
<p data-font="sans-bold" class="title">
|
||||||
PLANNED CHANGES' DETAILS
|
LISTED CHANGE DETAILS
|
||||||
</p>
|
</p>
|
||||||
<div class="tip">
|
<div class="tip">
|
||||||
<p data-font="sans-bold">
|
<p data-font="sans-bold">
|
||||||
Admin only control mode
|
Add support for Crunchyroll
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="tip">
|
<div class="tip">
|
||||||
<p data-font="sans-bold">
|
<p data-font="sans-bold">
|
||||||
Interactive system messages
|
Add support for Google Play Movies & TV
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="tip">
|
<div class="tip">
|
||||||
<p data-font="sans-bold">
|
<p data-font="sans-bold">
|
||||||
Reply to messages with quoting
|
Completely rebuilt Chat UI
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="tip">
|
<div class="tip">
|
||||||
<p data-font="sans-bold">
|
<p data-font="sans-bold">
|
||||||
Party name & pin history across sites
|
Gif UI revamped
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="tip">
|
||||||
|
<p data-font="sans-bold">
|
||||||
|
Shows sending messages
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="tip">
|
||||||
|
<p data-font="sans-bold">
|
||||||
|
Resizable sidebar
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="tip">
|
||||||
|
<p data-font="sans-bold">
|
||||||
|
New Welcome experience (chromewatchparty.com/welcome)
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="tip">
|
||||||
|
<p data-font="sans-bold">
|
||||||
|
Clear party and pin history
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="tip">
|
||||||
|
<p data-font="sans-bold">
|
||||||
|
Fix header bug on website
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="tip">
|
||||||
|
<p data-font="sans-bold">
|
||||||
|
Optimize website feature animations
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="tip">
|
||||||
|
<p data-font="sans-bold">
|
||||||
|
Admin only control mode (affects player sync and call)
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="tip">
|
||||||
|
<p data-font="sans-bold">
|
||||||
|
Anyone can start calls when not in admin only mode
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="tip">
|
||||||
|
<p data-font="sans-bold">
|
||||||
|
Cross site party name and pin history
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="tip">
|
||||||
|
<p data-font="sans-bold">
|
||||||
|
Volume control for users on call
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="tip">
|
||||||
|
<p data-font="sans-bold">
|
||||||
|
Interactive system messages in chat
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="tip">
|
||||||
|
<p data-font="sans-bold">
|
||||||
|
Alerts on sidebar create/join screen
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="tip">
|
||||||
|
<p data-font="sans-bold">
|
||||||
|
Autocomplete for party names and pins
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="tip">
|
||||||
|
<p data-font="sans-bold">
|
||||||
|
Proper page opens on update
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<a
|
<a
|
||||||
@@ -93,19 +295,30 @@ Peacock TV logo is a trademark and intellectual property of Peacock TV & NBC Uni
|
|||||||
</div>
|
</div>
|
||||||
<footer data-font="sans">
|
<footer data-font="sans">
|
||||||
<p class="title built-with">
|
<p class="title built-with">
|
||||||
<a href="../copyright/">COPYRIGHT</a> © 2020 AYUSHYA AMITABH. ALL RIGHTS RESERVED.
|
<a href="../../copyright/">COPYRIGHT</a> © 2020 AYUSHYA AMITABH.
|
||||||
|
ALL RIGHTS RESERVED.
|
||||||
</p>
|
</p>
|
||||||
<p class="title built-with">
|
<p class="title built-with">
|
||||||
BUILT WITH 💚 FOR <a href="https://www.google.com/chrome/">GOOGLE CHROME</a> USING
|
BUILT WITH 💚 FOR
|
||||||
|
<a href="https://www.google.com/chrome/">GOOGLE CHROME</a> USING
|
||||||
<a href="https://firebase.google.com/">FIREBASE</a>,
|
<a href="https://firebase.google.com/">FIREBASE</a>,
|
||||||
<a href="https://material-ui.com/">MATERIAL-UI</a>,
|
<a href="https://material-ui.com/">MATERIAL-UI</a>,
|
||||||
<a href="https://reactjs.org/">REACT JS</a>, <a href="https://nodejs.org/en/">NODE JS</a>,
|
<a href="https://reactjs.org/">REACT JS</a>,
|
||||||
<a href="https://giphy.com/">GIPHY</a>, & <a href="https://dolby.io/">DOLBY VOXEET</a>.
|
<a href="https://nodejs.org/en/">NODE JS</a>,
|
||||||
|
<a href="https://giphy.com/">GIPHY</a>, &
|
||||||
|
<a href="https://dolby.io/">DOLBY VOXEET</a>.
|
||||||
</p>
|
</p>
|
||||||
<a data-font="sans-bold" href="https://paypal.me/Ayushya" class="link-button">
|
<a
|
||||||
|
data-font="sans-bold"
|
||||||
|
href="https://paypal.me/Ayushya"
|
||||||
|
class="link-button"
|
||||||
|
>
|
||||||
Support Watch Party
|
Support Watch Party
|
||||||
</a>
|
</a>
|
||||||
<a data-font="sans-bold" href="https://request.chromewatchparty.com" class="link-button"
|
<a
|
||||||
|
data-font="sans-bold"
|
||||||
|
href="https://request.chromewatchparty.com"
|
||||||
|
class="link-button"
|
||||||
>Get Chrome Extension</a
|
>Get Chrome Extension</a
|
||||||
>
|
>
|
||||||
<a
|
<a
|
||||||
|
|||||||
@@ -4,18 +4,11 @@ Copyright (C) Ayushya Amitabh - All Rights Reserved
|
|||||||
Unauthorized copying of this file, via any medium is strictly prohibited
|
Unauthorized copying of this file, via any medium is strictly prohibited
|
||||||
Proprietary and confidential
|
Proprietary and confidential
|
||||||
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
||||||
|
https://www.chromewatchparty.com/copyright
|
||||||
=========================================================================
|
=========================================================================
|
||||||
ALL CONTENT ON THIS WEBSITE, UNLESS OTHERWISE CITED ARE THE SOLE
|
ALL CONTENT ON WATCH PARTY'S WEBSITE OR IN WATCH PARTY'S CHROME EXTENSION APP, UNLESS OTHERWISE
|
||||||
INTELECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE COPIED, EDITED,
|
CITED ARE THE SOLE INTELECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE
|
||||||
OR REPRODUCED WITHOUT PERMISSION.
|
COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
|
||||||
|
|
||||||
Netflix logo is a trademark and intellectual property of Netflix, Inc.
|
|
||||||
Disney+ logo is a trademark and intellectual property of The Walt Disney Company
|
|
||||||
Prime logo is a trademark and intellectual property of Amazon.com, Inc.
|
|
||||||
YouTube logo is a trademark and intellectual property of Google, Inc.
|
|
||||||
Hulu logo is a trademark and intellectual property of Hulu, LLC.
|
|
||||||
HBO Now and HBO Max logos are trademark and intellectual property of WarnerMedia Direct,LLC.
|
|
||||||
Peacock TV logo is a trademark and intellectual property of Peacock TV & NBC Universal.
|
|
||||||
------------------------------------------------------------------------->
|
------------------------------------------------------------------------->
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
@@ -40,11 +33,22 @@ Peacock TV logo is a trademark and intellectual property of Peacock TV & NBC Uni
|
|||||||
<script src="../scripts/Stickied.js"></script>
|
<script src="../scripts/Stickied.js"></script>
|
||||||
<title>Watch Party | Copyright</title>
|
<title>Watch Party | Copyright</title>
|
||||||
</head>
|
</head>
|
||||||
|
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||||||
|
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-87498806-2">
|
||||||
|
</script>
|
||||||
|
<script>
|
||||||
|
window.dataLayer = window.dataLayer || [];
|
||||||
|
function gtag(){dataLayer.push(arguments);}
|
||||||
|
gtag('js', new Date());
|
||||||
|
|
||||||
|
gtag('config', 'UA-87498806-2');
|
||||||
|
</script>
|
||||||
<body class="copyright">
|
<body class="copyright">
|
||||||
<div class="landing">
|
<div class="landing">
|
||||||
<div class="logo-circle"></div>
|
<div class="logo-circle"></div>
|
||||||
<div class="logo-circle"></div>
|
<div class="logo-circle"></div>
|
||||||
<div class="logo-circle"></div>
|
<div class="logo-circle"></div>
|
||||||
|
<h1 data-font="serif" class="logo duplicate"><a href="../">WATCH PARTY</a> | COPYRIGHT</h1>
|
||||||
<h1 data-font="serif" class="logo"><a href="../">WATCH PARTY</a> | COPYRIGHT</h1>
|
<h1 data-font="serif" class="logo"><a href="../">WATCH PARTY</a> | COPYRIGHT</h1>
|
||||||
<h5 data-font="sans" class="logo-tag">
|
<h5 data-font="sans" class="logo-tag">
|
||||||
Copyright © 2020 Ayushya Amitabh. All Rights Reserved.
|
Copyright © 2020 Ayushya Amitabh. All Rights Reserved.
|
||||||
@@ -68,7 +72,9 @@ Peacock TV logo is a trademark and intellectual property of Peacock TV & NBC Uni
|
|||||||
Hulu logo is a trademark and intellectual property of Hulu, LLC.<br />
|
Hulu logo is a trademark and intellectual property of Hulu, LLC.<br />
|
||||||
HBO Now and HBO Max logos are trademark and intellectual property of WarnerMedia Direct,
|
HBO Now and HBO Max logos are trademark and intellectual property of WarnerMedia Direct,
|
||||||
LLC.<br />
|
LLC.<br />
|
||||||
Peacock TV logo is a trademark and intellectual property of Peacock TV & NBC Universal.
|
Peacock TV logo is a trademark and intellectual property of Peacock TV & NBC Universal.<br />
|
||||||
|
Google Play Movies & TV logo is a trademark and intellectual property of Google, Inc.<br />
|
||||||
|
Crunchyroll logo is a trademark and intellectual property of Crunchyroll and Ellation, Inc.
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@@ -3,6 +3,11 @@ Copyright (C) Ayushya Amitabh - All Rights Reserved
|
|||||||
Unauthorized copying of this file, via any medium is strictly prohibited
|
Unauthorized copying of this file, via any medium is strictly prohibited
|
||||||
Proprietary and confidential
|
Proprietary and confidential
|
||||||
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
||||||
|
https://www.chromewatchparty.com/copyright
|
||||||
|
=========================================================================
|
||||||
|
ALL CONTENT ON WATCH PARTY'S WEBSITE OR IN WATCH PARTY'S CHROME EXTENSION APP, UNLESS OTHERWISE
|
||||||
|
CITED ARE THE SOLE INTELECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE
|
||||||
|
COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
@@ -35,10 +40,13 @@ Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
|||||||
}
|
}
|
||||||
[data-font='serif'] {
|
[data-font='serif'] {
|
||||||
font-family: 'PixelSplitter', sans-serif;
|
font-family: 'PixelSplitter', sans-serif;
|
||||||
|
font-display: swap;
|
||||||
}
|
}
|
||||||
[data-font='sans'] {
|
[data-font='sans'] {
|
||||||
font-family: 'Glacial', sans-serif;
|
font-family: 'Glacial', sans-serif;
|
||||||
|
font-display: swap;
|
||||||
}
|
}
|
||||||
[data-font='sans-bold'] {
|
[data-font='sans-bold'] {
|
||||||
font-family: 'GlacialBold', sans-serif;
|
font-family: 'GlacialBold', sans-serif;
|
||||||
|
font-display: swap;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,126 +4,404 @@ Copyright (C) Ayushya Amitabh - All Rights Reserved
|
|||||||
Unauthorized copying of this file, via any medium is strictly prohibited
|
Unauthorized copying of this file, via any medium is strictly prohibited
|
||||||
Proprietary and confidential
|
Proprietary and confidential
|
||||||
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
||||||
|
https://www.chromewatchparty.com/copyright
|
||||||
=========================================================================
|
=========================================================================
|
||||||
ALL CONTENT ON THIS WEBSITE, UNLESS OTHERWISE CITED ARE THE SOLE
|
ALL CONTENT ON WATCH PARTY'S WEBSITE OR IN WATCH PARTY'S CHROME EXTENSION APP, UNLESS OTHERWISE
|
||||||
INTELECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE COPIED, EDITED,
|
CITED ARE THE SOLE INTELECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE
|
||||||
OR REPRODUCED WITHOUT PERMISSION.
|
COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
|
||||||
|
|
||||||
Netflix logo is a trademark and intellectual property of Netflix, Inc.
|
|
||||||
Disney+ logo is a trademark and intellectual property of The Walt Disney Company
|
|
||||||
Prime logo is a trademark and intellectual property of Amazon.com, Inc.
|
|
||||||
YouTube logo is a trademark and intellectual property of Google, Inc.
|
|
||||||
Hulu logo is a trademark and intellectual property of Hulu, LLC.
|
|
||||||
HBO Now and HBO Max logos are trademark and intellectual property of WarnerMedia Direct,LLC.
|
|
||||||
Peacock TV logo is a trademark and intellectual property of Peacock TV & NBC Universal.
|
|
||||||
------------------------------------------------------------------------->
|
------------------------------------------------------------------------->
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<link rel="apple-touch-icon" sizes="57x57" href="./icons/apple-icon-57x57.png" />
|
<link
|
||||||
<link rel="apple-touch-icon" sizes="60x60" href="./icons/apple-icon-60x60.png" />
|
rel="apple-touch-icon"
|
||||||
<link rel="apple-touch-icon" sizes="72x72" href="./icons/apple-icon-72x72.png" />
|
sizes="57x57"
|
||||||
<link rel="apple-touch-icon" sizes="76x76" href="./icons/apple-icon-76x76.png" />
|
href="./icons/apple-icon-57x57.png"
|
||||||
<link rel="apple-touch-icon" sizes="114x114" href="./icons/apple-icon-114x114.png" />
|
/>
|
||||||
<link rel="apple-touch-icon" sizes="120x120" href="./icons/apple-icon-120x120.png" />
|
<link
|
||||||
<link rel="apple-touch-icon" sizes="144x144" href="./icons/apple-icon-144x144.png" />
|
rel="apple-touch-icon"
|
||||||
<link rel="apple-touch-icon" sizes="152x152" href="./icons/apple-icon-152x152.png" />
|
sizes="60x60"
|
||||||
<link rel="apple-touch-icon" sizes="180x180" href="./icons/apple-icon-180x180.png" />
|
href="./icons/apple-icon-60x60.png"
|
||||||
<link rel="icon" type="image/png" sizes="192x192" href="./icons/android-icon-192x192.png" />
|
/>
|
||||||
<link rel="icon" type="image/png" sizes="32x32" href="./icons/favicon-32x32.png" />
|
<link
|
||||||
<link rel="icon" type="image/png" sizes="96x96" href="./icons/favicon-96x96.png" />
|
rel="apple-touch-icon"
|
||||||
<link rel="icon" type="image/png" sizes="16x16" href="./icons/favicon-16x16.png" />
|
sizes="72x72"
|
||||||
|
href="./icons/apple-icon-72x72.png"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="apple-touch-icon"
|
||||||
|
sizes="76x76"
|
||||||
|
href="./icons/apple-icon-76x76.png"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="apple-touch-icon"
|
||||||
|
sizes="114x114"
|
||||||
|
href="./icons/apple-icon-114x114.png"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="apple-touch-icon"
|
||||||
|
sizes="120x120"
|
||||||
|
href="./icons/apple-icon-120x120.png"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="apple-touch-icon"
|
||||||
|
sizes="144x144"
|
||||||
|
href="./icons/apple-icon-144x144.png"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="apple-touch-icon"
|
||||||
|
sizes="152x152"
|
||||||
|
href="./icons/apple-icon-152x152.png"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="apple-touch-icon"
|
||||||
|
sizes="180x180"
|
||||||
|
href="./icons/apple-icon-180x180.png"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="icon"
|
||||||
|
type="image/png"
|
||||||
|
sizes="192x192"
|
||||||
|
href="./icons/android-icon-192x192.png"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="icon"
|
||||||
|
type="image/png"
|
||||||
|
sizes="32x32"
|
||||||
|
href="./icons/favicon-32x32.png"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="icon"
|
||||||
|
type="image/png"
|
||||||
|
sizes="96x96"
|
||||||
|
href="./icons/favicon-96x96.png"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="icon"
|
||||||
|
type="image/png"
|
||||||
|
sizes="16x16"
|
||||||
|
href="./icons/favicon-16x16.png"
|
||||||
|
/>
|
||||||
<link rel="icon" href="./icons/favicon.ico" />
|
<link rel="icon" href="./icons/favicon.ico" />
|
||||||
<link rel="manifest" href="./manifest.json" />
|
<link rel="manifest" href="./manifest.json" />
|
||||||
<meta name="msapplication-TileImage" content="./icons/ms-icon-144x144.png" />
|
<meta
|
||||||
|
name="msapplication-TileImage"
|
||||||
|
content="./icons/ms-icon-144x144.png"
|
||||||
|
/>
|
||||||
<link rel="stylesheet" type="text/css" href="./font.css" />
|
<link rel="stylesheet" type="text/css" href="./font.css" />
|
||||||
<link rel="stylesheet" type="text/css" href="./styles/index.css" />
|
<link rel="stylesheet" type="text/css" href="./styles/index.css" />
|
||||||
<script src="./scripts/Stickied.js"></script>
|
<script src="./scripts/Stickied.js"></script>
|
||||||
<title>Watch Party</title>
|
<title>Watch Party</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||||||
|
<script
|
||||||
|
async
|
||||||
|
src="https://www.googletagmanager.com/gtag/js?id=UA-87498806-2"
|
||||||
|
></script>
|
||||||
|
<script>
|
||||||
|
window.dataLayer = window.dataLayer || [];
|
||||||
|
function gtag() {
|
||||||
|
dataLayer.push(arguments);
|
||||||
|
}
|
||||||
|
gtag("js", new Date());
|
||||||
|
|
||||||
|
gtag("config", "UA-87498806-2");
|
||||||
|
</script>
|
||||||
|
<body class="home">
|
||||||
<div class="landing">
|
<div class="landing">
|
||||||
<div class="logo-circle"></div>
|
<div class="logo-circle"></div>
|
||||||
<div class="logo-circle"></div>
|
<div class="logo-circle"></div>
|
||||||
<div class="logo-circle"></div>
|
<div class="logo-circle"></div>
|
||||||
|
<h1 data-font="serif" class="logo duplicate">WATCH PARTY</h1>
|
||||||
<h1 data-font="serif" class="logo">WATCH PARTY</h1>
|
<h1 data-font="serif" class="logo">WATCH PARTY</h1>
|
||||||
<h5 data-font="sans" class="logo-tag">
|
<h5 data-font="sans" class="logo-tag">
|
||||||
WATCH YOUR FAVORITES,<br />WITH YOUR FAVORITE PEOPLE
|
WATCH YOUR FAVORITES,<br />WITH YOUR FAVORITE PEOPLE
|
||||||
</h5>
|
</h5>
|
||||||
<p data-font="sans-bold" class="title subtitle">FREE. NO SIGNUP. NO BS.<br />WORKS WITH</p>
|
<p data-font="sans-bold" class="title subtitle">
|
||||||
|
FREE. NO SIGNUP. NO BS.<br />WORKS WITH
|
||||||
|
</p>
|
||||||
<div class="supported">
|
<div class="supported">
|
||||||
<div data-full-support class="supported-logo" id="netflix"></div>
|
<div data-full-support class="supported-logo" id="netflix"></div>
|
||||||
<div data-full-support class="supported-logo" id="hulu"></div>
|
<div data-full-support class="supported-logo" id="hulu"></div>
|
||||||
<div data-full-support class="supported-logo" id="disney"></div>
|
<div data-full-support class="supported-logo" id="disney"></div>
|
||||||
<div data-full-support class="supported-logo" id="prime"></div>
|
<div data-full-support class="supported-logo" id="prime"></div>
|
||||||
<div data-full-support class="supported-logo" id="youtube"></div>
|
<div data-full-support class="supported-logo" id="youtube"></div>
|
||||||
<div data-beta-support class="supported-logo" id="hbonow"></div>
|
<div data-full-support class="supported-logo" id="hbonow"></div>
|
||||||
<div data-beta-support class="supported-logo" id="hbomax"></div>
|
<div data-full-support class="supported-logo" id="hbomax"></div>
|
||||||
<div data-beta-support class="supported-logo" id="peacock"></div>
|
<div data-full-support class="supported-logo" id="peacock"></div>
|
||||||
|
<div
|
||||||
|
data-upcoming-support="In v1.6.0"
|
||||||
|
class="supported-logo"
|
||||||
|
id="googleplay"
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
data-upcoming-support="In v1.6.0"
|
||||||
|
class="supported-logo"
|
||||||
|
id="crunchyroll"
|
||||||
|
></div>
|
||||||
</div>
|
</div>
|
||||||
<a data-font="sans-bold" href="https://request.chromewatchparty.com" class="link-button"
|
<a
|
||||||
>Get Chrome Extension</a
|
data-font="sans-bold"
|
||||||
|
href="https://request.chromewatchparty.com"
|
||||||
|
class="link-button duplicate"
|
||||||
>
|
>
|
||||||
|
Get Chrome Extension
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
data-font="sans-bold"
|
||||||
|
href="https://request.chromewatchparty.com"
|
||||||
|
class="link-button"
|
||||||
|
>
|
||||||
|
Get Chrome Extension
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="features">
|
<div class="features">
|
||||||
<p data-font="sans-bold" class="title subtitle">FEATURES</p>
|
<p data-font="sans-bold" class="title subtitle">FEATURES</p>
|
||||||
<div class="feature-card">
|
<div class="feature-card">
|
||||||
<div class="feature-icon" id="sync"></div>
|
<div class="feature-icon" id="sync">
|
||||||
|
<video loop muted autoplay src="./media/features/Sync.mp4"></video>
|
||||||
|
</div>
|
||||||
<p data-font="sans" class="feature-text">
|
<p data-font="sans" class="feature-text">
|
||||||
Watch Party syncs play, pause and timestamp.
|
Watch Party syncs play, pause and timestamp.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="feature-card">
|
<div class="feature-card">
|
||||||
<div class="feature-icon" id="phone"></div>
|
<div class="feature-icon" id="phone">
|
||||||
|
<video loop muted autoplay src="./media/features/Phone.mp4"></video>
|
||||||
|
</div>
|
||||||
<p data-font="sans" class="feature-text">
|
<p data-font="sans" class="feature-text">
|
||||||
Free group voice calls - for when text and GIFs just won't do.
|
Free group voice calls - for when text and GIFs just won't do.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="feature-card">
|
<div class="feature-card">
|
||||||
<div class="feature-icon" id="chat"></div>
|
<div class="feature-icon" id="chat">
|
||||||
|
<video loop muted autoplay src="./media/features/Chat.mp4"></video>
|
||||||
|
</div>
|
||||||
<p data-font="sans" class="feature-text">
|
<p data-font="sans" class="feature-text">
|
||||||
Unlimited gifs from Giphy in chat.
|
Unlimited gifs from Giphy in chat.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="feature-card">
|
<div class="feature-card">
|
||||||
<div class="feature-icon" id="delete"></div>
|
<div class="feature-icon" id="delete">
|
||||||
|
<video loop muted autoplay src="./media/features/Delete.mp4"></video>
|
||||||
|
</div>
|
||||||
<p data-font="sans" class="feature-text">
|
<p data-font="sans" class="feature-text">
|
||||||
What happens in Watch Party, stays in Watch Party - for 24 hours, then it's all gone.
|
What happens in Watch Party, stays in Watch Party - for 24 hours, then
|
||||||
|
it's all gone.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="feature-card">
|
<div class="feature-card">
|
||||||
<div class="feature-icon" id="hideable"></div>
|
<div class="feature-icon" id="hideable">
|
||||||
|
<video
|
||||||
|
loop
|
||||||
|
muted
|
||||||
|
autoplay
|
||||||
|
src="./media/features/Hideable.mp4"
|
||||||
|
></video>
|
||||||
|
</div>
|
||||||
<p data-font="sans" class="feature-text">
|
<p data-font="sans" class="feature-text">
|
||||||
There when you need it, hideable when you want to focus on the show.
|
There when you need it, hideable when you want to focus on the show.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="feature-card">
|
<div class="feature-card">
|
||||||
<div class="feature-icon" id="custom"></div>
|
<div class="feature-icon" id="custom">
|
||||||
|
<video loop muted autoplay src="./media/features/Custom.mp4"></video>
|
||||||
|
</div>
|
||||||
<p data-font="sans" class="feature-text">
|
<p data-font="sans" class="feature-text">
|
||||||
No party crashers. Custom party names secured with custom pins.
|
No party crashers. Custom party names secured with custom pins.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="feature-card">
|
<div class="feature-card">
|
||||||
<div class="feature-icon" id="signup"></div>
|
<div class="feature-icon" id="signup">
|
||||||
|
<video loop muted autoplay src="./media/features/Signup.mp4"></video>
|
||||||
|
</div>
|
||||||
<p data-font="sans" class="feature-text">
|
<p data-font="sans" class="feature-text">
|
||||||
No sign up, no login, no data taken from you.
|
No sign up, no login, no data taken from you.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="getting-started" class="pop-features">
|
||||||
|
<p data-font="sans-bold" class="title subtitle">
|
||||||
|
GETTING STARTED
|
||||||
|
</p>
|
||||||
|
<div class="pop-feature">
|
||||||
|
<div id="title-card-container">
|
||||||
|
<div id="title-card">
|
||||||
|
<div data-font="serif" id="fab">WP</div>
|
||||||
|
<div id="sidebar"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="explanation">
|
||||||
|
<div>
|
||||||
|
<h4 data-font="sans-bold">TO BE OR NOT TO BE</h4>
|
||||||
|
<p data-font="sans">
|
||||||
|
Watch Party is built to not be in your way. There when you need
|
||||||
|
it, gone when you don't. The sidebar is now resizeable, and now
|
||||||
|
supports having access to Watch Party in fullscreen. (Use the
|
||||||
|
fullscreen button in the sidebar)
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="pop-feature alternate">
|
||||||
|
<div id="title-card-container">
|
||||||
|
<div id="title-card">
|
||||||
|
<h5 data-font="sans-bold" id="title-card-title">WATCH PARTY</h5>
|
||||||
|
<h3 data-font="sans" id="title-card-subtitle">YOUR PARTY NAME</h3>
|
||||||
|
<p data-font="sans" id="control-notification">
|
||||||
|
Allow chat notification when side panel is closed
|
||||||
|
<span>Notifications show up when the side bar is hidden</span>
|
||||||
|
</p>
|
||||||
|
<p data-font="sans" id="control-autorejoin">
|
||||||
|
Allow Watch Party to auto rejoin
|
||||||
|
<span
|
||||||
|
>Automatically rejoin party if you return to the page within 1
|
||||||
|
minute</span
|
||||||
|
>
|
||||||
|
</p>
|
||||||
|
<p data-font="sans" id="control-admin">
|
||||||
|
Enable admin only mode
|
||||||
|
<span>Only party admin can sync player and start calls</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="explanation">
|
||||||
|
<div>
|
||||||
|
<h4 data-font="sans-bold">Stay in control</h4>
|
||||||
|
<p data-font="sans">
|
||||||
|
Find your settings by clicking on title card (when you're in a
|
||||||
|
party) or in the settings panel (when you're creating or joining)
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="pop-feature">
|
||||||
|
<div id="title-card-container">
|
||||||
|
<div id="title-card">
|
||||||
|
<h5 data-font="sans-bold" id="system-message">
|
||||||
|
Ayushya started the party.
|
||||||
|
</h5>
|
||||||
|
|
||||||
|
<div id="ti">
|
||||||
|
<div id="tn">SOMEONE</div>
|
||||||
|
<div id="tm">
|
||||||
|
<div id="tt">
|
||||||
|
<span>12:00:00 PM</span>
|
||||||
|
<div id="ri"></div>
|
||||||
|
</div>
|
||||||
|
<p>Hiya buddy!</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="ti" class="mm">
|
||||||
|
<div id="tn">AYUSHYA</div>
|
||||||
|
<div id="tr">Hiya buddy!</div>
|
||||||
|
<div id="tm">
|
||||||
|
<div id="tt">
|
||||||
|
<span>12:00:00 PM</span>
|
||||||
|
<div id="ri"></div>
|
||||||
|
</div>
|
||||||
|
<p>OH GOD NO! PLEASE GOD NO! NO!</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="ti">
|
||||||
|
<div id="tn">SOMEONE</div>
|
||||||
|
<div id="tm">
|
||||||
|
<div id="tt">
|
||||||
|
<span>12:00:00 PM</span>
|
||||||
|
<div id="ri"></div>
|
||||||
|
</div>
|
||||||
|
<img
|
||||||
|
src="https://media.giphy.com/media/d10dMmzqCYqQ0/giphy.gif"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="ti" class="mm">
|
||||||
|
<div id="tn">SOMEONE</div>
|
||||||
|
<div id="tr">
|
||||||
|
<img
|
||||||
|
src="https://media.giphy.com/media/d10dMmzqCYqQ0/giphy.gif"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div id="tm">
|
||||||
|
<div id="tt">
|
||||||
|
<span>12:00:00 PM</span>
|
||||||
|
<div id="ri"></div>
|
||||||
|
</div>
|
||||||
|
<p>Let's watch The Office</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="explanation">
|
||||||
|
<div>
|
||||||
|
<h4 data-font="sans-bold">FULL FEATURED CHAT</h4>
|
||||||
|
<p data-font="sans">
|
||||||
|
A brand new, completely revamped chat user interface, now has
|
||||||
|
replies, shows pending messages, and improves the Giphy GIF picker
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="pop-feature alternate">
|
||||||
|
<div id="title-card-container">
|
||||||
|
<div id="title-card">
|
||||||
|
<h5 data-font="sans-bold" id="title-card-title">WATCH PARTY</h5>
|
||||||
|
<h3 data-font="sans" id="title-card-subtitle">ANIME WATCH PARTY</h3>
|
||||||
|
<h6 data-font="sans" id="title-card-tagline">USERS IN PARTY</h6>
|
||||||
|
<p data-font="sans" id="call-user-chip">Ayushya</p>
|
||||||
|
<p data-font="sans" id="call-user-chip">Someone</p>
|
||||||
|
<p data-font="sans" id="call-user-chip">Third Party</p>
|
||||||
|
<p data-font="sans" id="call-user-chip">Won't Stop Talking</p>
|
||||||
|
<h6 data-font="sans" id="title-card-tagline">USERS ON CALL</h6>
|
||||||
|
<p data-font="sans" id="call-user-chip">Ayushya</p>
|
||||||
|
<p data-font="sans" id="call-user-chip" class="not-me-user-chip">
|
||||||
|
Someone
|
||||||
|
</p>
|
||||||
|
<p data-font="sans" id="call-user-chip" class="not-me-user-chip">
|
||||||
|
Won't Stop Talking
|
||||||
|
<input type="range" value="2" min="0" max="10" />
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="explanation">
|
||||||
|
<div>
|
||||||
|
<h4 data-font="sans-bold">MADE FOR YOU & YOUR GANG</h4>
|
||||||
|
<p data-font="sans">
|
||||||
|
See who's in your party, get on a call with your party, and volume
|
||||||
|
control for the person who just won't stop talking.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<footer data-font="sans">
|
<footer data-font="sans">
|
||||||
<p class="title built-with">
|
<p class="title built-with">
|
||||||
<a href="./copyright/">COPYRIGHT</a> © 2020 AYUSHYA AMITABH. ALL RIGHTS RESERVED.
|
<a href="./copyright/">COPYRIGHT</a> © 2020 AYUSHYA AMITABH. ALL
|
||||||
|
RIGHTS RESERVED.
|
||||||
</p>
|
</p>
|
||||||
<p class="title built-with">
|
<p class="title built-with">
|
||||||
BUILT WITH 💚 FOR <a href="https://www.google.com/chrome/">GOOGLE CHROME</a> USING
|
BUILT WITH 💚 FOR
|
||||||
|
<a href="https://www.google.com/chrome/">GOOGLE CHROME</a> USING
|
||||||
<a href="https://firebase.google.com/">FIREBASE</a>,
|
<a href="https://firebase.google.com/">FIREBASE</a>,
|
||||||
<a href="https://material-ui.com/">MATERIAL-UI</a>,
|
<a href="https://material-ui.com/">MATERIAL-UI</a>,
|
||||||
<a href="https://reactjs.org/">REACT JS</a>, <a href="https://nodejs.org/en/">NODE JS</a>,
|
<a href="https://reactjs.org/">REACT JS</a>,
|
||||||
<a href="https://giphy.com/">GIPHY</a>, & <a href="https://dolby.io/">DOLBY VOXEET</a>.
|
<a href="https://nodejs.org/en/">NODE JS</a>,
|
||||||
|
<a href="https://giphy.com/">GIPHY</a>, &
|
||||||
|
<a href="https://dolby.io/">DOLBY VOXEET</a>.
|
||||||
</p>
|
</p>
|
||||||
<a data-font="sans-bold" href="https://paypal.me/Ayushya" class="link-button">
|
<a
|
||||||
|
data-font="sans-bold"
|
||||||
|
href="https://paypal.me/Ayushya"
|
||||||
|
class="link-button"
|
||||||
|
>
|
||||||
Support Watch Party
|
Support Watch Party
|
||||||
</a>
|
</a>
|
||||||
<a data-font="sans-bold" href="https://request.chromewatchparty.com" class="link-button"
|
<a
|
||||||
|
data-font="sans-bold"
|
||||||
|
href="https://request.chromewatchparty.com"
|
||||||
|
class="link-button"
|
||||||
>Get Chrome Extension</a
|
>Get Chrome Extension</a
|
||||||
>
|
>
|
||||||
<a
|
<a
|
||||||
|
|||||||
@@ -1,9 +1,3 @@
|
|||||||
/************************************************************************
|
|
||||||
Copyright (C) Ayushya Amitabh - All Rights Reserved
|
|
||||||
Unauthorized copying of this file, via any medium is strictly prohibited
|
|
||||||
Proprietary and confidential
|
|
||||||
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
|
||||||
************************************************************************/
|
|
||||||
{
|
{
|
||||||
"name": "Watch Party",
|
"name": "Watch Party",
|
||||||
"short_name": "WP",
|
"short_name": "WP",
|
||||||
|
|||||||
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 26 KiB |
@@ -3,30 +3,43 @@ Copyright (C) Ayushya Amitabh - All Rights Reserved
|
|||||||
Unauthorized copying of this file, via any medium is strictly prohibited
|
Unauthorized copying of this file, via any medium is strictly prohibited
|
||||||
Proprietary and confidential
|
Proprietary and confidential
|
||||||
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
||||||
|
https://www.chromewatchparty.com/copyright
|
||||||
|
=========================================================================
|
||||||
|
ALL CONTENT ON WATCH PARTY'S WEBSITE OR IN WATCH PARTY'S CHROME EXTENSION APP, UNLESS OTHERWISE
|
||||||
|
CITED ARE THE SOLE INTELECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE
|
||||||
|
COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
|
|
||||||
var LOGO_INIT = 0;
|
var LOGO_INIT = 0;
|
||||||
var GET_INIT = 0;
|
var GET_INIT = 0;
|
||||||
function handleSticky() {
|
function handleSticky() {
|
||||||
const logo = document.querySelector('.logo');
|
const logo = document.querySelector('.logo.duplicate');
|
||||||
const get = document.querySelector('.landing .link-button');
|
const get = document.querySelector('.landing .link-button.duplicate');
|
||||||
if (window.scrollY >= LOGO_INIT + logo.offsetHeight * 2) {
|
if (window.scrollY >= LOGO_INIT + logo.offsetHeight) {
|
||||||
logo.classList.add('stickied');
|
logo.classList.add('stickied');
|
||||||
} else {
|
} else {
|
||||||
logo.classList.remove('stickied');
|
logo.classList.remove('stickied');
|
||||||
}
|
}
|
||||||
if (get) {
|
if (get) {
|
||||||
if (window.scrollY >= GET_INIT + get.offsetHeight * 2) {
|
if (window.scrollY >= GET_INIT + get.offsetHeight) {
|
||||||
get.classList.add('stickied');
|
get.classList.add('stickied');
|
||||||
} else {
|
} else {
|
||||||
get.classList.remove('stickied');
|
get.classList.remove('stickied');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
function handleLogoMargin () {
|
||||||
|
const logo = document.querySelector('.logo.duplicate');
|
||||||
|
if (logo) document.documentElement.style.setProperty('--logo-offset', '-' + logo.offsetHeight + 'px');
|
||||||
|
const linkButton = document.querySelector('.link-button.duplicate');
|
||||||
|
if (linkButton) document.documentElement.style.setProperty('--link-button-offset', '-' + linkButton.offsetHeight + 'px');
|
||||||
|
}
|
||||||
window.onload = function () {
|
window.onload = function () {
|
||||||
LOGO_INIT = document.querySelector('.logo').offsetTop;
|
LOGO_INIT = document.querySelector('.logo').offsetTop;
|
||||||
GET_INIT = document.querySelector('.landing .link-button')
|
GET_INIT = document.querySelector('.landing .link-button')
|
||||||
? document.querySelector('.landing .link-button').offsetTop
|
? document.querySelector('.landing .link-button').offsetTop
|
||||||
: 0;
|
: 0;
|
||||||
|
this.handleLogoMargin();
|
||||||
window.addEventListener('scroll', this.handleSticky);
|
window.addEventListener('scroll', this.handleSticky);
|
||||||
|
window.addEventListener('resize', this.handleLogoMargin);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,6 +3,11 @@ Copyright (C) Ayushya Amitabh - All Rights Reserved
|
|||||||
Unauthorized copying of this file, via any medium is strictly prohibited
|
Unauthorized copying of this file, via any medium is strictly prohibited
|
||||||
Proprietary and confidential
|
Proprietary and confidential
|
||||||
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
||||||
|
https://www.chromewatchparty.com/copyright
|
||||||
|
=========================================================================
|
||||||
|
ALL CONTENT ON WATCH PARTY'S WEBSITE OR IN WATCH PARTY'S CHROME EXTENSION APP, UNLESS OTHERWISE
|
||||||
|
CITED ARE THE SOLE INTELECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE
|
||||||
|
COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
|
|
||||||
html {
|
html {
|
||||||
|
|||||||
@@ -3,6 +3,11 @@ Copyright (C) Ayushya Amitabh - All Rights Reserved
|
|||||||
Unauthorized copying of this file, via any medium is strictly prohibited
|
Unauthorized copying of this file, via any medium is strictly prohibited
|
||||||
Proprietary and confidential
|
Proprietary and confidential
|
||||||
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
||||||
|
https://www.chromewatchparty.com/copyright
|
||||||
|
=========================================================================
|
||||||
|
ALL CONTENT ON WATCH PARTY'S WEBSITE OR IN WATCH PARTY'S CHROME EXTENSION APP, UNLESS OTHERWISE
|
||||||
|
CITED ARE THE SOLE INTELECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE
|
||||||
|
COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
|
|
||||||
@keyframes circleFloat {
|
@keyframes circleFloat {
|
||||||
@@ -71,6 +76,17 @@ body {
|
|||||||
letter-spacing: 2.2rem;
|
letter-spacing: 2.2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.logo.duplicate {
|
||||||
|
margin-bottom: var(--logo-offset);
|
||||||
|
opacity: 0;
|
||||||
|
height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.link-button.duplicate {
|
||||||
|
margin-bottom: var(--link-button-offset);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.logo-tag {
|
.logo-tag {
|
||||||
color: var(--primary-text);
|
color: var(--primary-text);
|
||||||
font-size: 3.2rem;
|
font-size: 3.2rem;
|
||||||
@@ -129,16 +145,17 @@ body {
|
|||||||
margin: 10rem 0;
|
margin: 10rem 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.feature-icon {
|
.feature-icon video {
|
||||||
padding: 5rem;
|
|
||||||
background-position: left !important;
|
|
||||||
background-size: contain !important;
|
|
||||||
background-repeat: no-repeat !important;
|
|
||||||
background-color: black;
|
|
||||||
margin: 2.5rem 0;
|
|
||||||
display: table;
|
|
||||||
width: fit-content;
|
|
||||||
border-radius: 100%;
|
border-radius: 100%;
|
||||||
|
width: 10rem;
|
||||||
|
height: auto;
|
||||||
|
margin: 0 auto;
|
||||||
|
margin-top: 9rem;
|
||||||
|
transition: all ease-in-out 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.feature-card .feature-icon video {
|
||||||
|
transform: scale(2.5) translateY(-50%) translateX(1.5rem);
|
||||||
}
|
}
|
||||||
|
|
||||||
.feature-text {
|
.feature-text {
|
||||||
@@ -207,7 +224,7 @@ footer .link-button {
|
|||||||
|
|
||||||
.welcome .landing#tips .tip {
|
.welcome .landing#tips .tip {
|
||||||
padding: 3rem 0;
|
padding: 3rem 0;
|
||||||
border-bottom: 0.5px solid var(--primary-medium);
|
border-bottom: 0.5px solid var(--cta);
|
||||||
padding-right: 3rem;
|
padding-right: 3rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -239,7 +256,7 @@ footer .link-button {
|
|||||||
.landing .supported .supported-logo[data-full-support]::before,
|
.landing .supported .supported-logo[data-full-support]::before,
|
||||||
.landing .supported .supported-logo[data-beta-support]::before,
|
.landing .supported .supported-logo[data-beta-support]::before,
|
||||||
.landing .supported .supported-logo[data-upcoming-support]::before {
|
.landing .supported .supported-logo[data-upcoming-support]::before {
|
||||||
content: 'FULLY SUPPORTED';
|
content: "FULLY SUPPORTED";
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
@@ -250,16 +267,407 @@ footer .link-button {
|
|||||||
font-size: 0.8rem;
|
font-size: 0.8rem;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
color: var(--primary);
|
color: var(--primary);
|
||||||
font-family: 'GlacialBold';
|
font-family: "GlacialBold";
|
||||||
background-color: var(--cta);
|
background-color: var(--cta);
|
||||||
padding: 1rem 0;
|
padding: 1rem 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.landing .supported .supported-logo[data-beta-support]::before {
|
.landing .supported .supported-logo[data-beta-support]::before {
|
||||||
content: 'BETA SUPPORT';
|
content: "BETA SUPPORT";
|
||||||
}
|
}
|
||||||
|
|
||||||
.landing .supported .supported-logo[data-upcoming-support]::before {
|
.landing .supported .supported-logo[data-upcoming-support]::before {
|
||||||
content: attr(data-upcoming-support);
|
content: attr(data-upcoming-support);
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.home .pop-features {
|
||||||
|
margin-bottom: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pop-features {
|
||||||
|
padding: 35px;
|
||||||
|
padding-left: 70px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pop-features .title {
|
||||||
|
margin-bottom: 70px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pop-feature {
|
||||||
|
width: 100%;
|
||||||
|
height: fit-content;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pop-feature > * {
|
||||||
|
flex: 1;
|
||||||
|
margin: 40px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#title-card {
|
||||||
|
border-radius: 26px;
|
||||||
|
background: var(--primary-light);
|
||||||
|
width: 500px;
|
||||||
|
position: relative;
|
||||||
|
height: 500px;
|
||||||
|
box-shadow: 0px 0px 84px var(--primary-medium);
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
div#title-card {
|
||||||
|
width: calc(500px - 60px);
|
||||||
|
height: calc(500px - 60px);
|
||||||
|
padding: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h5#title-card-title {
|
||||||
|
font-size: 20px;
|
||||||
|
color: var(--cta);
|
||||||
|
letter-spacing: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3#title-card-subtitle {
|
||||||
|
font-size: 30px;
|
||||||
|
letter-spacing: 5px;
|
||||||
|
margin: 7.5px 0px;
|
||||||
|
color: var(--primary-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
p#control-notification,
|
||||||
|
p#control-autorejoin,
|
||||||
|
p#control-admin {
|
||||||
|
font-size: 15px;
|
||||||
|
padding: 10px 55px;
|
||||||
|
background: var(--primary);
|
||||||
|
border-radius: 26px;
|
||||||
|
color: var(--primary-text);
|
||||||
|
box-shadow: 0px 0px 20px var(--primary-medium);
|
||||||
|
margin: 35px 0px;
|
||||||
|
width: max-content;
|
||||||
|
}
|
||||||
|
|
||||||
|
p#control-notification {
|
||||||
|
margin-left: -150px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p#control-autorejoin {
|
||||||
|
margin-left: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p#control-admin {
|
||||||
|
margin-left: -75px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p#control-notification span,
|
||||||
|
p#control-autorejoin span,
|
||||||
|
p#control-admin span {
|
||||||
|
display: block;
|
||||||
|
color: #949494;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pop-feature .explanation > div {
|
||||||
|
margin: auto auto;
|
||||||
|
align-items: center;
|
||||||
|
max-width: 55%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pop-feature .explanation div h4 {
|
||||||
|
color: var(--primary-text);
|
||||||
|
font-size: 20px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 5px;
|
||||||
|
margin-bottom: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pop-feature .explanation p {
|
||||||
|
color: var(--primary-text);
|
||||||
|
font-size: 16px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 5px;
|
||||||
|
line-height: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pop-feature .explanation {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
h5#system-message {
|
||||||
|
text-align: center;
|
||||||
|
color: var(--primary-text);
|
||||||
|
font-size: 16px;
|
||||||
|
letter-spacing: 2px;
|
||||||
|
margin: 5px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
p#call-user-chip {
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 20px;
|
||||||
|
padding: 10px 25px;
|
||||||
|
color: var(--primary-text);
|
||||||
|
border-radius: 26px;
|
||||||
|
background: var(--cta);
|
||||||
|
color: var(--primary-medium);
|
||||||
|
margin-right: 20px;
|
||||||
|
position: relative;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p#call-user-chip.not-me-user-chip {
|
||||||
|
background: var(--primary);
|
||||||
|
color: var(--primary-text);
|
||||||
|
display: inline-flex;
|
||||||
|
margin: 0;
|
||||||
|
max-width: fit-content;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
p#call-user-chip.not-me-user-chip input {
|
||||||
|
margin-left: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h6#title-card-tagline {
|
||||||
|
color: var(--primary-medium);
|
||||||
|
font-size: 15px;
|
||||||
|
color: var(--primary);
|
||||||
|
margin: 20px 0;
|
||||||
|
letter-spacing: 3.5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes circleMove {
|
||||||
|
0% {
|
||||||
|
right: -40px;
|
||||||
|
bottom: -40px;
|
||||||
|
}
|
||||||
|
35% {
|
||||||
|
right: 200px;
|
||||||
|
bottom: 350px;
|
||||||
|
}
|
||||||
|
60% {
|
||||||
|
right: 200px;
|
||||||
|
bottom: 350px;
|
||||||
|
}
|
||||||
|
75% {
|
||||||
|
right: -40px;
|
||||||
|
bottom: -40px;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
right: -40px;
|
||||||
|
bottom: -40px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@keyframes rectSize {
|
||||||
|
0% {
|
||||||
|
width: 0;
|
||||||
|
}
|
||||||
|
35% {
|
||||||
|
width: 300px;
|
||||||
|
}
|
||||||
|
60% {
|
||||||
|
width: 300px;
|
||||||
|
}
|
||||||
|
75% {
|
||||||
|
width: 0;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
width: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
div#fab {
|
||||||
|
background: var(--primary);
|
||||||
|
width: 200px;
|
||||||
|
height: 200px;
|
||||||
|
border-radius: 100px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 60px;
|
||||||
|
letter-spacing: 5px;
|
||||||
|
text-align: center;
|
||||||
|
color: var(--cta);
|
||||||
|
position: absolute;
|
||||||
|
right: 250px;
|
||||||
|
bottom: 250px;
|
||||||
|
animation: circleMove 2s linear 0s infinite alternate !important;
|
||||||
|
z-index: 99;
|
||||||
|
filter: drop-shadow(0px 0px 20px var(--primary));
|
||||||
|
}
|
||||||
|
|
||||||
|
div#title-card {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
div#sidebar {
|
||||||
|
width: 300px;
|
||||||
|
height: 120%;
|
||||||
|
right: 0;
|
||||||
|
position: absolute;
|
||||||
|
background: var(--cta);
|
||||||
|
top: -10%;
|
||||||
|
border-top-right-radius: 26px;
|
||||||
|
border-bottom-right-radius: 26px;
|
||||||
|
animation: rectSize 2s linear 0s infinite alternate !important;
|
||||||
|
box-shadow: -5px 0px 50px var(--primary-medium);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
T H R E A D
|
||||||
|
D E M O S
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ti * {
|
||||||
|
font-size: 14px !important;
|
||||||
|
font-family: "Glacial";
|
||||||
|
letter-spacing: 1.1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ti {
|
||||||
|
color: white;
|
||||||
|
width: fit-content;
|
||||||
|
margin: 10px 0;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
#tm {
|
||||||
|
width: 100%;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
#tm #tt {
|
||||||
|
height: 0;
|
||||||
|
overflow-y: visible;
|
||||||
|
font-size: 10px;
|
||||||
|
transition: all ease-in-out 0.3s;
|
||||||
|
/* transition-delay: 0.1s; */
|
||||||
|
white-space: nowrap;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
opacity: 0;
|
||||||
|
color: #9f9f9f;
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: row-reverse;
|
||||||
|
}
|
||||||
|
#tm #tt span {
|
||||||
|
flex: 1;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
#tm #tt #ri {
|
||||||
|
position: absolute;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
padding: 15px;
|
||||||
|
color: #c0f300;
|
||||||
|
font-size: 20px;
|
||||||
|
border-radius: 26px;
|
||||||
|
z-index: 99 !important;
|
||||||
|
left: 0;
|
||||||
|
cursor: pointer;
|
||||||
|
background-color: white;
|
||||||
|
background-image: url("https://www.materialui.co/materialIcons/content/reply_grey_192x192.png");
|
||||||
|
background-size: 75%;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center;
|
||||||
|
bottom: 0;
|
||||||
|
transition: all ease-in-out 0.3s;
|
||||||
|
/* transition-delay: 0.1s; */
|
||||||
|
}
|
||||||
|
#ti:hover #tm #tt {
|
||||||
|
height: 24px;
|
||||||
|
margin-bottom: 7px;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
#tm p {
|
||||||
|
max-width: 40%;
|
||||||
|
padding: 5px 15px;
|
||||||
|
background: #424242;
|
||||||
|
border-radius: 26px;
|
||||||
|
z-index: 99 !important;
|
||||||
|
transition: all ease-in-out 0.3s;
|
||||||
|
/* transition-delay: 0.1s; */
|
||||||
|
width: fit-content;
|
||||||
|
}
|
||||||
|
#tm img {
|
||||||
|
max-width: 40%;
|
||||||
|
border-radius: 26px;
|
||||||
|
transition: all ease-in-out 0.3s;
|
||||||
|
/* transition-delay: 0.1s; */
|
||||||
|
z-index: 99;
|
||||||
|
}
|
||||||
|
#ti:hover #tm p,
|
||||||
|
#ti:hover #tm img {
|
||||||
|
margin-left: 40px;
|
||||||
|
}
|
||||||
|
#tm #tt #ri:hover {
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
#tn {
|
||||||
|
font-size: 11px;
|
||||||
|
margin-top: 15px;
|
||||||
|
margin-bottom: 7px;
|
||||||
|
color: var(--primary-text);
|
||||||
|
}
|
||||||
|
#tr {
|
||||||
|
font-size: 11px;
|
||||||
|
margin-bottom: -20px;
|
||||||
|
padding: 7.5px 15px;
|
||||||
|
padding-bottom: 25px;
|
||||||
|
border-radius: 13px;
|
||||||
|
background: #222222;
|
||||||
|
width: fit-content;
|
||||||
|
max-width: 35%;
|
||||||
|
z-index: 99 !important;
|
||||||
|
transition: all ease-in-out 0.3s;
|
||||||
|
/* transition-delay: 0.1s; */
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
#tr img {
|
||||||
|
max-height: 50px;
|
||||||
|
border-radius: 26px;
|
||||||
|
transition: all ease-in-out 0.3s;
|
||||||
|
/* transition-delay: 0.1s; */
|
||||||
|
}
|
||||||
|
#ti:hover #tr {
|
||||||
|
margin-bottom: 0;
|
||||||
|
padding-bottom: 7.5px;
|
||||||
|
}
|
||||||
|
#tr:hover {
|
||||||
|
background: #111111;
|
||||||
|
}
|
||||||
|
#ti.mm {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-end;
|
||||||
|
}
|
||||||
|
#ti.mm #tn {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
#ti.mm #tm {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-end;
|
||||||
|
}
|
||||||
|
#ti.mm #tm p {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
#ti.mm #tm #tt {
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
#ti.mm #tm #tt #ri {
|
||||||
|
right: 0;
|
||||||
|
left: unset;
|
||||||
|
}
|
||||||
|
#ti.mm:hover #tm p,
|
||||||
|
#ti.mm:hover #tm img {
|
||||||
|
margin-left: 0;
|
||||||
|
margin-right: 40px;
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,6 +3,11 @@ Copyright (C) Ayushya Amitabh - All Rights Reserved
|
|||||||
Unauthorized copying of this file, via any medium is strictly prohibited
|
Unauthorized copying of this file, via any medium is strictly prohibited
|
||||||
Proprietary and confidential
|
Proprietary and confidential
|
||||||
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
||||||
|
https://www.chromewatchparty.com/copyright
|
||||||
|
=========================================================================
|
||||||
|
ALL CONTENT ON WATCH PARTY'S WEBSITE OR IN WATCH PARTY'S CHROME EXTENSION APP, UNLESS OTHERWISE
|
||||||
|
CITED ARE THE SOLE INTELECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE
|
||||||
|
COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
|
|
||||||
@import './variables.css';
|
@import './variables.css';
|
||||||
|
|||||||
@@ -3,6 +3,11 @@ Copyright (C) Ayushya Amitabh - All Rights Reserved
|
|||||||
Unauthorized copying of this file, via any medium is strictly prohibited
|
Unauthorized copying of this file, via any medium is strictly prohibited
|
||||||
Proprietary and confidential
|
Proprietary and confidential
|
||||||
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
||||||
|
https://www.chromewatchparty.com/copyright
|
||||||
|
=========================================================================
|
||||||
|
ALL CONTENT ON WATCH PARTY'S WEBSITE OR IN WATCH PARTY'S CHROME EXTENSION APP, UNLESS OTHERWISE
|
||||||
|
CITED ARE THE SOLE INTELECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE
|
||||||
|
COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
|
|
||||||
.features,
|
.features,
|
||||||
@@ -13,3 +18,41 @@ Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
|||||||
.landing video {
|
.landing video {
|
||||||
max-width: 45%;
|
max-width: 45%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.home .pop-features {
|
||||||
|
margin-bottom: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pop-feature {
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pop-feature {
|
||||||
|
margin: 100px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pop-feature > * {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pop-feature .explanation {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pop-feature .explanation div {
|
||||||
|
margin-left: 0;
|
||||||
|
padding: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pop-feature.alternate {
|
||||||
|
flex-direction: row-reverse;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pop-feature.alternate .explanation {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pop-feature.pop-feature.alternate .explanation div {
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,6 +3,11 @@ Copyright (C) Ayushya Amitabh - All Rights Reserved
|
|||||||
Unauthorized copying of this file, via any medium is strictly prohibited
|
Unauthorized copying of this file, via any medium is strictly prohibited
|
||||||
Proprietary and confidential
|
Proprietary and confidential
|
||||||
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
||||||
|
https://www.chromewatchparty.com/copyright
|
||||||
|
=========================================================================
|
||||||
|
ALL CONTENT ON WATCH PARTY'S WEBSITE OR IN WATCH PARTY'S CHROME EXTENSION APP, UNLESS OTHERWISE
|
||||||
|
CITED ARE THE SOLE INTELECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE
|
||||||
|
COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
|
|
||||||
html {
|
html {
|
||||||
@@ -31,7 +36,7 @@ body {
|
|||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
.link-button::before {
|
.link-button::before {
|
||||||
content: '';
|
content: "";
|
||||||
height: 100%;
|
height: 100%;
|
||||||
top: 0;
|
top: 0;
|
||||||
width: 0;
|
width: 0;
|
||||||
@@ -61,13 +66,16 @@ body {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
left: 0;
|
left: 0;
|
||||||
top: 0;
|
top: 0;
|
||||||
|
opacity: 1;
|
||||||
padding: 3rem 10rem;
|
padding: 3rem 10rem;
|
||||||
|
height: auto;
|
||||||
z-index: 999 !important;
|
z-index: 999 !important;
|
||||||
}
|
}
|
||||||
.landing .link-button.stickied {
|
.landing .link-button.stickied {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
right: 0rem;
|
right: 0rem;
|
||||||
top: 0;
|
top: 0;
|
||||||
|
opacity: 1;
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
font-size: 2rem;
|
font-size: 2rem;
|
||||||
z-index: 1999 !important;
|
z-index: 1999 !important;
|
||||||
@@ -111,21 +119,7 @@ body {
|
|||||||
transition: all 0.3s ease-in;
|
transition: all 0.3s ease-in;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
.feature-icon {
|
|
||||||
z-index: 1;
|
|
||||||
background-position: center !important;
|
|
||||||
transition: all ease-out 0.3s;
|
|
||||||
border-radius: 100%;
|
|
||||||
width: 0;
|
|
||||||
margin: 0 auto;
|
|
||||||
height: 0;
|
|
||||||
background-size: cover !important;
|
|
||||||
padding: 5rem;
|
|
||||||
background-color: black;
|
|
||||||
position: absolute;
|
|
||||||
top: 13rem;
|
|
||||||
left: 13rem;
|
|
||||||
}
|
|
||||||
.feature-card .feature-text {
|
.feature-card .feature-text {
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
display: table;
|
display: table;
|
||||||
@@ -145,13 +139,19 @@ body {
|
|||||||
color: var(--primary-light);
|
color: var(--primary-light);
|
||||||
line-height: initial;
|
line-height: initial;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
|
margin-top: -1.75rem;
|
||||||
}
|
}
|
||||||
.feature-card:hover .feature-icon {
|
|
||||||
position: relative;
|
.feature-icon {
|
||||||
top: -35%;
|
display: flex;
|
||||||
left: unset;
|
}
|
||||||
transform: scale(3);
|
|
||||||
margin-bottom: 3rem;
|
.feature-card .feature-icon video {
|
||||||
|
transform: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.feature-card:hover .feature-icon video {
|
||||||
|
transform: scale(3) translateY(-50%);
|
||||||
}
|
}
|
||||||
|
|
||||||
footer {
|
footer {
|
||||||
@@ -187,9 +187,10 @@ footer .link-button {
|
|||||||
|
|
||||||
.welcome .logo a::before,
|
.welcome .logo a::before,
|
||||||
.copyright .logo a::before {
|
.copyright .logo a::before {
|
||||||
content: '';
|
content: "";
|
||||||
height: 100%;
|
height: 100%;
|
||||||
top: 0;
|
top: -3px;
|
||||||
|
padding-top: 2px;
|
||||||
width: 0;
|
width: 0;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: -1rem;
|
left: -1rem;
|
||||||
@@ -218,7 +219,7 @@ footer .link-button {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.welcome .landing#tips .tip {
|
.welcome .landing#tips .tip {
|
||||||
padding-right: 0;
|
padding-right: 100px;
|
||||||
transition: all ease-out 0.3s;
|
transition: all ease-out 0.3s;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -231,7 +232,7 @@ footer .link-button {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.welcome .landing .supported-logo::before {
|
.welcome .landing .supported-logo::before {
|
||||||
content: 'START WATCHING';
|
content: "START WATCHING";
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
@@ -242,7 +243,7 @@ footer .link-button {
|
|||||||
font-size: 1.5rem;
|
font-size: 1.5rem;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
color: var(--primary);
|
color: var(--primary);
|
||||||
font-family: 'GlacialBold';
|
font-family: "GlacialBold";
|
||||||
background-color: var(--cta);
|
background-color: var(--cta);
|
||||||
padding: 1rem 0;
|
padding: 1rem 0;
|
||||||
}
|
}
|
||||||
@@ -265,7 +266,7 @@ footer .link-button {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.welcome .landing#tips .tip h6 {
|
.welcome .landing#tips .tip h6 {
|
||||||
color: var(--primary-light);
|
color: var(--primary-medium);
|
||||||
transition: all ease-out 0.3s;
|
transition: all ease-out 0.3s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,11 @@ Copyright (C) Ayushya Amitabh - All Rights Reserved
|
|||||||
Unauthorized copying of this file, via any medium is strictly prohibited
|
Unauthorized copying of this file, via any medium is strictly prohibited
|
||||||
Proprietary and confidential
|
Proprietary and confidential
|
||||||
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
||||||
|
https://www.chromewatchparty.com/copyright
|
||||||
|
=========================================================================
|
||||||
|
ALL CONTENT ON WATCH PARTY'S WEBSITE OR IN WATCH PARTY'S CHROME EXTENSION APP, UNLESS OTHERWISE
|
||||||
|
CITED ARE THE SOLE INTELECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE
|
||||||
|
COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
|
|
||||||
.welcome .landing video {
|
.welcome .landing video {
|
||||||
|
|||||||
@@ -3,12 +3,17 @@ Copyright (C) Ayushya Amitabh - All Rights Reserved
|
|||||||
Unauthorized copying of this file, via any medium is strictly prohibited
|
Unauthorized copying of this file, via any medium is strictly prohibited
|
||||||
Proprietary and confidential
|
Proprietary and confidential
|
||||||
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
||||||
|
https://www.chromewatchparty.com/copyright
|
||||||
|
=========================================================================
|
||||||
|
ALL CONTENT ON WATCH PARTY'S WEBSITE OR IN WATCH PARTY'S CHROME EXTENSION APP, UNLESS OTHERWISE
|
||||||
|
CITED ARE THE SOLE INTELECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE
|
||||||
|
COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
--primary: black;
|
--primary: black;
|
||||||
--primary-medium: #232323;
|
--primary-medium: #464646;
|
||||||
--primary-light: #454545;
|
--primary-light: #626262;
|
||||||
--cta: #c0f300;
|
--cta: #c0f300;
|
||||||
--primary-text: white;
|
--primary-text: white;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,11 @@ Copyright (C) Ayushya Amitabh - All Rights Reserved
|
|||||||
Unauthorized copying of this file, via any medium is strictly prohibited
|
Unauthorized copying of this file, via any medium is strictly prohibited
|
||||||
Proprietary and confidential
|
Proprietary and confidential
|
||||||
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
||||||
|
https://www.chromewatchparty.com/copyright
|
||||||
|
=========================================================================
|
||||||
|
ALL CONTENT ON WATCH PARTY'S WEBSITE OR IN WATCH PARTY'S CHROME EXTENSION APP, UNLESS OTHERWISE
|
||||||
|
CITED ARE THE SOLE INTELECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE
|
||||||
|
COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
@@ -14,48 +19,32 @@ Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
|||||||
font-size: 10px;
|
font-size: 10px;
|
||||||
}
|
}
|
||||||
.supported-logo#netflix {
|
.supported-logo#netflix {
|
||||||
background-image: url('../media/logos/Netflix.png');
|
background-image: url("../media/logos/Netflix.png");
|
||||||
}
|
}
|
||||||
.supported-logo#hulu {
|
.supported-logo#hulu {
|
||||||
background-image: url('../media/logos/Hulu.png');
|
background-image: url("../media/logos/Hulu.png");
|
||||||
}
|
}
|
||||||
.supported-logo#disney {
|
.supported-logo#disney {
|
||||||
background-image: url('../media/logos/DisneyColor.png');
|
background-image: url("../media/logos/DisneyColor.png");
|
||||||
}
|
}
|
||||||
.supported-logo#prime {
|
.supported-logo#prime {
|
||||||
background-image: url('../media/logos/PrimeColor.png');
|
background-image: url("../media/logos/PrimeColor.png");
|
||||||
}
|
}
|
||||||
.supported-logo#youtube {
|
.supported-logo#youtube {
|
||||||
background-image: url('../media/logos/YoutubeColor.png');
|
background-image: url("../media/logos/YoutubeColor.png");
|
||||||
}
|
}
|
||||||
.supported-logo#hbonow {
|
.supported-logo#hbonow {
|
||||||
background-image: url('../media/logos/HBONowBlack.png');
|
background-image: url("../media/logos/HBONowBlack.png");
|
||||||
}
|
}
|
||||||
.supported-logo#hbomax {
|
.supported-logo#hbomax {
|
||||||
background-image: url('../media/logos/HBOMax.png');
|
background-image: url("../media/logos/HBOMax.png");
|
||||||
}
|
}
|
||||||
.supported-logo#peacock {
|
.supported-logo#peacock {
|
||||||
background-image: url('../media/logos/PeacockColor.png');
|
background-image: url("../media/logos/PeacockColor.png");
|
||||||
}
|
}
|
||||||
|
.supported-logo#googleplay {
|
||||||
.feature-icon#phone {
|
background-image: url("../media/logos/GooglePlay.png");
|
||||||
background-image: url('../media/features/Phone.gif');
|
|
||||||
}
|
}
|
||||||
.feature-icon#delete {
|
.supported-logo#crunchyroll {
|
||||||
background-image: url('../media/features/Delete.gif');
|
background-image: url("../media/logos/Crunchyroll.png");
|
||||||
}
|
|
||||||
.feature-icon#signup {
|
|
||||||
background-image: url('../media/features/Signup.gif');
|
|
||||||
}
|
|
||||||
.feature-icon#sync {
|
|
||||||
background-image: url('../media/features/Sync.gif');
|
|
||||||
}
|
|
||||||
.feature-icon#custom {
|
|
||||||
background-image: url('../media/features/Custom.gif');
|
|
||||||
}
|
|
||||||
.feature-icon#chat {
|
|
||||||
background-image: url('../media/features/Chat.gif');
|
|
||||||
}
|
|
||||||
.feature-icon#hideable {
|
|
||||||
background-image: url('../media/features/Hideable.gif');
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,18 +4,11 @@ Copyright (C) Ayushya Amitabh - All Rights Reserved
|
|||||||
Unauthorized copying of this file, via any medium is strictly prohibited
|
Unauthorized copying of this file, via any medium is strictly prohibited
|
||||||
Proprietary and confidential
|
Proprietary and confidential
|
||||||
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
Written by Ayushya Amitabh <admin@chromewatchparty.com>, 2020
|
||||||
|
https://www.chromewatchparty.com/copyright
|
||||||
=========================================================================
|
=========================================================================
|
||||||
ALL CONTENT ON THIS WEBSITE, UNLESS OTHERWISE CITED ARE THE SOLE
|
ALL CONTENT ON WATCH PARTY'S WEBSITE OR IN WATCH PARTY'S CHROME EXTENSION APP, UNLESS OTHERWISE
|
||||||
INTELECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE COPIED, EDITED,
|
CITED ARE THE SOLE INTELECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE
|
||||||
OR REPRODUCED WITHOUT PERMISSION.
|
COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
|
||||||
|
|
||||||
Netflix logo is a trademark and intellectual property of Netflix, Inc.
|
|
||||||
Disney+ logo is a trademark and intellectual property of The Walt Disney Company
|
|
||||||
Prime logo is a trademark and intellectual property of Amazon.com, Inc.
|
|
||||||
YouTube logo is a trademark and intellectual property of Google, Inc.
|
|
||||||
Hulu logo is a trademark and intellectual property of Hulu, LLC.
|
|
||||||
HBO Now and HBO Max logos are trademark and intellectual property of WarnerMedia Direct,LLC.
|
|
||||||
Peacock TV logo is a trademark and intellectual property of Peacock TV & NBC Universal.
|
|
||||||
------------------------------------------------------------------------->
|
------------------------------------------------------------------------->
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
@@ -40,18 +33,26 @@ Peacock TV logo is a trademark and intellectual property of Peacock TV & NBC Uni
|
|||||||
<script src="../scripts/Stickied.js"></script>
|
<script src="../scripts/Stickied.js"></script>
|
||||||
<title>Watch Party | Welcome</title>
|
<title>Watch Party | Welcome</title>
|
||||||
</head>
|
</head>
|
||||||
|
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||||||
|
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-87498806-2">
|
||||||
|
</script>
|
||||||
|
<script>
|
||||||
|
window.dataLayer = window.dataLayer || [];
|
||||||
|
function gtag(){dataLayer.push(arguments);}
|
||||||
|
gtag('js', new Date());
|
||||||
|
|
||||||
|
gtag('config', 'UA-87498806-2');
|
||||||
|
</script>
|
||||||
<body class="welcome">
|
<body class="welcome">
|
||||||
<div class="landing">
|
<div class="landing">
|
||||||
<div class="logo-circle"></div>
|
<div class="logo-circle"></div>
|
||||||
<div class="logo-circle"></div>
|
<div class="logo-circle"></div>
|
||||||
<div class="logo-circle"></div>
|
<div class="logo-circle"></div>
|
||||||
|
<h1 data-font="serif" class="logo duplicate"><a href="../">WATCH PARTY</a></h1>
|
||||||
<h1 data-font="serif" class="logo"><a href="../">WATCH PARTY</a></h1>
|
<h1 data-font="serif" class="logo"><a href="../">WATCH PARTY</a></h1>
|
||||||
<h5 data-font="sans" class="logo-tag">
|
<h5 data-font="sans" class="logo-tag">
|
||||||
WELCOME TO WATCH PARTY
|
WELCOME TO WATCH PARTY
|
||||||
</h5>
|
</h5>
|
||||||
<p data-font="sans-bold" class="title subtitle">Watch Party lives in the bottom right corner of your screen. <br /> It's there when you need it and hidden when you don't.</p>
|
|
||||||
<video src="../media/features/Tutorial.mp4" autoplay muted loop> </video>
|
|
||||||
<a data-font="sans-bold" href="../changes/" class="link-button">See What's New</a>
|
|
||||||
<p data-font="sans-bold" class="title subtitle">
|
<p data-font="sans-bold" class="title subtitle">
|
||||||
WATCH TOGETHER ON
|
WATCH TOGETHER ON
|
||||||
</p>
|
</p>
|
||||||
@@ -63,14 +64,162 @@ Peacock TV logo is a trademark and intellectual property of Peacock TV & NBC Uni
|
|||||||
<a href="https://www.youtube.com"><div class="supported-logo" id="youtube"></div></a>
|
<a href="https://www.youtube.com"><div class="supported-logo" id="youtube"></div></a>
|
||||||
<a href="https://play.hbonow.com"><div class="supported-logo" id="hbonow"></div></a>
|
<a href="https://play.hbonow.com"><div class="supported-logo" id="hbonow"></div></a>
|
||||||
<a href="https://play.hbomax.com"><div class="supported-logo" id="hbomax"></div></a>
|
<a href="https://play.hbomax.com"><div class="supported-logo" id="hbomax"></div></a>
|
||||||
<a href="https://www.peacocktv.com"><div class="supported-logo" id="peacock"></div></div></a>
|
<a href="https://www.peacocktv.com"><div class="supported-logo" id="peacock"></div></a>
|
||||||
|
<a href="https://play.google.com/movies"><div class="supported-logo" id="googleplay"></div></a>
|
||||||
|
<a href="https://www.crunchyroll.com"><div class="supported-logo" id="crunchyroll"></div></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="getting-started" class="pop-features">
|
||||||
|
<p data-font="sans-bold" class="title">
|
||||||
|
GETTING STARTED
|
||||||
|
</p>
|
||||||
|
<div class="pop-feature">
|
||||||
|
<div id="title-card-container">
|
||||||
|
<div id="title-card">
|
||||||
|
<div data-font="serif" id="fab">WP</div>
|
||||||
|
<div id="sidebar"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="explanation">
|
||||||
|
<div>
|
||||||
|
<h4 data-font="sans-bold">TO BE OR NOT TO BE</h4>
|
||||||
|
<p data-font="sans">Watch Party is built to not be in your way. There when you need it, gone when you don't. The sidebar is now resizeable, and now supports having access to Watch Party in fullscreen. (Use the fullscreen button in the sidebar)</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="pop-feature alternate">
|
||||||
|
<div id="title-card-container">
|
||||||
|
<div id="title-card">
|
||||||
|
<h5 data-font="sans-bold" id="title-card-title">WATCH PARTY</h5>
|
||||||
|
<h3 data-font="sans" id="title-card-subtitle">YOUR PARTY NAME</h3>
|
||||||
|
<p data-font="sans" id="control-notification">
|
||||||
|
Allow chat notification when side panel is closed
|
||||||
|
<span>Notifications show up when the side bar is hidden</span>
|
||||||
|
</p>
|
||||||
|
<p data-font="sans" id="control-autorejoin">
|
||||||
|
Allow Watch Party to auto rejoin
|
||||||
|
<span>Automatically rejoin party if you return to the page within 1 minute</span>
|
||||||
|
</p>
|
||||||
|
<p data-font="sans" id="control-admin">
|
||||||
|
Enable admin only mode
|
||||||
|
<span>Only party admin can sync player and start calls</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="explanation">
|
||||||
|
<div>
|
||||||
|
<h4 data-font="sans-bold">Stay in control</h4>
|
||||||
|
<p data-font="sans">Find your settings by clicking on title card (when you're in a party) or in the settings panel (when you're creating or joining) </p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="pop-feature">
|
||||||
|
<div id="title-card-container">
|
||||||
|
<div id="title-card">
|
||||||
|
<h5 data-font="sans-bold" id="system-message">Ayushya started the party.</h5>
|
||||||
|
|
||||||
|
<div id="ti">
|
||||||
|
<div id="tn">SOMEONE</div>
|
||||||
|
<div id="tm">
|
||||||
|
<div id="tt">
|
||||||
|
<span>12:00:00 PM</span>
|
||||||
|
<div id="ri"></div></div>
|
||||||
|
<p>Hiya buddy!</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="ti" class="mm">
|
||||||
|
<div id="tn">AYUSHYA</div>
|
||||||
|
<div id="tr">Hiya buddy!
|
||||||
|
</div>
|
||||||
|
<div id="tm">
|
||||||
|
<div id="tt">
|
||||||
|
<span>12:00:00 PM</span>
|
||||||
|
<div id="ri"></div></div>
|
||||||
|
<p>OH GOD NO! PLEASE GOD NO! NO!</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="ti">
|
||||||
|
<div id="tn">SOMEONE</div>
|
||||||
|
<div id="tm">
|
||||||
|
<div id="tt">
|
||||||
|
<span>12:00:00 PM</span>
|
||||||
|
<div id="ri"></div>
|
||||||
|
</div>
|
||||||
|
<img src="https://media.giphy.com/media/d10dMmzqCYqQ0/giphy.gif" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="ti" class="mm">
|
||||||
|
<div id="tn">SOMEONE</div>
|
||||||
|
<div id="tr">
|
||||||
|
<img src="https://media.giphy.com/media/d10dMmzqCYqQ0/giphy.gif" /></div>
|
||||||
|
<div id="tm">
|
||||||
|
<div id="tt">
|
||||||
|
<span>12:00:00 PM</span>
|
||||||
|
<div id="ri"></div>
|
||||||
|
</div>
|
||||||
|
<p>Let's watch The Office</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="explanation">
|
||||||
|
<div>
|
||||||
|
<h4 data-font="sans-bold">FULL FEATURED CHAT</h4>
|
||||||
|
<p data-font="sans">A brand new, completely revamped chat user interface, now has replies, shows pending messages, and improves the Giphy GIF picker</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="pop-feature alternate">
|
||||||
|
|
||||||
|
<div id="title-card-container">
|
||||||
|
<div id="title-card">
|
||||||
|
<h5 data-font="sans-bold" id="title-card-title">WATCH PARTY</h5>
|
||||||
|
<h3 data-font="sans" id="title-card-subtitle">ANIME WATCH PARTY</h3>
|
||||||
|
<h6 data-font="sans" id="title-card-tagline">USERS IN PARTY</h6>
|
||||||
|
<p data-font="sans" id="call-user-chip">Ayushya</p>
|
||||||
|
<p data-font="sans" id="call-user-chip">Someone</p>
|
||||||
|
<p data-font="sans" id="call-user-chip">Third Party</p>
|
||||||
|
<p data-font="sans" id="call-user-chip">Won't Stop Talking</p>
|
||||||
|
<h6 data-font="sans" id="title-card-tagline">USERS ON CALL</h6>
|
||||||
|
<p data-font="sans" id="call-user-chip">Ayushya</p>
|
||||||
|
<p data-font="sans" id="call-user-chip" class="not-me-user-chip">Someone</p>
|
||||||
|
<p data-font="sans" id="call-user-chip" class="not-me-user-chip">Won't Stop Talking <input type="range" value="2" min="0" max="10"></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="explanation">
|
||||||
|
<div>
|
||||||
|
<h4 data-font="sans-bold">MADE FOR YOU & YOUR GANG</h4>
|
||||||
|
<p data-font="sans">See who's in your party, get on a call with your party, and volume control for the person who just won't stop talking. </p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
<div id="tips" class="landing">
|
<div id="tips" class="landing">
|
||||||
<p data-font="sans-bold" class="title">
|
<p data-font="sans-bold" class="title">
|
||||||
TIPS & FAQ
|
TIPS & FAQ
|
||||||
</p>
|
</p>
|
||||||
|
<div class="tip">
|
||||||
|
<h6 data-font="sans">
|
||||||
|
DO I STILL NEED ACCOUNTS FOR THE STREAMING PLATFORMS
|
||||||
|
</h6>
|
||||||
|
<p data-font="sans-bold">
|
||||||
|
Yes, Watch Party is not a hack. The sole purpose of Watch Party is to help synchronize the playing/pausing on streamed content.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="tip">
|
||||||
|
<h6 data-font="sans">
|
||||||
|
HOW CAN I HELP KEEP WATCH PARTY ALIVE
|
||||||
|
</h6>
|
||||||
|
<p data-font="sans-bold">
|
||||||
|
Watch Party is built to be completely free, all the costs are paid by the developer alone. While no payment is needed, any small donation helps make sure I can keep the servers up and running. You can request more details by reaching out to admin@chromewatchparty.com.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
<div class="tip">
|
<div class="tip">
|
||||||
<h6 data-font="sans">
|
<h6 data-font="sans">
|
||||||
CAN I USE WATCH PARTY IN FULLSCREEN
|
CAN I USE WATCH PARTY IN FULLSCREEN
|
||||||
@@ -87,14 +236,6 @@ Peacock TV logo is a trademark and intellectual property of Peacock TV & NBC Uni
|
|||||||
If you started the party, you can simply join the party from a different place to change the party location.
|
If you started the party, you can simply join the party from a different place to change the party location.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="tip">
|
|
||||||
<h6 data-font="sans">
|
|
||||||
I CAN'T START A CALL
|
|
||||||
</h6>
|
|
||||||
<p data-font="sans-bold">
|
|
||||||
A group call can only be started by the person who started the party - after that the rest of the party can join.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div class="tip">
|
<div class="tip">
|
||||||
<h6 data-font="sans">
|
<h6 data-font="sans">
|
||||||
CHAT NOTIFICATIONS ARE ANNOYING
|
CHAT NOTIFICATIONS ARE ANNOYING
|
||||||
@@ -124,7 +265,7 @@ Peacock TV logo is a trademark and intellectual property of Peacock TV & NBC Uni
|
|||||||
CAN I DISABLE WATCH PARTY TEMPORARILY
|
CAN I DISABLE WATCH PARTY TEMPORARILY
|
||||||
</h6>
|
</h6>
|
||||||
<p data-font="sans-bold">
|
<p data-font="sans-bold">
|
||||||
Watch Party is built to not be in your way but, it can be manually disabled by going to the Chrome Extensions page (chrome://extensions).</a>
|
Watch Party is built to not be in your way but, it can be manually disabled by going to the Chrome Extensions page (chrome://extensions).
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<a data-font="sans-bold" href="mailto:admin@chromewatchparty.com?subject=New FAQ Question" class="link-button">
|
<a data-font="sans-bold" href="mailto:admin@chromewatchparty.com?subject=New FAQ Question" class="link-button">
|
||||||
|
|||||||