diff --git a/.prettierrc b/.prettierrc
index 4722d95280..544138be45 100644
--- a/.prettierrc
+++ b/.prettierrc
@@ -1,8 +1,3 @@
{
- "endOfLine": "lf",
- "semi": true,
- "trailingComma": "es5",
- "useTabs": false,
- "tabWidth": 2,
"singleQuote": true
}
diff --git a/dev/promises.js b/dev/promises.js
index cb5269c21f..483b718dfb 100644
--- a/dev/promises.js
+++ b/dev/promises.js
@@ -8,7 +8,7 @@ async function test() {
await new Promise((resolve) => setTimeout(resolve, el * 1000));
console.log('[m]', start);
resolve(el);
- })
+ }),
);
const result = await Promise.allSettled(arrPromises);
console.log('[e]', start, result);
diff --git a/dev/renamer.js b/dev/renamer.js
index 6bc5ad63a0..b2cf4cf93a 100644
--- a/dev/renamer.js
+++ b/dev/renamer.js
@@ -15,7 +15,7 @@ async function init() {
console.log(vids);
vids.forEach((vid) => {
const match = subs.find((sub) =>
- vid.toLowerCase().startsWith(sub.slice(0, -4).toLowerCase())
+ vid.toLowerCase().startsWith(sub.slice(0, -4).toLowerCase()),
);
console.log(vid, match);
if (vid && match) {
diff --git a/index.html b/index.html
index 80af4aeb5a..ef9fc0d0f7 100644
--- a/index.html
+++ b/index.html
@@ -1,4 +1,4 @@
-
+
diff --git a/package-lock.json b/package-lock.json
index 6afb5a8a2c..2ca8db5dd5 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -18,7 +18,7 @@
"compression": "^1.7.4",
"cors": "^2.8.5",
"discord.js": "^14.14.1",
- "dotenv": "^16.3.1",
+ "dotenv": "^16.3.2",
"eventemitter3": "^4.0.7",
"express": "^4.18.2",
"fast-xml-parser": "^4.3.3",
@@ -29,7 +29,7 @@
"mediasoup-client": "^3.7.2",
"node-ssh": "^13.1.0",
"pg": "^8.11.3",
- "pm2": "^5.3.0",
+ "pm2": "^5.3.1",
"react": "^18.2.0",
"react-colorful": "^5.6.1",
"react-dom": "^18.2.0",
@@ -57,7 +57,7 @@
"@types/cors": "^2.8.17",
"@types/emoji-mart": "^3.0.14",
"@types/express": "^4.17.21",
- "@types/node": "^18.19.7",
+ "@types/node": "^20.11.5",
"@types/pg": "^8.10.9",
"@types/react": "^18.2.48",
"@types/react-dom": "^18.2.18",
@@ -71,11 +71,11 @@
"@types/youtube": "^0.0.50",
"husky": "^4.3.8",
"lint-staged": "^13.3.0",
- "prettier": "^2.8.8",
+ "prettier": "^3.2.4",
"source-map-explorer": "^2.5.3",
"ts-node-dev": "^2.0.0",
"typescript": "^5.3.3",
- "vite": "^5.0.11"
+ "vite": "^5.0.12"
}
},
"node_modules/@babel/code-frame": {
@@ -1839,14 +1839,14 @@
"integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ=="
},
"node_modules/@pm2/js-api": {
- "version": "0.6.7",
- "resolved": "https://registry.npmjs.org/@pm2/js-api/-/js-api-0.6.7.tgz",
- "integrity": "sha512-jiJUhbdsK+5C4zhPZNnyA3wRI01dEc6a2GhcQ9qI38DyIk+S+C8iC3fGjcjUbt/viLYKPjlAaE+hcT2/JMQPXw==",
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/@pm2/js-api/-/js-api-0.8.0.tgz",
+ "integrity": "sha512-nmWzrA/BQZik3VBz+npRcNIu01kdBhWL0mxKmP1ciF/gTcujPTQqt027N9fc1pK9ERM8RipFhymw7RcmCyOEYA==",
"dependencies": {
"async": "^2.6.3",
- "axios": "^0.21.0",
"debug": "~4.3.1",
"eventemitter2": "^6.3.1",
+ "extrareqp2": "^1.0.0",
"ws": "^7.0.0"
},
"engines": {
@@ -1861,14 +1861,6 @@
"lodash": "^4.17.14"
}
},
- "node_modules/@pm2/js-api/node_modules/axios": {
- "version": "0.21.4",
- "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz",
- "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==",
- "dependencies": {
- "follow-redirects": "^1.14.0"
- }
- },
"node_modules/@pm2/js-api/node_modules/debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
@@ -2623,9 +2615,9 @@
"integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g=="
},
"node_modules/@types/node": {
- "version": "18.19.7",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.7.tgz",
- "integrity": "sha512-IGRJfoNX10N/PfrReRZ1br/7SQ+2vF/tK3KXNwzXz82D32z5dMQEoOlFew18nLSN+vMNcLY4GrKfzwi/yWI8/w==",
+ "version": "20.11.5",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.5.tgz",
+ "integrity": "sha512-g557vgQjUUfN76MZAN/dt1z3dzcUsimuysco0KeluHgrPdJXkP/XdAURgyO2W9fZWHRtRBiVKzKn8vyOAwlG+w==",
"dependencies": {
"undici-types": "~5.26.4"
}
@@ -2810,6 +2802,14 @@
"@types/node": "*"
}
},
+ "node_modules/@types/ssh2/node_modules/@types/node": {
+ "version": "18.19.8",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.8.tgz",
+ "integrity": "sha512-g1pZtPhsvGVTwmeVoexWZLTQaOvXwoSq//pTL0DHeNzUDrFnir4fgETdhjhIxjVnN+hKOuh98+E1eMLnUXstFg==",
+ "dependencies": {
+ "undici-types": "~5.26.4"
+ }
+ },
"node_modules/@types/strip-bom": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@types/strip-bom/-/strip-bom-3.0.0.tgz",
@@ -4698,9 +4698,9 @@
}
},
"node_modules/dotenv": {
- "version": "16.3.1",
- "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz",
- "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==",
+ "version": "16.3.2",
+ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.2.tgz",
+ "integrity": "sha512-HTlk5nmhkm8F6JcdXvHIzaorzCoziNQT9mGxLPVXW8wJF1TiGSL60ZGB4gHWabHOaMmWmhvk2/lPHfnBiT78AQ==",
"engines": {
"node": ">=12"
},
@@ -5289,6 +5289,14 @@
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
},
+ "node_modules/extrareqp2": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/extrareqp2/-/extrareqp2-1.0.0.tgz",
+ "integrity": "sha512-Gum0g1QYb6wpPJCVypWP3bbIuaibcFiJcpuPM10YSXp/tzqi84x9PJageob+eN4xVRIOto4wjSGNLyMD54D2xA==",
+ "dependencies": {
+ "follow-redirects": "^1.14.0"
+ }
+ },
"node_modules/fake-mediastreamtrack": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/fake-mediastreamtrack/-/fake-mediastreamtrack-1.2.0.tgz",
@@ -9182,13 +9190,13 @@
}
},
"node_modules/pm2": {
- "version": "5.3.0",
- "resolved": "https://registry.npmjs.org/pm2/-/pm2-5.3.0.tgz",
- "integrity": "sha512-xscmQiAAf6ArVmKhjKTeeN8+Td7ZKnuZFFPw1DGkdFPR/0Iyx+m+1+OpCdf9+HQopX3VPc9/wqPQHqVOfHum9w==",
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/pm2/-/pm2-5.3.1.tgz",
+ "integrity": "sha512-DLVQHpSR1EegaTaRH3KbRXxpPVaqYwAp3uHSCtCsS++LSErvk07WSxuUnntFblBRqNU/w2KQyqs12mSq5wurkg==",
"dependencies": {
"@pm2/agent": "~2.0.0",
"@pm2/io": "~5.0.0",
- "@pm2/js-api": "~0.6.7",
+ "@pm2/js-api": "~0.8.0",
"@pm2/pm2-version-check": "latest",
"async": "~3.2.0",
"blessed": "0.1.81",
@@ -9505,15 +9513,15 @@
}
},
"node_modules/prettier": {
- "version": "2.8.8",
- "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz",
- "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==",
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.4.tgz",
+ "integrity": "sha512-FWu1oLHKCrtpO1ypU6J0SbK2d9Ckwysq6bHj/uaCP26DxrPpppCLQRGVuqAxSTvhF00AcvDRyYrLNW7ocBhFFQ==",
"dev": true,
"bin": {
- "prettier": "bin-prettier.js"
+ "prettier": "bin/prettier.cjs"
},
"engines": {
- "node": ">=10.13.0"
+ "node": ">=14"
},
"funding": {
"url": "https://github.com/prettier/prettier?sponsor=1"
@@ -12214,9 +12222,9 @@
}
},
"node_modules/vite": {
- "version": "5.0.11",
- "resolved": "https://registry.npmjs.org/vite/-/vite-5.0.11.tgz",
- "integrity": "sha512-XBMnDjZcNAw/G1gEiskiM1v6yzM4GE5aMGvhWTlHAYYhxb7S3/V1s3m2LDHa8Vh6yIWYYB0iJwsEaS523c4oYA==",
+ "version": "5.0.12",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-5.0.12.tgz",
+ "integrity": "sha512-4hsnEkG3q0N4Tzf1+t6NdN9dg/L3BM+q8SWgbSPnJvrgH2kgdyzfVJwbR1ic69/4uMJJ/3dqDZZE5/WwqW8U1w==",
"dev": true,
"dependencies": {
"esbuild": "^0.19.3",
@@ -13976,14 +13984,14 @@
}
},
"@pm2/js-api": {
- "version": "0.6.7",
- "resolved": "https://registry.npmjs.org/@pm2/js-api/-/js-api-0.6.7.tgz",
- "integrity": "sha512-jiJUhbdsK+5C4zhPZNnyA3wRI01dEc6a2GhcQ9qI38DyIk+S+C8iC3fGjcjUbt/viLYKPjlAaE+hcT2/JMQPXw==",
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/@pm2/js-api/-/js-api-0.8.0.tgz",
+ "integrity": "sha512-nmWzrA/BQZik3VBz+npRcNIu01kdBhWL0mxKmP1ciF/gTcujPTQqt027N9fc1pK9ERM8RipFhymw7RcmCyOEYA==",
"requires": {
"async": "^2.6.3",
- "axios": "^0.21.0",
"debug": "~4.3.1",
"eventemitter2": "^6.3.1",
+ "extrareqp2": "^1.0.0",
"ws": "^7.0.0"
},
"dependencies": {
@@ -13995,14 +14003,6 @@
"lodash": "^4.17.14"
}
},
- "axios": {
- "version": "0.21.4",
- "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz",
- "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==",
- "requires": {
- "follow-redirects": "^1.14.0"
- }
- },
"debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
@@ -14615,9 +14615,9 @@
"integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g=="
},
"@types/node": {
- "version": "18.19.7",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.7.tgz",
- "integrity": "sha512-IGRJfoNX10N/PfrReRZ1br/7SQ+2vF/tK3KXNwzXz82D32z5dMQEoOlFew18nLSN+vMNcLY4GrKfzwi/yWI8/w==",
+ "version": "20.11.5",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.5.tgz",
+ "integrity": "sha512-g557vgQjUUfN76MZAN/dt1z3dzcUsimuysco0KeluHgrPdJXkP/XdAURgyO2W9fZWHRtRBiVKzKn8vyOAwlG+w==",
"requires": {
"undici-types": "~5.26.4"
}
@@ -14791,6 +14791,16 @@
"integrity": "sha512-7eH4ppQMFlzvn//zhwD54MWaITR1aSc1oFBye9vb76GZ2Y9PSFYdwVIwOlxRXWs5+1hifntXyt+8a6SUbOD7Hg==",
"requires": {
"@types/node": "^18.11.18"
+ },
+ "dependencies": {
+ "@types/node": {
+ "version": "18.19.8",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.8.tgz",
+ "integrity": "sha512-g1pZtPhsvGVTwmeVoexWZLTQaOvXwoSq//pTL0DHeNzUDrFnir4fgETdhjhIxjVnN+hKOuh98+E1eMLnUXstFg==",
+ "requires": {
+ "undici-types": "~5.26.4"
+ }
+ }
}
},
"@types/ssh2-streams": {
@@ -16128,9 +16138,9 @@
}
},
"dotenv": {
- "version": "16.3.1",
- "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz",
- "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ=="
+ "version": "16.3.2",
+ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.2.tgz",
+ "integrity": "sha512-HTlk5nmhkm8F6JcdXvHIzaorzCoziNQT9mGxLPVXW8wJF1TiGSL60ZGB4gHWabHOaMmWmhvk2/lPHfnBiT78AQ=="
},
"duplexer": {
"version": "0.1.2",
@@ -16558,6 +16568,14 @@
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
},
+ "extrareqp2": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/extrareqp2/-/extrareqp2-1.0.0.tgz",
+ "integrity": "sha512-Gum0g1QYb6wpPJCVypWP3bbIuaibcFiJcpuPM10YSXp/tzqi84x9PJageob+eN4xVRIOto4wjSGNLyMD54D2xA==",
+ "requires": {
+ "follow-redirects": "^1.14.0"
+ }
+ },
"fake-mediastreamtrack": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/fake-mediastreamtrack/-/fake-mediastreamtrack-1.2.0.tgz",
@@ -19284,13 +19302,13 @@
}
},
"pm2": {
- "version": "5.3.0",
- "resolved": "https://registry.npmjs.org/pm2/-/pm2-5.3.0.tgz",
- "integrity": "sha512-xscmQiAAf6ArVmKhjKTeeN8+Td7ZKnuZFFPw1DGkdFPR/0Iyx+m+1+OpCdf9+HQopX3VPc9/wqPQHqVOfHum9w==",
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/pm2/-/pm2-5.3.1.tgz",
+ "integrity": "sha512-DLVQHpSR1EegaTaRH3KbRXxpPVaqYwAp3uHSCtCsS++LSErvk07WSxuUnntFblBRqNU/w2KQyqs12mSq5wurkg==",
"requires": {
"@pm2/agent": "~2.0.0",
"@pm2/io": "~5.0.0",
- "@pm2/js-api": "~0.6.7",
+ "@pm2/js-api": "~0.8.0",
"@pm2/pm2-version-check": "latest",
"async": "~3.2.0",
"blessed": "0.1.81",
@@ -19511,9 +19529,9 @@
"optional": true
},
"prettier": {
- "version": "2.8.8",
- "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz",
- "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==",
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.4.tgz",
+ "integrity": "sha512-FWu1oLHKCrtpO1ypU6J0SbK2d9Ckwysq6bHj/uaCP26DxrPpppCLQRGVuqAxSTvhF00AcvDRyYrLNW7ocBhFFQ==",
"dev": true
},
"promptly": {
@@ -21458,9 +21476,9 @@
}
},
"vite": {
- "version": "5.0.11",
- "resolved": "https://registry.npmjs.org/vite/-/vite-5.0.11.tgz",
- "integrity": "sha512-XBMnDjZcNAw/G1gEiskiM1v6yzM4GE5aMGvhWTlHAYYhxb7S3/V1s3m2LDHa8Vh6yIWYYB0iJwsEaS523c4oYA==",
+ "version": "5.0.12",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-5.0.12.tgz",
+ "integrity": "sha512-4hsnEkG3q0N4Tzf1+t6NdN9dg/L3BM+q8SWgbSPnJvrgH2kgdyzfVJwbR1ic69/4uMJJ/3dqDZZE5/WwqW8U1w==",
"dev": true,
"requires": {
"esbuild": "^0.19.3",
diff --git a/package.json b/package.json
index 4ba322f6ec..c746dedd8e 100644
--- a/package.json
+++ b/package.json
@@ -13,7 +13,7 @@
"compression": "^1.7.4",
"cors": "^2.8.5",
"discord.js": "^14.14.1",
- "dotenv": "^16.3.1",
+ "dotenv": "^16.3.2",
"eventemitter3": "^4.0.7",
"express": "^4.18.2",
"fast-xml-parser": "^4.3.3",
@@ -24,7 +24,7 @@
"mediasoup-client": "^3.7.2",
"node-ssh": "^13.1.0",
"pg": "^8.11.3",
- "pm2": "^5.3.0",
+ "pm2": "^5.3.1",
"react": "^18.2.0",
"react-colorful": "^5.6.1",
"react-dom": "^18.2.0",
@@ -93,7 +93,7 @@
"@types/cors": "^2.8.17",
"@types/emoji-mart": "^3.0.14",
"@types/express": "^4.17.21",
- "@types/node": "^18.19.7",
+ "@types/node": "^20.11.5",
"@types/pg": "^8.10.9",
"@types/react": "^18.2.48",
"@types/react-dom": "^18.2.18",
@@ -107,10 +107,10 @@
"@types/youtube": "^0.0.50",
"husky": "^4.3.8",
"lint-staged": "^13.3.0",
- "prettier": "^2.8.8",
+ "prettier": "^3.2.4",
"source-map-explorer": "^2.5.3",
"ts-node-dev": "^2.0.0",
"typescript": "^5.3.3",
- "vite": "^5.0.11"
+ "vite": "^5.0.12"
}
}
diff --git a/public/sw.min.js b/public/sw.min.js
index 9a47ebe4b5..dbf462c636 100644
--- a/public/sw.min.js
+++ b/public/sw.min.js
@@ -11,67 +11,67 @@
? t.includes(self.registration.scope + 'webtorrent/keepalive/')
? new Response()
: t.includes(self.registration.scope + 'webtorrent/cancel/')
- ? new Response(
- new ReadableStream({
- cancel() {
- e = !0;
- },
- })
- )
- : (async function ({ request: s }) {
- const { url: t, method: n, headers: o, destination: a } = s,
- l = await clients.matchAll({
- type: 'window',
- includeUncontrolled: !0,
+ ? new Response(
+ new ReadableStream({
+ cancel() {
+ e = !0;
+ },
}),
- [r, i] = await new Promise((e) => {
- for (const s of l) {
- const l = new MessageChannel(),
- { port1: r, port2: i } = l;
- (r.onmessage = ({ data: s }) => {
- e([s, r]);
- }),
- s.postMessage(
- {
- url: t,
- method: n,
- headers: Object.fromEntries(o.entries()),
- scope: self.registration.scope,
- destination: a,
- type: 'webtorrent',
- },
- [i]
- );
- }
- });
- let c = null;
- const d = () => {
- i.postMessage(!1), clearTimeout(c), (i.onmessage = null);
- };
- return 'STREAM' !== r.body
- ? (d(), new Response(r.body, r))
- : new Response(
- new ReadableStream({
- pull: (s) =>
- new Promise((t) => {
- (i.onmessage = ({ data: e }) => {
- e ? s.enqueue(e) : (d(), s.close()), t();
+ )
+ : (async function ({ request: s }) {
+ const { url: t, method: n, headers: o, destination: a } = s,
+ l = await clients.matchAll({
+ type: 'window',
+ includeUncontrolled: !0,
+ }),
+ [r, i] = await new Promise((e) => {
+ for (const s of l) {
+ const l = new MessageChannel(),
+ { port1: r, port2: i } = l;
+ (r.onmessage = ({ data: s }) => {
+ e([s, r]);
+ }),
+ s.postMessage(
+ {
+ url: t,
+ method: n,
+ headers: Object.fromEntries(o.entries()),
+ scope: self.registration.scope,
+ destination: a,
+ type: 'webtorrent',
+ },
+ [i],
+ );
+ }
+ });
+ let c = null;
+ const d = () => {
+ i.postMessage(!1), clearTimeout(c), (i.onmessage = null);
+ };
+ return 'STREAM' !== r.body
+ ? (d(), new Response(r.body, r))
+ : new Response(
+ new ReadableStream({
+ pull: (s) =>
+ new Promise((t) => {
+ (i.onmessage = ({ data: e }) => {
+ e ? s.enqueue(e) : (d(), s.close()), t();
+ }),
+ e ||
+ (clearTimeout(c),
+ 'document' !== a &&
+ (c = setTimeout(() => {
+ d(), t();
+ }, 5e3))),
+ i.postMessage(!0);
}),
- e ||
- (clearTimeout(c),
- 'document' !== a &&
- (c = setTimeout(() => {
- d(), t();
- }, 5e3))),
- i.postMessage(!0);
- }),
- cancel() {
- d();
- },
- }),
- r
- );
- })(s)
+ cancel() {
+ d();
+ },
+ }),
+ r,
+ );
+ })(s)
: null;
})(s);
t && s.respondWith(t);
diff --git a/server/cleanup.ts b/server/cleanup.ts
index 85bc24e19d..09715fef07 100644
--- a/server/cleanup.ts
+++ b/server/cleanup.ts
@@ -9,7 +9,7 @@ async function cleanupPostgres() {
}
console.time('[CLEANUP]');
const result = await postgres?.query(
- `DELETE FROM room WHERE owner IS NULL AND ("lastUpdateTime" < NOW() - INTERVAL '1 day' OR "lastUpdateTime" IS NULL)`
+ `DELETE FROM room WHERE owner IS NULL AND ("lastUpdateTime" < NOW() - INTERVAL '1 day' OR "lastUpdateTime" IS NULL)`,
);
console.log(result.command, result.rowCount);
console.timeEnd('[CLEANUP]');
diff --git a/server/room.ts b/server/room.ts
index 368a305c1f..63d6d86dc8 100644
--- a/server/room.ts
+++ b/server/room.ts
@@ -74,7 +74,7 @@ export class Room {
constructor(
io: Server,
roomId: string,
- roomData?: string | null | undefined
+ roomData?: string | null | undefined,
) {
this.roomId = roomId;
this.io = io;
@@ -105,7 +105,7 @@ export class Room {
if (postgres) {
const result = await postgres.query(
`SELECT password, "isSubRoom" FROM room where "roomId" = $1`,
- [this.roomId]
+ [this.roomId],
);
const roomPassword = result.rows[0]?.password;
if (roomPassword && password !== roomPassword) {
@@ -148,28 +148,28 @@ export class Room {
socket.on('CMD:pause', () => this.pauseVideo(socket));
socket.on('CMD:seek', (data) => this.seekVideo(socket, data));
socket.on('CMD:playbackRate', (data) =>
- this.setPlaybackRate(socket, data)
+ this.setPlaybackRate(socket, data),
);
socket.on('CMD:loop', (data) => this.setLoop(socket, data));
socket.on('CMD:ts', (data) => this.setTimestamp(socket, data));
socket.on('CMD:chat', (data) => this.sendChatMessage(socket, data));
socket.on('CMD:addReaction', (data) => this.addReaction(socket, data));
socket.on('CMD:removeReaction', (data) =>
- this.removeReaction(socket, data)
+ this.removeReaction(socket, data),
);
socket.on('CMD:joinVideo', () => this.joinVideo(socket));
socket.on('CMD:leaveVideo', () => this.leaveVideo(socket));
socket.on('CMD:joinScreenShare', (data) =>
- this.joinScreenSharing(socket, data)
+ this.joinScreenSharing(socket, data),
);
socket.on('CMD:userMute', (data) => this.setUserMute(socket, data));
socket.on('CMD:leaveScreenShare', () => this.leaveScreenSharing(socket));
socket.on('CMD:startVBrowser', (data) =>
- this.startVBrowser(socket, data)
+ this.startVBrowser(socket, data),
);
socket.on('CMD:stopVBrowser', () => this.stopVBrowser(socket));
socket.on('CMD:changeController', (data) =>
- this.changeController(socket, data)
+ this.changeController(socket, data),
);
socket.on('CMD:subtitle', (data) => this.addSubtitles(socket, data));
socket.on('CMD:lock', (data) => this.lockRoom(socket, data));
@@ -183,7 +183,7 @@ export class Room {
socket.on('CMD:playlistAdd', (data) => this.playlistAdd(socket, data));
socket.on('CMD:playlistMove', (data) => this.playlistMove(socket, data));
socket.on('CMD:playlistDelete', (data) =>
- this.playlistDelete(socket, data)
+ this.playlistDelete(socket, data),
);
socket.on('signal', (data) => this.sendSignal(socket, data));
@@ -191,7 +191,7 @@ export class Room {
socket.on('kickUser', (data) => this.kickUser(socket, data));
socket.on('CMD:deleteChatMessages', (data) =>
- this.deleteChatMessages(socket, data)
+ this.deleteChatMessages(socket, data),
);
socket.on('disconnect', () => this.disconnectUser(socket));
@@ -277,7 +277,7 @@ export class Room {
const roomString = this.serialize();
await postgres.query(
`UPDATE room SET "lastUpdateTime" = $1, data = $2 WHERE "roomId" = $3`,
- [this.lastUpdateTime, roomString, this.roomId]
+ [this.lastUpdateTime, roomString, this.roomId],
);
} catch (e) {
console.warn(e);
@@ -326,7 +326,7 @@ export class Room {
private getHostState = (): HostState => {
// Reverse lookup the clientid to the socket id
const match = this.roster.find(
- (user) => this.clientIdMap[user.id] === this.vBrowser?.controllerClient
+ (user) => this.clientIdMap[user.id] === this.vBrowser?.controllerClient,
);
return {
video: this.video ?? '',
@@ -369,7 +369,7 @@ export class Room {
region,
id,
roomId: this.roomId,
- }
+ },
);
}
} catch (e) {
@@ -432,7 +432,7 @@ export class Room {
private validateOwner = async (uid: string) => {
const result = await postgres?.query(
'SELECT owner FROM room where "roomId" = $1',
- [this.roomId]
+ [this.roomId],
);
const owner = result?.rows[0]?.owner;
return !owner || uid === owner;
@@ -459,7 +459,7 @@ export class Room {
private changeUserID = async (
socket: Socket,
- data: { uid: string; token: string }
+ data: { uid: string; token: string },
) => {
if (!data) {
return;
@@ -609,7 +609,7 @@ export class Room {
private playlistMove = (
socket: Socket,
- data: { index: number; toIndex: number }
+ data: { index: number; toIndex: number },
) => {
if (data.index !== -1) {
const items = this.playlist.splice(data.index, 1);
@@ -721,14 +721,14 @@ export class Room {
private addReaction = (
socket: Socket,
- data: { value: string; msgId: string; msgTimestamp: string }
+ data: { value: string; msgId: string; msgTimestamp: string },
) => {
// Emojis can be multiple bytes
if (data.value.length > 8) {
return;
}
const msg = this.chat.find(
- (m) => m.id === data.msgId && m.timestamp === data.msgTimestamp
+ (m) => m.id === data.msgId && m.timestamp === data.msgTimestamp,
);
if (!msg) {
return;
@@ -746,20 +746,20 @@ export class Room {
private removeReaction = (
socket: Socket,
- data: { value: string; msgId: string; msgTimestamp: string }
+ data: { value: string; msgId: string; msgTimestamp: string },
) => {
// Emojis can be multiple bytes
if (data.value.length > 8) {
return;
}
const msg = this.chat.find(
- (m) => m.id === data.msgId && m.timestamp === data.msgTimestamp
+ (m) => m.id === data.msgId && m.timestamp === data.msgTimestamp,
);
if (!msg || !msg.reactions?.[data.value]) {
return;
}
msg.reactions[data.value] = msg.reactions[data.value].filter(
- (id) => id !== socket.id
+ (id) => id !== socket.id,
);
const reaction: Reaction = { user: socket.id, ...data };
this.io.of(this.roomId).emit('REC:removeReaction', reaction);
@@ -792,7 +792,7 @@ export class Room {
private joinScreenSharing = (
socket: Socket,
- data: { file: boolean; mediasoup?: boolean }
+ data: { file: boolean; mediasoup?: boolean },
) => {
if (!this.validateLock(socket.id)) {
return;
@@ -812,13 +812,13 @@ export class Room {
if (data && data.file) {
this.cmdHost(
socket,
- 'fileshare://' + this.clientIdMap[socket.id] + mediasoupSuffix
+ 'fileshare://' + this.clientIdMap[socket.id] + mediasoupSuffix,
);
redisCount('fileShareStarts');
} else {
this.cmdHost(
socket,
- 'screenshare://' + this.clientIdMap[socket.id] + mediasoupSuffix
+ 'screenshare://' + this.clientIdMap[socket.id] + mediasoupSuffix,
);
redisCount('screenShareStarts');
}
@@ -841,7 +841,7 @@ export class Room {
token: string;
rcToken: string;
options: { size: string; region: string; provider: string };
- }
+ },
) => {
if (!this.validateLock(socket.id)) {
socket.emit('errorMessage', 'Room is locked.');
@@ -871,7 +871,7 @@ export class Room {
) {
socket.emit(
'errorMessage',
- 'A verified email is required to start a VBrowser.'
+ 'A verified email is required to start a VBrowser.',
);
return;
}
@@ -885,13 +885,13 @@ export class Room {
const clientCount = await redis.zincrby(
'vBrowserClientIDs',
1,
- clientId
+ clientId,
);
redis.expireat('vBrowserClientIDs', expireTime);
const clientMinutes = await redis.zincrby(
'vBrowserClientIDMinutes',
1,
- clientId
+ clientId,
);
redis.expireat('vBrowserClientIDMinutes', expireTime);
}
@@ -907,7 +907,7 @@ export class Room {
if (false) {
socket.emit(
'errorMessage',
- 'There is already an active vBrowser for this user.'
+ 'There is already an active vBrowser for this user.',
);
return;
}
@@ -984,7 +984,7 @@ export class Room {
region,
uid,
roomId,
- }
+ },
);
assignment = data;
}
@@ -1004,11 +1004,11 @@ export class Room {
'[ASSIGN] %s to %s in %s',
assignment.provider + ':' + assignment.id,
roomId,
- assignElapsed + 'ms'
+ assignElapsed + 'ms',
);
this.cmdHost(
null,
- 'vbrowser://' + this.vBrowser.pass + '@' + this.vBrowser.host
+ 'vbrowser://' + this.vBrowser.pass + '@' + this.vBrowser.host,
);
}
await new Promise((resolve) => setTimeout(resolve, 1000));
@@ -1052,7 +1052,7 @@ export class Room {
private lockRoom = async (
socket: Socket,
- data: { uid: string; token: string; locked: boolean }
+ data: { uid: string; token: string; locked: boolean },
) => {
if (!data) {
return;
@@ -1080,7 +1080,7 @@ export class Room {
uid: string;
token: string;
undo: boolean;
- }
+ },
) => {
if (!postgres) {
socket.emit('errorMessage', 'Database is not available');
@@ -1088,7 +1088,7 @@ export class Room {
}
const decoded = await validateUserToken(
data?.uid as string,
- data?.token as string
+ data?.token as string,
);
if (!decoded) {
socket.emit('errorMessage', 'Failed to authenticate user');
@@ -1116,7 +1116,7 @@ export class Room {
roomTitleColor: null,
mediaPath: null,
},
- { roomId: this.roomId }
+ { roomId: this.roomId },
);
socket.emit('REC:getRoomState', {});
} else {
@@ -1124,14 +1124,14 @@ export class Room {
const roomCount = (
await postgres.query(
'SELECT count(1) from room where owner = $1 AND "roomId" != $2',
- [owner, this.roomId]
+ [owner, this.roomId],
)
).rows[0].count;
const limit = isSubscriber ? config.SUBSCRIBER_ROOM_LIMIT : 1;
if (roomCount >= limit) {
socket.emit(
'errorMessage',
- `You've exceeded the permanent room limit. Subscribe for additional permanent rooms.`
+ `You've exceeded the permanent room limit. Subscribe for additional permanent rooms.`,
);
return;
}
@@ -1160,7 +1160,7 @@ export class Room {
}
const result = await postgres.query(
`SELECT password, vanity, owner, "isChatDisabled", "roomTitle", "roomDescription", "roomTitleColor", "mediaPath" FROM room where "roomId" = $1`,
- [this.roomId]
+ [this.roomId],
);
const first = result.rows[0];
if (this.isChatDisabled === undefined) {
@@ -1191,7 +1191,7 @@ export class Room {
roomDescription: string;
roomTitleColor: string;
mediaPath: string;
- }
+ },
) => {
if (!postgres) {
socket.emit('errorMessage', 'Database is not available');
@@ -1199,7 +1199,7 @@ export class Room {
}
const decoded = await validateUserToken(
data?.uid as string,
- data?.token as string
+ data?.token as string,
);
if (!decoded) {
socket.emit('errorMessage', 'Failed to authenticate user');
@@ -1307,7 +1307,7 @@ export class Room {
private signalSS = (
socket: Socket,
- data: { to: string; sharer: boolean; msg: string }
+ data: { to: string; sharer: boolean; msg: string },
) => {
if (!data) {
return;
@@ -1343,11 +1343,11 @@ export class Room {
uid: string;
token: string;
userToBeKicked: string;
- }
+ },
) => {
const decoded = await validateUserToken(
data?.uid as string,
- data?.token as string
+ data?.token as string,
);
if (!decoded) {
socket.emit('errorMessage', 'Failed to authenticate user');
@@ -1378,11 +1378,11 @@ export class Room {
timestamp: string | undefined;
uid: string;
token: string;
- }
+ },
) => {
const decoded = await validateUserToken(
data?.uid as string,
- data?.token as string
+ data?.token as string,
);
if (!decoded) {
socket.emit('errorMessage', 'Failed to authenticate user');
diff --git a/server/server.ts b/server/server.ts
index 3b3eae5d3a..9b12934385 100644
--- a/server/server.ts
+++ b/server/server.ts
@@ -44,7 +44,7 @@ if (process.env.NODE_ENV === 'development') {
},
(error) => {
console.error(error);
- }
+ },
);
}
@@ -183,7 +183,7 @@ app.get('/searchSubtitles', async (req, res) => {
subUrl = `https://rest.opensubtitles.org/search/moviebytesize-${size}/moviehash-${hash}/sublanguageid-eng`;
} else if (title) {
subUrl = `https://rest.opensubtitles.org/search/query-${encodeURIComponent(
- title
+ title,
)}/sublanguageid-eng`;
}
console.log(subUrl);
@@ -301,7 +301,7 @@ app.post('/manageSub', async (req, res) => {
}
const session = await createSelfServicePortal(
customer.id,
- req.body?.return_url
+ req.body?.return_url,
);
return res.json(session);
});
@@ -328,7 +328,7 @@ app.delete('/deleteAccount', async (req, res) => {
app.get('/metadata', async (req, res) => {
const decoded = await validateUserToken(
req.query?.uid as string,
- req.query?.token as string
+ req.query?.token as string,
);
let isSubscriber = await getIsSubscriberByEmail(decoded?.email);
// Has the user ever been a subscriber?
@@ -337,7 +337,7 @@ app.get('/metadata', async (req, res) => {
try {
isFreePoolFull = (
await axios.get(
- 'http://localhost:' + config.VMWORKER_PORT + '/isFreePoolFull'
+ 'http://localhost:' + config.VMWORKER_PORT + '/isFreePoolFull',
)
).data.isFull;
} catch (e: any) {
@@ -353,7 +353,7 @@ app.get('/metadata', async (req, res) => {
postgres,
'active_user',
{ uid: decoded?.uid, lastActiveTime: new Date() },
- { uid: true }
+ { uid: true },
);
}
return res.json({
@@ -368,7 +368,7 @@ app.get('/resolveRoom/:vanity', async (req, res) => {
const vanity = req.params.vanity;
const result = await postgres?.query(
`SELECT "roomId", vanity from room WHERE LOWER(vanity) = $1`,
- [vanity?.toLowerCase() ?? '']
+ [vanity?.toLowerCase() ?? ''],
);
// console.log(vanity, result.rows);
// We also use this for checking name availability, so just return empty response if it doesn't exist (http 200)
@@ -383,14 +383,14 @@ app.get('/resolveShard/:roomId', async (req, res) => {
app.get('/listRooms', async (req, res) => {
const decoded = await validateUserToken(
req.query?.uid as string,
- req.query?.token as string
+ req.query?.token as string,
);
if (!decoded) {
return res.status(400).json({ error: 'invalid user token' });
}
const result = await postgres?.query(
`SELECT "roomId", vanity from room WHERE owner = $1`,
- [decoded.uid]
+ [decoded.uid],
);
return res.json(result?.rows ?? []);
});
@@ -398,14 +398,14 @@ app.get('/listRooms', async (req, res) => {
app.delete('/deleteRoom', async (req, res) => {
const decoded = await validateUserToken(
req.query?.uid as string,
- req.query?.token as string
+ req.query?.token as string,
);
if (!decoded) {
return res.status(400).json({ error: 'invalid user token' });
}
const result = await postgres?.query(
`DELETE from room WHERE owner = $1 and "roomId" = $2`,
- [decoded.uid, req.query.roomId]
+ [decoded.uid, req.query.roomId],
);
return res.json(result?.rows);
});
@@ -413,7 +413,7 @@ app.delete('/deleteRoom', async (req, res) => {
app.get('/linkAccount', async (req, res) => {
const decoded = await validateUserToken(
req.query?.uid as string,
- req.query?.token as string
+ req.query?.token as string,
);
if (!decoded) {
return res.status(400).json({ error: 'invalid user token' });
@@ -426,7 +426,7 @@ app.get('/linkAccount', async (req, res) => {
if (decoded?.uid && postgres) {
const { rows } = await postgres.query(
'SELECT kind, accountid, accountname, discriminator FROM link_account WHERE uid = $1',
- [decoded?.uid]
+ [decoded?.uid],
);
linkAccounts = rows;
}
@@ -436,7 +436,7 @@ app.get('/linkAccount', async (req, res) => {
app.post('/linkAccount', async (req, res) => {
const decoded = await validateUserToken(
req.body?.uid as string,
- req.body?.token as string
+ req.body?.token as string,
);
if (!decoded) {
return res.status(400).json({ error: 'invalid user token' });
@@ -468,7 +468,7 @@ app.post('/linkAccount', async (req, res) => {
uid: decoded.uid,
kind: kind,
},
- { uid: true, kind: true }
+ { uid: true, kind: true },
);
return res.json({});
}
@@ -478,7 +478,7 @@ app.delete('/linkAccount', async (req, res) => {
// TODO read from req.query instead
const decoded = await validateUserToken(
req.body?.uid as string,
- req.body?.token as string
+ req.body?.token as string,
);
if (!decoded) {
return res.status(400).json({ error: 'invalid user token' });
@@ -488,7 +488,7 @@ app.delete('/linkAccount', async (req, res) => {
}
await postgres.query(
'DELETE FROM link_account WHERE uid = $1 AND kind = $2',
- [decoded.uid, req.body.kind]
+ [decoded.uid, req.body.kind],
);
res.json({});
});
@@ -504,7 +504,7 @@ app.get('/proxy/*', async (req, res) => {
// VOD
// https://d2vjef5jvl6bfs.cloudfront.net/3012391a6c3e84c79ef6_gamesdonequick_41198403369_1681059003/chunked/index-dvr.m3u8
const resp = await axios.get(
- 'https://' + req.query.host + req.path.slice('/proxy'.length)
+ 'https://' + req.query.host + req.path.slice('/proxy'.length),
);
const re = /proxy\/(.*)\/chunked\/index-dvr.m3u8/;
const rematch = re.exec(req.path);
@@ -513,7 +513,7 @@ app.get('/proxy/*', async (req, res) => {
const re2 = /(.*).ts/g;
const repl = resp.data.replaceAll(
re2,
- `/proxy/${name}/chunked/$1.ts?host=${host}`
+ `/proxy/${name}/chunked/$1.ts?host=${host}`,
);
res.send(repl);
} else if (req.path.includes('/v1/playlist')) {
@@ -521,21 +521,21 @@ app.get('/proxy/*', async (req, res) => {
// https://video-weaver.sea02.hls.ttvnw.net/v1/playlist/CrQEgv7Mz6nnsfJH3XtVQxeYXk8mViy1zNGWglcybvxZsI1rv3iLnjAnnqwCiVXCJ-DdD27J6RuFrLy7YUYwHUCKazIKICIupUCn9UXtaBYhBM5JIYqg9dz6NWYrCWU9HZJj2TGROv9mAOKuTR51YS82hdYL4PFZa3xxWXhgDsxXQHNDB03kY6S0aG0-EVva1xYrn5Ge6IAXRwug9QDGlb-ydtF3BtYppoTklVI7CVLySPPwbbt5Ow1JXdnKhLSwQEs4bh3BLwMnRBwUFI5nmE18BLYbkMOUivgYP5SSMgnGGlSkJO-iJNPWvepunEgyBUzB_7L-b1keTcV-Qak9IcWIITIWbRvmg6qB3ZSuWdcJgWKmdXdIn4qoRM4o16G1_0N_WRqPtMQFo0hmTlAVmHrzRArJQmaSgqAxZxRbFMd9RFeX6qjP9NtwguPbSeStdVbQxMNC34iavYUIxo8Ug812BHsG7J_kIlof2zkIqkEbP3oV3UkSByIo7xh9EEVargjaGDuQRt8zPQ6-fNBWJJe9F6IFu7lXBPIJ016lopyfcvTWjbLbBHsVkg6vG-3UISh0nud7KB5g5ipQePhtcFSI5hvjlfX1DAVHEpTWXkvlnL4wNqEqpBYL2btSXYeE1Cb-RAvrAT0s61usERcL2eI-S5aTcSO8_hxQ2afC7c9vlypOWgP6p6XNpViZHXmdXv4t-d68Z-MpLtSU7VbB3pRWnSswFFyA3W39ITic4lb97Djp3wHhGgz0Sy8aDb9r0tnphIYgASoJdXMtZWFzdC0yMKQG.m3u8
// Extract the edge URL host and add it to URL so proxy can fetch
const resp = await axios.get(
- 'https://' + req.query.host + req.path.slice('/proxy'.length)
+ 'https://' + req.query.host + req.path.slice('/proxy'.length),
);
const re = /https:\/\/(.*)\/v1\/segment\/(.*)/g;
const match = re.exec(resp.data);
const edgehost = match?.[1];
const repl = resp.data.replaceAll(
re,
- `/proxy/v1/segment/$2?host=${edgehost}`
+ `/proxy/v1/segment/$2?host=${edgehost}`,
);
res.send(repl);
} else {
// Segment
const resp = await axios.get(
'https://' + req.query.host + req.path.slice('/proxy'.length),
- { responseType: 'arraybuffer' }
+ { responseType: 'arraybuffer' },
);
res.writeHead(200, {
'Content-Type': 'application/octet-stream',
@@ -555,7 +555,7 @@ app.use(express.static(config.BUILD_DIRECTORY));
// Send index.html for all other requests (SPA)
app.use('/*', (_req, res) => {
res.sendFile(
- path.resolve(__dirname + `/../${config.BUILD_DIRECTORY}/index.html`)
+ path.resolve(__dirname + `/../${config.BUILD_DIRECTORY}/index.html`),
);
});
@@ -628,7 +628,7 @@ async function minuteMetrics() {
// Update the heartbeat
await postgres?.query(
`UPDATE vbrowser SET "heartbeatTime" = $1 WHERE "roomId" = $2 and vmid = $3`,
- [new Date(), room.roomId, room.vBrowser.id]
+ [new Date(), room.roomId, room.vBrowser.id],
);
const expireTime = getStartOfDay() / 1000 + 86400;
@@ -636,7 +636,7 @@ async function minuteMetrics() {
await redis?.zincrby(
'vBrowserClientIDMinutes',
1,
- room.vBrowser.creatorClientID
+ room.vBrowser.creatorClientID,
);
await redis?.expireat('vBrowserClientIDMinutes', expireTime);
}
@@ -644,7 +644,7 @@ async function minuteMetrics() {
await redis?.zincrby(
'vBrowserUIDMinutes',
1,
- room.vBrowser?.creatorUID
+ room.vBrowser?.creatorUID,
);
await redis?.expireat('vBrowserUIDMinutes', expireTime);
}
@@ -685,7 +685,7 @@ async function getAllRooms() {
}
return (
await postgres.query(
- `SELECT * from room where "roomId" SIMILAR TO '${range}'`
+ `SELECT * from room where "roomId" SIMILAR TO '${range}'`,
)
).rows;
}
@@ -747,12 +747,12 @@ async function getStats() {
});
currentVBrowserUIDCounts = Object.fromEntries(
- Object.entries(currentVBrowserUIDCounts).filter(([, val]) => val > 1)
+ Object.entries(currentVBrowserUIDCounts).filter(([, val]) => val > 1),
);
const dbRoomData = (
await postgres?.query(
- `SELECT "roomId", "creationTime", "lastUpdateTime", vanity, "isSubRoom", "roomTitle", "roomDescription", "mediaPath", owner, password from room WHERE "lastUpdateTime" > NOW() - INTERVAL '7 day' ORDER BY "creationTime" DESC`
+ `SELECT "roomId", "creationTime", "lastUpdateTime", vanity, "isSubRoom", "roomTitle", "roomDescription", "mediaPath", owner, password from room WHERE "lastUpdateTime" > NOW() - INTERVAL '7 day' ORDER BY "creationTime" DESC`,
)
)?.rows;
const currentRoomData = dbRoomData
@@ -801,18 +801,18 @@ async function getStats() {
?.split('\n')
.find((line) => line.startsWith('used_memory:'))
?.split(':')[1]
- .trim()
+ .trim(),
);
const postgresUsage = Number(
(await postgres?.query(`SELECT pg_database_size('postgres');`))?.rows[0]
- .pg_database_size
+ .pg_database_size,
);
const numPermaRooms = Number(
(await postgres?.query('SELECT count(1) from room WHERE owner IS NOT NULL'))
- ?.rows[0].count
+ ?.rows[0].count,
);
const numSubs = Number(
- (await postgres?.query('SELECT count(1) from subscriber'))?.rows[0].count
+ (await postgres?.query('SELECT count(1) from subscriber'))?.rows[0].count,
);
const discordBotWatch = await getRedisCountDay('discordBotWatch');
const createRoomErrors = await getRedisCountDay('createRoomError');
@@ -825,18 +825,18 @@ async function getStats() {
const vBrowserFails = await getRedisCountDay('vBrowserFails');
const vBrowserStagingFails = await getRedisCountDay('vBrowserStagingFails');
const vBrowserStopTimeout = await getRedisCountDay(
- 'vBrowserTerminateTimeout'
+ 'vBrowserTerminateTimeout',
);
const vBrowserStopEmpty = await getRedisCountDay('vBrowserTerminateEmpty');
const vBrowserStopManual = await getRedisCountDay('vBrowserTerminateManual');
const recaptchaRejectsLowScore = await getRedisCountDay(
- 'recaptchaRejectsLowScore'
+ 'recaptchaRejectsLowScore',
);
const vBrowserStartMS = await redis?.lrange('vBrowserStartMS', 0, -1);
const vBrowserStageRetries = await redis?.lrange(
'vBrowserStageRetries',
0,
- -1
+ -1,
);
const vBrowserStageFails = await redis?.lrange('vBrowserStageFails', 0, -1);
const vBrowserSessionMS = await redis?.lrange('vBrowserSessionMS', 0, -1);
@@ -850,7 +850,7 @@ async function getStats() {
const videoChatStarts = await getRedisCountDay('videoChatStarts');
const connectStarts = await getRedisCountDay('connectStarts');
const connectStartsDistinct = await getRedisCountDayDistinct(
- 'connectStartsDistinct'
+ 'connectStartsDistinct',
);
const subUploads = await getRedisCountDay('subUploads');
const subDownloadsOS = await getRedisCountDay('subDownloadsOS');
@@ -863,7 +863,7 @@ async function getStats() {
'WITHSCORES',
'LIMIT',
0,
- 20
+ 20,
);
const vBrowserUIDs = await redis?.zrevrangebyscore(
'vBrowserUIDs',
@@ -872,7 +872,7 @@ async function getStats() {
'WITHSCORES',
'LIMIT',
0,
- 20
+ 20,
);
const vBrowserClientIDMinutes = await redis?.zrevrangebyscore(
'vBrowserClientIDMinutes',
@@ -881,7 +881,7 @@ async function getStats() {
'WITHSCORES',
'LIMIT',
0,
- 20
+ 20,
);
const vBrowserUIDMinutes = await redis?.zrevrangebyscore(
'vBrowserUIDMinutes',
@@ -890,7 +890,7 @@ async function getStats() {
'WITHSCORES',
'LIMIT',
0,
- 20
+ 20,
);
const vBrowserClientIDsCard = await redis?.zcard('vBrowserClientIDs');
const vBrowserUIDsCard = await redis?.zcard('vBrowserUIDs');
diff --git a/server/syncSubs.ts b/server/syncSubs.ts
index 87d568fcff..e1b30b14dd 100644
--- a/server/syncSubs.ts
+++ b/server/syncSubs.ts
@@ -52,9 +52,9 @@ async function syncSubscribers() {
.map((sub) =>
emailMap.get(sub.customer)
? getUserByEmail(emailMap.get(sub.customer))
- : null
+ : null,
)
- .filter(Boolean)
+ .filter(Boolean),
);
fbUsers.forEach((user) => {
uidMap.set(user?.email, user?.uid);
@@ -82,7 +82,8 @@ async function syncSubscribers() {
console.log('%s subs do not have UID, using email', noUID);
const newResult = result.filter(
- (sub, index) => index === result.findIndex((other) => sub.uid === other.uid)
+ (sub, index) =>
+ index === result.findIndex((other) => sub.uid === other.uid),
);
console.log('%s deduped subs to insert', newResult.length);
if (result.length !== newResult.length) {
@@ -110,7 +111,7 @@ async function syncSubscribers() {
postgres2,
'room',
{ isSubRoom: true },
- { owner: row.uid }
+ { owner: row.uid },
);
}
await postgres2?.query('COMMIT');
@@ -129,12 +130,12 @@ async function syncSubscribers() {
// Update the sub status of users in Discord
// Join the current subs with linked accounts
const guild = discordBot.guilds.cache.get(
- config.DISCORD_ADMIN_BOT_SERVER_ID
+ config.DISCORD_ADMIN_BOT_SERVER_ID,
);
const role = guild?.roles.cache.get(config.DISCORD_ADMIN_BOT_SUB_ROLE_ID);
const toUpdate = (
await postgres2.query(
- `SELECT la.accountid from subscriber JOIN link_account la ON subscriber.uid = la.uid WHERE la.kind = 'discord'`
+ `SELECT la.accountid from subscriber JOIN link_account la ON subscriber.uid = la.uid WHERE la.kind = 'discord'`,
)
).rows;
console.log('%s users to set sub role', toUpdate.length);
diff --git a/server/timeSeries.ts b/server/timeSeries.ts
index a06705b83b..55c13f342a 100644
--- a/server/timeSeries.ts
+++ b/server/timeSeries.ts
@@ -13,7 +13,7 @@ async function statsTimeSeries() {
const stats = await statsAgg();
const isFreePoolFull = (
await axios.get(
- 'http://localhost:' + config.VMWORKER_PORT + '/isFreePoolFull'
+ 'http://localhost:' + config.VMWORKER_PORT + '/isFreePoolFull',
)
).data.isFull;
const datapoint: AnyDict = {
@@ -33,7 +33,7 @@ async function statsTimeSeries() {
stats.vBrowserStartMS &&
stats.vBrowserStartMS.reduce(
(a: string, b: string) => Number(a) + Number(b),
- 0
+ 0,
) / stats.vBrowserStartMS.length,
vBrowserStarts: stats.vBrowserStarts,
vBrowserLaunches: stats.vBrowserLaunches,
diff --git a/server/tsconfig.json b/server/tsconfig.json
index f69fcfa9aa..1f57d62cf5 100644
--- a/server/tsconfig.json
+++ b/server/tsconfig.json
@@ -6,7 +6,7 @@
"strict": true,
"esModuleInterop": true,
"module": "commonjs",
- "outDir": "../buildServer"
+ "outDir": "../buildServer",
},
- "include": [".", "../global.d.ts"]
+ "include": [".", "../global.d.ts"],
}
diff --git a/server/utils/firebase.ts b/server/utils/firebase.ts
index f6ba043a01..abb00b7e9b 100644
--- a/server/utils/firebase.ts
+++ b/server/utils/firebase.ts
@@ -4,7 +4,7 @@ import * as admin from 'firebase-admin';
if (config.FIREBASE_ADMIN_SDK_CONFIG) {
admin.initializeApp({
credential: admin.credential.cert(
- JSON.parse(config.FIREBASE_ADMIN_SDK_CONFIG)
+ JSON.parse(config.FIREBASE_ADMIN_SDK_CONFIG),
),
databaseURL: config.FIREBASE_DATABASE_URL,
});
diff --git a/server/utils/moniker.ts b/server/utils/moniker.ts
index c435fbec7e..84c4a68d11 100644
--- a/server/utils/moniker.ts
+++ b/server/utils/moniker.ts
@@ -21,7 +21,7 @@ export function makeRoomName(shard: number | undefined) {
if (shard) {
// Filter the adjective list by shard
filteredAdjectives = adjectives.filter(
- (adj) => resolveShard(adj) === Number(shard)
+ (adj) => resolveShard(adj) === Number(shard),
);
}
const adjective = randomElement(filteredAdjectives);
@@ -32,7 +32,7 @@ export function makeRoomName(shard: number | undefined) {
export function makeUserName() {
return `${capFirst(randomElement(adjectives))} ${capFirst(
- randomElement(nouns)
+ randomElement(nouns),
)}`;
}
diff --git a/server/utils/playlist.ts b/server/utils/playlist.ts
index a130ecb41a..8b7c6e7f91 100644
--- a/server/utils/playlist.ts
+++ b/server/utils/playlist.ts
@@ -1,6 +1,6 @@
export const findPlaylistVideoByUrl = (
playlist: PlaylistVideo[],
- url?: string
+ url?: string,
) => {
if (!url) return;
return playlist.find((video) => video.url === url);
diff --git a/server/utils/postgres.ts b/server/utils/postgres.ts
index a21f2f2e70..810038815c 100644
--- a/server/utils/postgres.ts
+++ b/server/utils/postgres.ts
@@ -31,7 +31,7 @@ export async function updateObject(
postgres: Client,
table: string,
object: AnyDict,
- condition: AnyDict
+ condition: AnyDict,
): Promise> {
const columns = Object.keys(object);
const values = Object.values(object);
@@ -52,7 +52,7 @@ export async function updateObject(
export async function insertObject(
postgres: Client,
table: string,
- object: AnyDict
+ object: AnyDict,
): Promise> {
const columns = Object.keys(object);
const values = Object.values(object);
@@ -68,7 +68,7 @@ export async function upsertObject(
postgres: Client,
table: string,
object: AnyDict,
- conflict: BooleanDict
+ conflict: BooleanDict,
): Promise> {
const columns = Object.keys(object);
const values = Object.values(object);
diff --git a/server/utils/statsAgg.ts b/server/utils/statsAgg.ts
index ee19718012..a330eb34f8 100644
--- a/server/utils/statsAgg.ts
+++ b/server/utils/statsAgg.ts
@@ -12,7 +12,7 @@ export async function statsAgg() {
axios({
url: `http://localhost:${port}/stats?key=${config.STATS_KEY}`,
validateStatus: () => true,
- })
+ }),
);
let stats: any = {};
diff --git a/server/utils/stripe.ts b/server/utils/stripe.ts
index 346fc9ec87..907aecb939 100644
--- a/server/utils/stripe.ts
+++ b/server/utils/stripe.ts
@@ -26,14 +26,14 @@ export async function getIsSubscriberByEmail(email: string | undefined) {
}
const customer = await getCustomerByEmail(email);
const isSubscriber = Boolean(
- customer?.subscriptions?.data?.find((sub) => sub?.status === 'active')
+ customer?.subscriptions?.data?.find((sub) => sub?.status === 'active'),
);
return isSubscriber;
}
export async function createSelfServicePortal(
customerId: string,
- returnUrl: string
+ returnUrl: string,
) {
return await stripe.billingPortal.sessions.create({
customer: customerId,
diff --git a/server/utils/youtube.ts b/server/utils/youtube.ts
index 63bce21917..74c94a22de 100644
--- a/server/utils/youtube.ts
+++ b/server/utils/youtube.ts
@@ -15,7 +15,7 @@ let Youtube = config.YOUTUBE_API_KEY
: null;
export const mapYoutubeSearchResult = (
- video: youtube_v3.Schema$SearchResult
+ video: youtube_v3.Schema$SearchResult,
): PlaylistVideo => {
return {
channel: video.snippet?.channelTitle ?? '',
@@ -28,7 +28,7 @@ export const mapYoutubeSearchResult = (
};
export const mapYoutubeListResult = (
- video: youtube_v3.Schema$Video
+ video: youtube_v3.Schema$Video,
): PlaylistVideo => {
const videoId = video.id;
return {
@@ -42,7 +42,7 @@ export const mapYoutubeListResult = (
};
export const searchYoutube = async (
- query: string
+ query: string,
): Promise => {
const response = await Youtube?.search.list({
part: ['snippet'],
@@ -68,7 +68,7 @@ export const getYoutubeVideoID = (url: string) => {
};
export const fetchYoutubeVideo = async (
- id: string
+ id: string,
): Promise => {
const response = await Youtube?.videos.list({
part: ['snippet', 'contentDetails'],
diff --git a/server/vm/base.ts b/server/vm/base.ts
index e1fff97c6d..9fd25f6718 100644
--- a/server/vm/base.ts
+++ b/server/vm/base.ts
@@ -51,7 +51,7 @@ export abstract class VMManager {
public getCurrentSize = async () => {
const { rows } = await postgres.query(
`SELECT count(1) FROM vbrowser WHERE pool = $1`,
- [this.getPoolName()]
+ [this.getPoolName()],
);
return Number(rows[0]?.count);
};
@@ -85,7 +85,7 @@ export abstract class VMManager {
public getAvailableCount = async (): Promise => {
const { rows } = await postgres.query(
`SELECT count(1) FROM vbrowser WHERE pool = $1 and state = 'available'`,
- [this.getPoolName()]
+ [this.getPoolName()],
);
return Number(rows[0]?.count);
};
@@ -93,7 +93,7 @@ export abstract class VMManager {
public getStagingCount = async (): Promise => {
const { rows } = await postgres.query(
`SELECT count(1) FROM vbrowser WHERE pool = $1 and state = 'staging'`,
- [this.getPoolName()]
+ [this.getPoolName()],
);
return Number(rows[0]?.count);
};
@@ -101,7 +101,7 @@ export abstract class VMManager {
public getAvailableVBrowsers = async (): Promise => {
const { rows } = await postgres.query(
`SELECT vmid from vbrowser WHERE pool = $1 and state = 'available'`,
- [this.getPoolName()]
+ [this.getPoolName()],
);
return rows.map((row: any) => row.vmid);
};
@@ -109,7 +109,7 @@ export abstract class VMManager {
public getStagingVBrowsers = async (): Promise => {
const { rows } = await postgres.query(
`SELECT vmid from vbrowser WHERE pool = $1 and state = 'staging'`,
- [this.getPoolName()]
+ [this.getPoolName()],
);
return rows.map((row: any) => row.vmid);
};
@@ -124,7 +124,7 @@ export abstract class VMManager {
public assignVM = async (
roomId: string,
- uid: string
+ uid: string,
): Promise => {
if (!roomId || !uid) {
return undefined;
@@ -154,7 +154,7 @@ export abstract class VMManager {
LIMIT 1
)
RETURNING data`,
- [roomId, uid, new Date(), this.getPoolName()]
+ [roomId, uid, new Date(), this.getPoolName()],
);
return rows[0]?.data;
};
@@ -170,7 +170,7 @@ export abstract class VMManager {
// verify the roomId matches if user initiated
const { rows } = await postgres.query(
`SELECT "roomId" FROM vbrowser WHERE pool = $1 AND vmid = $2`,
- [this.getPoolName(), vmid]
+ [this.getPoolName(), vmid],
);
if (rows[0]?.roomId && rows[0]?.roomId !== roomId) {
console.log(
@@ -178,7 +178,7 @@ export abstract class VMManager {
this.getPoolName(),
vmid,
rows[0]?.roomId,
- roomId
+ roomId,
);
return;
}
@@ -200,7 +200,7 @@ export abstract class VMManager {
UPDATE SET state = 'staging',
"roomId" = NULL, uid = NULL, retries = 0, "heartbeatTime" = NULL, "assignTime" = NULL, data = NULL
`,
- [this.getPoolName(), vmid, new Date()]
+ [this.getPoolName(), vmid, new Date()],
);
console.log('UPSERT', result.rowCount);
// Normally this should be an update, but we could insert if:
@@ -221,7 +221,7 @@ export abstract class VMManager {
`
INSERT INTO vbrowser(pool, vmid, "creationTime", state)
VALUES($1, $2, $3, 'staging')`,
- [this.getPoolName(), id, new Date()]
+ [this.getPoolName(), id, new Date()],
);
redisCount('vBrowserLaunches');
return id;
@@ -230,7 +230,7 @@ export abstract class VMManager {
e.response?.status,
JSON.stringify(e.response?.data),
e.config?.url,
- e.config?.data
+ e.config?.data,
);
}
};
@@ -241,7 +241,7 @@ export abstract class VMManager {
// If we don't actually complete the termination, cleanup will reset it
const { command, rowCount } = await postgres.query(
`DELETE FROM vbrowser WHERE pool = $1 AND vmid = $2`,
- [this.getPoolName(), vmid]
+ [this.getPoolName(), vmid],
);
console.log(command, rowCount);
// We can log the VM lifetime by returning the creationTime and diffing
@@ -270,7 +270,7 @@ export abstract class VMManager {
'currentSize:',
currentSize,
'limit:',
- this.getLimitSize()
+ this.getLimitSize(),
);
this.startVMWrapper();
}
@@ -303,7 +303,7 @@ export abstract class VMManager {
this.getPoolName(),
config.VM_MIN_UPTIME_MINUTES * 60, // to seconds
this.getMinSize(),
- ]
+ ],
);
const first = rows[0];
if (first) {
@@ -311,7 +311,7 @@ export abstract class VMManager {
'[RESIZE-DECR] %s: %s up for %s seconds of hour',
this.getPoolName(),
first.vmid,
- first.uptime_frac
+ first.uptime_frac,
);
await this.terminateVMWrapper(first.vmid);
}
@@ -329,7 +329,7 @@ export abstract class VMManager {
} catch (e) {
console.log(
'[CLEANUP] %s: failed to fetch VM list',
- this.getPoolName()
+ this.getPoolName(),
);
return;
}
@@ -342,14 +342,14 @@ export abstract class VMManager {
OR state = 'staging'
OR state = 'available')
`,
- [this.getPoolName()]
+ [this.getPoolName()],
);
const inUse = new Set(rows.map((row: any) => row.vmid));
console.log(
'[CLEANUP] %s: found %s VMs, %s to keep',
this.getPoolName(),
allVMs.length,
- inUse.size
+ inUse.size,
);
for (let i = 0; i < allVMs.length; i++) {
const server = allVMs[i];
@@ -376,7 +376,7 @@ export abstract class VMManager {
WHERE pool = $1 and state = 'staging'
RETURNING id, vmid, data, retries
`,
- [this.getPoolName()]
+ [this.getPoolName()],
);
const stagingPromises = rows.map(async (row: any): Promise => {
const rowid = row.id;
@@ -389,7 +389,7 @@ export abstract class VMManager {
'[CHECKSTAGING] %s: [vmid: %s] [attempt: %s] waiting for minRetries',
this.getPoolName(),
vmid,
- retryCount
+ retryCount,
);
}
// Do a minimum # of retries to give reboot time
@@ -399,7 +399,7 @@ export abstract class VMManager {
console.log(
'[CHECKSTAGING] %s: %s poweron, attach to network',
this.getPoolName(),
- vmid
+ vmid,
);
this.powerOn(vmid);
//this.attachToNetwork(vmid);
@@ -434,7 +434,7 @@ export abstract class VMManager {
// Save the VM data
await postgres.query(
`UPDATE vbrowser SET data = $1 WHERE id = $2`,
- [vm, rowid]
+ [vm, rowid],
);
}
}
@@ -442,7 +442,7 @@ export abstract class VMManager {
console.log(
'[CHECKSTAGING] %s: no host for vm %s',
this.getPoolName(),
- vmid
+ vmid,
);
throw new Error('no host for vm ' + vmid);
}
@@ -457,13 +457,13 @@ export abstract class VMManager {
ready,
vmid,
retryCount,
- vm?.host
+ vm?.host,
);
}
if (ready) {
await postgres.query(
`UPDATE vbrowser SET state = 'available' WHERE id = $1`,
- [rowid]
+ [rowid],
);
await redis?.lpush('vBrowserStageRetries', retryCount);
await redis?.ltrim('vBrowserStageRetries', 0, 24);
@@ -489,7 +489,7 @@ export abstract class VMManager {
await this.getCurrentSize(),
await this.getAvailableCount(),
await this.getStagingCount(),
- this.getAdjustedBuffer()
+ this.getAdjustedBuffer(),
);
}, 10000);
@@ -504,7 +504,7 @@ export abstract class VMManager {
console.warn(
'[CLEANUPVMGROUP-ERROR]',
this.getPoolName(),
- e.response?.data
+ e.response?.data,
);
}
console.timeEnd(this.getPoolName() + ':cleanup');
diff --git a/server/vm/digitalocean.ts b/server/vm/digitalocean.ts
index 0b10dd4cc6..9b976bcfdd 100644
--- a/server/vm/digitalocean.ts
+++ b/server/vm/digitalocean.ts
@@ -158,7 +158,7 @@ export class DigitalOcean extends VMManager {
mapServerObject = (server: any): VM => {
const ip = server.networks.v4.find(
- (network: any) => network.type === 'private'
+ (network: any) => network.type === 'private',
)?.ip_address;
return {
id: server.id?.toString(),
diff --git a/server/vm/docker.ts b/server/vm/docker.ts
index 53c4925d89..fb9cd42ed4 100644
--- a/server/vm/docker.ts
+++ b/server/vm/docker.ts
@@ -54,7 +54,7 @@ export class Docker extends VMManager {
UDP_START=$((59000+$INDEX*100))
UDP_END=$((59099+$INDEX*100))
docker run -d --rm --name=${name} --memory="2g" --cpus="2" -p $PORT:$PORT -p $UDP_START-$UDP_END:$UDP_START-$UDP_END/udp -v /etc/letsencrypt:/etc/letsencrypt -l ${tag} -l index=$INDEX --log-opt max-size=1g --shm-size=1g --cap-add="SYS_ADMIN" ${sslEnv} -e DISPLAY=":99.0" -e NEKO_PASSWORD=${name} -e NEKO_PASSWORD_ADMIN=${name} -e NEKO_BIND=":$PORT" -e NEKO_EPR=":$UDP_START-$UDP_END" -e NEKO_H264="1" ${imageName}
- `
+ `,
);
console.log(stdout, stderr);
return stdout.trim();
diff --git a/server/vm/hetzner.ts b/server/vm/hetzner.ts
index d70509842d..5f0e93adcc 100644
--- a/server/vm/hetzner.ts
+++ b/server/vm/hetzner.ts
@@ -116,7 +116,7 @@ export class Hetzner extends VMManager {
console.log(
'[GETVM] %s: %s rate limit remaining',
id,
- response?.headers['ratelimit-remaining']
+ response?.headers['ratelimit-remaining'],
);
redis?.set('hetznerApiRemaining', response?.headers['ratelimit-remaining']);
if (response.data.server.private_net?.length > 1) {
@@ -147,13 +147,13 @@ export class Hetzner extends VMManager {
per_page: 50,
label_selector: filter,
},
- })
- )
+ }),
+ ),
);
const responsesMapped = responses.map((response) =>
response.data.servers
.map(this.mapServerObject)
- .filter((server: VM) => server.tags.includes(this.getTag()))
+ .filter((server: VM) => server.tags.includes(this.getTag())),
);
return responsesMapped.flat();
};
diff --git a/server/vmWorker.ts b/server/vmWorker.ts
index c922414541..75175b3c3e 100644
--- a/server/vmWorker.ts
+++ b/server/vmWorker.ts
@@ -29,7 +29,7 @@ app.post('/assignVM', async (req, res) => {
'assignVM from pool:',
pool.getPoolName(),
req.body.roomId,
- req.body.uid
+ req.body.uid,
);
const vm = await pool.assignVM(req.body.roomId, req.body.uid);
return res.json(vm ?? null);
@@ -93,7 +93,7 @@ app.get('/isFreePoolFull', async (req, res) => {
isFull = Boolean(
limitSize > 0 &&
(Number(availableCount) === 0 ||
- Number(currentSize) - Number(availableCount) > limitSize * 0.95)
+ Number(currentSize) - Number(availableCount) > limitSize * 0.95),
);
}
return res.json({ isFull });
diff --git a/src/components/Announce/Announce.tsx b/src/components/Announce/Announce.tsx
index a6603f0eba..5e9e5c82ef 100644
--- a/src/components/Announce/Announce.tsx
+++ b/src/components/Announce/Announce.tsx
@@ -28,7 +28,7 @@ const Announce = () => {
page: 1,
per_page: 1,
},
- }
+ },
);
const data = response.data;
// console.log(data);
diff --git a/src/components/App/App.tsx b/src/components/App/App.tsx
index 099250979e..064ae36320 100644
--- a/src/components/App/App.tsx
+++ b/src/components/App/App.tsx
@@ -245,9 +245,12 @@ export default class App extends React.Component {
document.onkeydown = this.onKeydown;
// Send heartbeat to the server
- this.heartbeat = window.setInterval(() => {
- window.fetch(serverPath + '/ping');
- }, 10 * 60 * 1000);
+ this.heartbeat = window.setInterval(
+ () => {
+ window.fetch(serverPath + '/ping');
+ },
+ 10 * 60 * 1000,
+ );
const canAutoplay = await testAutoplay();
this.setState({ isAutoPlayable: canAutoplay });
@@ -275,7 +278,7 @@ export default class App extends React.Component {
if (this.props.vanity) {
try {
const response = await axios.get(
- serverPath + '/resolveRoom/' + this.props.vanity
+ serverPath + '/resolveRoom/' + this.props.vanity,
);
if (response.data.roomId) {
roomId = response.data.roomId;
@@ -297,7 +300,7 @@ export default class App extends React.Component {
let password = '';
try {
const savedPasswordsString = window.localStorage.getItem(
- 'watchparty-passwords'
+ 'watchparty-passwords',
);
const savedPasswords = JSON.parse(savedPasswordsString || '{}');
this.setState({ savedPasswords });
@@ -449,7 +452,7 @@ export default class App extends React.Component {
this.playingVBrowser()
) {
console.log(
- 'exiting REC:host since we are using webRTC (fileshare, screenshare, or vbrowser). Check setupRTCConnections()'
+ 'exiting REC:host since we are using webRTC (fileshare, screenshare, or vbrowser). Check setupRTCConnections()',
);
if (!(this.playingVBrowser() && !this.getVBrowserHost())) {
// Remove the loader unless we're waiting for a vbrowser
@@ -459,7 +462,7 @@ export default class App extends React.Component {
}
if (this.usingYoutube() && !this.YouTubeInterface.isReady()) {
console.log(
- 'YT player not ready, onReady callback will retry when it is'
+ 'YT player not ready, onReady callback will retry when it is',
);
return;
}
@@ -510,10 +513,10 @@ export default class App extends React.Component {
// Torrents can contain many files.
const files = torrent.files;
const filtered = files.filter(
- (f: WebTorrent.TorrentFile) => f.length >= 10 * 1024 * 1024
+ (f: WebTorrent.TorrentFile) => f.length >= 10 * 1024 * 1024,
);
const fileIndex = Number(
- new URLSearchParams(src).get('fileIndex')
+ new URLSearchParams(src).get('fileIndex'),
);
// Try to find a single large file to play
const target =
@@ -526,7 +529,7 @@ export default class App extends React.Component {
name: f.name as string,
url: src + `&fileIndex=${i}`,
length: f.length as number,
- }))
+ })),
);
} else {
//@ts-ignore
@@ -534,7 +537,7 @@ export default class App extends React.Component {
leftVideo.currentTime = time;
}
resolve(null);
- }
+ },
);
});
} else if (isHls(src) && window.MediaSource) {
@@ -568,7 +571,7 @@ export default class App extends React.Component {
this.Player().setPlaybackRate(data.playbackRate);
}
},
- { once: true }
+ { once: true },
);
// Progress updater
@@ -577,7 +580,7 @@ export default class App extends React.Component {
if (currentMedia.includes('/stream?torrent=magnet')) {
this.progressUpdater = window.setInterval(async () => {
const response = await window.fetch(
- currentMedia.replace('/stream', '/progress')
+ currentMedia.replace('/stream', '/progress'),
);
const data = await response.json();
this.setState({
@@ -601,7 +604,7 @@ export default class App extends React.Component {
}
}, 1000);
}
- }
+ },
);
});
socket.on('REC:chat', (data: ChatMessage) => {
@@ -625,7 +628,7 @@ export default class App extends React.Component {
socket.on('REC:addReaction', (data: Reaction) => {
const { chat } = this.state;
const msgIndex = chat.findIndex(
- (m) => m.id === data.msgId && m.timestamp === data.msgTimestamp
+ (m) => m.id === data.msgId && m.timestamp === data.msgTimestamp,
);
if (msgIndex === -1) {
return;
@@ -648,13 +651,13 @@ export default class App extends React.Component {
socket.on('REC:removeReaction', (data: Reaction) => {
const { chat } = this.state;
const msg = chat.find(
- (m) => m.id === data.msgId && m.timestamp === data.msgTimestamp
+ (m) => m.id === data.msgId && m.timestamp === data.msgTimestamp,
);
if (!msg || !msg.reactions?.[data.value]) {
return;
}
msg.reactions[data.value] = msg.reactions[data.value].filter(
- (id) => id !== data.user
+ (id) => id !== data.user,
);
this.setState({ chat });
});
@@ -708,7 +711,7 @@ export default class App extends React.Component {
{ participants: data, rosterUpdateTS: Number(new Date()) },
() => {
this.setupRTCConnections();
- }
+ },
);
});
socket.on('chatinit', (data: ChatMessage[]) => {
@@ -749,7 +752,7 @@ export default class App extends React.Component {
// Allow stereo audio
answer.sdp = answer.sdp?.replace(
'useinbandfec=1',
- 'useinbandfec=1; stereo=1; maxaveragebitrate=510000'
+ 'useinbandfec=1; stereo=1; maxaveragebitrate=510000',
);
// console.log(answer.sdp);
// Allow multichannel audio if Chromium
@@ -759,7 +762,7 @@ export default class App extends React.Component {
?.replace('opus/48000/2', 'multiopus/48000/6')
.replace(
'useinbandfec=1',
- 'channel_mapping=0,4,1,2,3,5; num_streams=4; coupled_streams=2;maxaveragebitrate=510000;minptime=10;useinbandfec=1'
+ 'channel_mapping=0,4,1,2,3,5; num_streams=4; coupled_streams=2;maxaveragebitrate=510000;minptime=10;useinbandfec=1',
);
}
await pc.setLocalDescription(answer);
@@ -767,7 +770,7 @@ export default class App extends React.Component {
} else if (msg.sdp && msg.sdp.type === 'answer') {
pc.setRemoteDescription(new RTCSessionDescription(msg.sdp));
}
- }
+ },
);
socket.on('REC:getRoomState', this.handleRoomState);
window.setInterval(() => {
@@ -778,7 +781,7 @@ export default class App extends React.Component {
};
launchMultiSelect = (
- data?: { name: string; url: string; length: number; playFn?: () => void }[]
+ data?: { name: string; url: string; length: number; playFn?: () => void }[],
) => {
this.setState({ multiStreamSelection: data });
};
@@ -1032,7 +1035,7 @@ export default class App extends React.Component {
dtlsParameters,
}: { dtlsParameters: MediasoupClient.types.DtlsParameters },
callback: () => void,
- errback: (error: Error) => void
+ errback: (error: Error) => void,
) => {
console.log('PUBLISH: --transport connect');
sendRequest('connectProducerTransport', {
@@ -1040,7 +1043,7 @@ export default class App extends React.Component {
})
.then(callback)
.catch(errback);
- }
+ },
);
producerTransport.on(
@@ -1054,7 +1057,7 @@ export default class App extends React.Component {
rtpParameters: MediasoupClient.types.RtpParameters;
},
callback: ({ id }: { id: string }) => void,
- errback: (error: Error) => void
+ errback: (error: Error) => void,
) => {
console.log('PUBLISH: --transport produce');
try {
@@ -1067,7 +1070,7 @@ export default class App extends React.Component {
} catch (err: any) {
errback(err);
}
- }
+ },
);
// producerTransport.on('connectionstatechange', (state: string) => {
@@ -1103,7 +1106,7 @@ export default class App extends React.Component {
}
async function loadDevice(
- routerRtpCapabilities: MediasoupClient.types.RtpCapabilities
+ routerRtpCapabilities: MediasoupClient.types.RtpCapabilities,
) {
const { Device } = await import('mediasoup-client');
device = new Device();
@@ -1223,7 +1226,7 @@ export default class App extends React.Component {
}
async function loadDevice(
- routerRtpCapabilities: MediasoupClient.types.RtpCapabilities
+ routerRtpCapabilities: MediasoupClient.types.RtpCapabilities,
) {
try {
const { Device } = await import('mediasoup-client');
@@ -1238,7 +1241,7 @@ export default class App extends React.Component {
async function consume(
transport: MediasoupClient.types.Transport,
- trackKind: string
+ trackKind: string,
) {
console.log('SUBSCRIBE: --start of consume --kind=' + trackKind);
const { rtpCapabilities } = device;
@@ -1285,7 +1288,7 @@ export default class App extends React.Component {
dtlsParameters,
}: { dtlsParameters: MediasoupClient.types.DtlsParameters },
callback: () => void,
- errback: (err: Error) => void
+ errback: (err: Error) => void,
) => {
console.log('SUBSCRIBE: ---consumer transport connect');
sendRequest('connectConsumerTransport', {
@@ -1293,7 +1296,7 @@ export default class App extends React.Component {
})
.then(callback)
.catch(errback);
- }
+ },
);
// consumerTransport.on('connectionstatechange', (state: string) => {
@@ -1566,7 +1569,7 @@ export default class App extends React.Component {
this.setState({ loading: false, nonPlayableMedia: true });
}
}
- }
+ },
);
};
@@ -1803,7 +1806,7 @@ export default class App extends React.Component {
const nextNum = Number(fileIndex) + 1;
const nextUrl = this.state.roomMedia.replace(
/&fileIndex=(\d+)$/,
- `&fileIndex=${nextNum}`
+ `&fileIndex=${nextNum}`,
);
this.roomSetMedia(null, { value: nextUrl });
}
@@ -1916,7 +1919,7 @@ export default class App extends React.Component {
circular
color={
getColorForString(
- this.state.participants.length.toString()
+ this.state.participants.length.toString(),
) as SemanticCOLORS
}
>
@@ -2438,7 +2441,7 @@ export default class App extends React.Component {
> */}
{Math.min(
(this.state.downloaded / this.state.total) * 100,
- 100
+ 100,
).toFixed(2) +
'% - ' +
formatSpeed(this.state.speed) +
diff --git a/src/components/Chat/Chat.tsx b/src/components/Chat/Chat.tsx
index 6239c3b100..b95a153a4d 100644
--- a/src/components/Chat/Chat.tsx
+++ b/src/components/Chat/Chat.tsx
@@ -82,7 +82,7 @@ export class Chat extends React.Component {
selectedMsgId?: string,
selectedMsgTimestamp?: string,
yPosition?: number,
- xPosition?: number
+ xPosition?: number,
) => {
this.setState({
reactionMenu: {
@@ -97,7 +97,7 @@ export class Chat extends React.Component {
handleReactionClick = (value: string, id?: string, timestamp?: string) => {
const msg = this.props.chat.find(
- (m) => m.id === id && m.timestamp === timestamp
+ (m) => m.id === id && m.timestamp === timestamp,
);
const data = {
value,
@@ -294,7 +294,7 @@ export class Chat extends React.Component {
position: 'fixed',
top: Math.min(
this.state.reactionMenu.yPosition - 150,
- window.innerHeight - 450
+ window.innerHeight - 450,
),
left: this.state.reactionMenu.xPosition - 240,
}}
@@ -385,7 +385,7 @@ const ChatMessage = ({
selectedMsgId?: string,
selectedMsgTimestamp?: string,
yPosition?: number,
- xPosition?: number
+ xPosition?: number,
) => void;
handleReactionClick: (value: string, id?: string, timestamp?: string) => void;
className: string;
@@ -440,7 +440,7 @@ const ChatMessage = ({
componentDecorator={(
decoratedHref: string,
decoratedText: string,
- key: string
+ key: string,
) => (
{decoratedText}
@@ -465,7 +465,7 @@ const ChatMessage = ({
id,
timestamp,
viewportOffset.top,
- viewportOffset.right
+ viewportOffset.right,
);
}, 100);
}}
@@ -512,11 +512,11 @@ const ChatMessage = ({
.concat(
reactions[key].length > spellFull
? [`${reactions[key].length - spellFull} more`]
- : []
+ : [],
)
.reduce(
(text, value, i, array) =>
- text + (i < array.length - 1 ? ', ' : ' and ') + value
+ text + (i < array.length - 1 ? ', ' : ' and ') + value,
)} reacted.`}
offset={[0, 6]}
trigger={
@@ -569,7 +569,7 @@ const ChatMessage = ({
}
/>
- ) : null
+ ) : null,
)}
diff --git a/src/components/ComboBox/ComboBox.tsx b/src/components/ComboBox/ComboBox.tsx
index 93c6e51ec0..b8600fb970 100644
--- a/src/components/ComboBox/ComboBox.tsx
+++ b/src/components/ComboBox/ComboBox.tsx
@@ -43,7 +43,7 @@ export class ComboBox extends React.Component {
setMediaAndClose = (e: any, data: DropdownProps) => {
window.setTimeout(
() => this.setState({ inputMedia: undefined, results: undefined }),
- 200
+ 200,
);
this.props.roomSetMedia(e, data);
};
@@ -161,7 +161,7 @@ export class ComboBox extends React.Component {
) {
this.doSearch(e);
}
- }
+ },
);
setTimeout(() => e.target.select(), 100);
}}
@@ -172,7 +172,7 @@ export class ComboBox extends React.Component {
inputMedia: undefined,
results: undefined,
}),
- 200
+ 200,
);
}}
onKeyPress={(e: any) => {
diff --git a/src/components/Controls/Controls.tsx b/src/components/Controls/Controls.tsx
index f18cb5413c..143917f579 100644
--- a/src/components/Controls/Controls.tsx
+++ b/src/components/Controls/Controls.tsx
@@ -277,7 +277,7 @@ export class Controls extends React.Component {
onClick={() =>
this.props.localSetSubtitleMode(
item.value as TextTrackMode,
- item.key
+ item.key,
)
}
/>
diff --git a/src/components/Create/Create.tsx b/src/components/Create/Create.tsx
index 0f07db8cfb..723499df9d 100644
--- a/src/components/Create/Create.tsx
+++ b/src/components/Create/Create.tsx
@@ -20,7 +20,7 @@ export const Create = () => {
user,
false,
new URLSearchParams(window.location.search).get('video') ??
- undefined
+ undefined,
);
}}
/>
diff --git a/src/components/Debug/Debug.tsx b/src/components/Debug/Debug.tsx
index aa4273c4c1..c67d0f51b6 100644
--- a/src/components/Debug/Debug.tsx
+++ b/src/components/Debug/Debug.tsx
@@ -23,7 +23,7 @@ const Debug = () => {
json.reverse();
setData(json);
}) as any,
- [setData]
+ [setData],
);
// Get the keys from the last/mostrecent element
const keys = Object.keys(data.slice(-1)[0] ?? {});
diff --git a/src/components/Modal/PasswordModal.tsx b/src/components/Modal/PasswordModal.tsx
index 4f99560bf1..5cabc41f2a 100644
--- a/src/components/Modal/PasswordModal.tsx
+++ b/src/components/Modal/PasswordModal.tsx
@@ -15,7 +15,7 @@ export const PasswordModal = ({
...savedPasswords,
[roomId]: (document.getElementById('roomPassword') as HTMLInputElement)
?.value,
- })
+ }),
);
window.location.reload();
}, [savedPasswords, roomId]);
diff --git a/src/components/Modal/ProfileModal.tsx b/src/components/Modal/ProfileModal.tsx
index 2b894f74a1..d69f06a59f 100644
--- a/src/components/Modal/ProfileModal.tsx
+++ b/src/components/Modal/ProfileModal.tsx
@@ -30,7 +30,7 @@ export class ProfileModal extends React.Component<{
uid: this.context.user?.uid,
token,
},
- }
+ },
);
const data = response.data;
const linkedDiscord = data.find((d) => d.kind === 'discord');
@@ -82,12 +82,12 @@ export class ProfileModal extends React.Component<{
authDiscord = () => {
const url = `https://discord.com/api/oauth2/authorize?client_id=1071707916719095908&redirect_uri=${encodeURIComponent(
- config.VITE_OAUTH_REDIRECT_HOSTNAME
+ config.VITE_OAUTH_REDIRECT_HOSTNAME,
)}%2Fdiscord%2Fauth&response_type=token&scope=identify`;
window.open(
url,
'_blank',
- 'toolbar=0,location=0,menubar=0,width=450,height=900'
+ 'toolbar=0,location=0,menubar=0,width=450,height=900',
);
};
diff --git a/src/components/Modal/SubtitleModal.tsx b/src/components/Modal/SubtitleModal.tsx
index 61a45580bb..15491bd43e 100644
--- a/src/components/Modal/SubtitleModal.tsx
+++ b/src/components/Modal/SubtitleModal.tsx
@@ -43,7 +43,7 @@ export class SubtitleModal extends React.Component<{
if (fileIndex) {
// Fetch title from the data endpoint
const response = await fetch(
- this.props.roomMedia.replace('/stream', '/data')
+ this.props.roomMedia.replace('/stream', '/data'),
);
const data = await response.json();
this.setState({ titleQuery: data?.files[fileIndex]?.name });
@@ -71,7 +71,7 @@ export class SubtitleModal extends React.Component<{
const json = await resp.json();
this.props.socket.emit(
'CMD:subtitle',
- serverPath + '/subtitle/' + json.hash
+ serverPath + '/subtitle/' + json.hash,
);
});
reader.readAsText(file);
@@ -121,8 +121,8 @@ export class SubtitleModal extends React.Component<{
checked={Boolean(
this.props.roomSubtitle &&
this.props.roomSubtitle?.startsWith(
- this.props.roomMedia
- )
+ this.props.roomMedia,
+ ),
)}
onClick={(e, data) => {
const subValue = this.props.roomMedia + '.srt';
@@ -140,7 +140,7 @@ export class SubtitleModal extends React.Component<{
checked={
Boolean(this.props.roomSubtitle) &&
this.props.roomSubtitle?.startsWith(
- serverPath + '/subtitle'
+ serverPath + '/subtitle',
)
}
/>
@@ -165,7 +165,7 @@ export class SubtitleModal extends React.Component<{
checked={
Boolean(this.props.roomSubtitle) &&
this.props.roomSubtitle?.startsWith(
- serverPath + '/downloadSubtitle'
+ serverPath + '/downloadSubtitle',
)
}
/>
@@ -190,7 +190,7 @@ export class SubtitleModal extends React.Component<{
const resp = await window.fetch(
serverPath +
'/searchSubtitles?title=' +
- this.state.titleQuery
+ this.state.titleQuery,
);
const json = await resp.json();
this.setState({ searchResults: json });
@@ -214,7 +214,7 @@ export class SubtitleModal extends React.Component<{
const resp = await window.fetch(
serverPath +
'/searchSubtitles?url=' +
- this.props.roomMedia
+ this.props.roomMedia,
);
const json = await resp.json();
this.setState({ searchResults: json });
@@ -235,12 +235,12 @@ export class SubtitleModal extends React.Component<{
name="radioGroup"
value={result.SubDownloadLink}
checked={this.props.roomSubtitle?.includes(
- result.SubDownloadLink
+ result.SubDownloadLink,
)}
onChange={(e, { value }) => {
this.props.socket.emit(
'CMD:subtitle',
- serverPath + '/downloadSubtitles?url=' + value
+ serverPath + '/downloadSubtitles?url=' + value,
);
}}
/>
diff --git a/src/components/Modal/VBrowserModal.tsx b/src/components/Modal/VBrowserModal.tsx
index 48ad674c64..fbbf6caf2e 100644
--- a/src/components/Modal/VBrowserModal.tsx
+++ b/src/components/Modal/VBrowserModal.tsx
@@ -15,7 +15,7 @@ export class VBrowserModal extends React.Component<{
closeModal: () => void;
startVBrowser: (
rcToken: string,
- options: { size: string; region: string }
+ options: { size: string; region: string },
) => void;
}> {
static contextType = MetadataContext;
diff --git a/src/components/Playlist/ChatVideoCard.tsx b/src/components/Playlist/ChatVideoCard.tsx
index a249c94a0e..6f456c3eff 100644
--- a/src/components/Playlist/ChatVideoCard.tsx
+++ b/src/components/Playlist/ChatVideoCard.tsx
@@ -33,7 +33,7 @@ const ChatVideoCard: React.FC<{
onPlay(index);
}
},
- [onPlay, index]
+ [onPlay, index],
);
const handlePlayNextClick = React.useCallback(
@@ -44,7 +44,7 @@ const ChatVideoCard: React.FC<{
onPlayNext(index);
}
},
- [onPlayNext, index]
+ [onPlayNext, index],
);
const handleRemoveClick = React.useCallback(
@@ -55,7 +55,7 @@ const ChatVideoCard: React.FC<{
onRemove(index);
}
},
- [onRemove, index]
+ [onRemove, index],
);
const Element = 'div';
diff --git a/src/components/SearchComponent/SearchComponent.tsx b/src/components/SearchComponent/SearchComponent.tsx
index d3e8b45f87..fbd3170d37 100644
--- a/src/components/SearchComponent/SearchComponent.tsx
+++ b/src/components/SearchComponent/SearchComponent.tsx
@@ -41,7 +41,7 @@ export class SearchComponent extends React.Component {
} else if (this.props.type === 'stream' && this.context.streamPath) {
results = await getStreamPathResults(
this.context.streamPath,
- query
+ query,
);
}
if (timestamp > this.state.lastResultTimestamp) {
@@ -60,7 +60,7 @@ export class SearchComponent extends React.Component {
setMedia = (e: any, data: DropdownProps) => {
window.setTimeout(
() => this.setState({ resetDropdown: Number(new Date()) }),
- 300
+ 300,
);
this.props.setMedia(e, data);
};
diff --git a/src/components/SearchResult/SearchResult.tsx b/src/components/SearchResult/SearchResult.tsx
index e6a1a88327..e309e95062 100644
--- a/src/components/SearchResult/SearchResult.tsx
+++ b/src/components/SearchResult/SearchResult.tsx
@@ -7,7 +7,7 @@ export const YouTubeSearchResult = (
props: SearchResult & {
setMedia: (_e: any, data: DropdownProps) => void;
playlistAdd: (_e: any, data: DropdownProps) => void;
- }
+ },
) => {
const result = props;
const setMedia = props.setMedia;
@@ -38,7 +38,7 @@ export const YouTubeSearchResult = (
};
export const MediaPathSearchResult = (
- props: SearchResult & { setMedia: (_e: any, data: DropdownProps) => void }
+ props: SearchResult & { setMedia: (_e: any, data: DropdownProps) => void },
) => {
const result = props;
const setMedia = props.setMedia;
@@ -77,13 +77,13 @@ export class StreamPathSearchResult extends React.Component<
let response = await window.fetch(
this.context.streamPath +
'/data?torrent=' +
- encodeURIComponent(result.magnet!)
+ encodeURIComponent(result.magnet!),
);
let metadata = await response.json();
// console.log(metadata);
if (
metadata.files.filter(
- (file: any) => file.length > 10 * 1024 * 1024
+ (file: any) => file.length > 10 * 1024 * 1024,
).length > 1
) {
// Multiple large files, present user selection
@@ -96,7 +96,7 @@ export class StreamPathSearchResult extends React.Component<
encodeURIComponent(result.magnet!) +
'&fileIndex=' +
i,
- })
+ }),
);
// multiStreamSelection.sort((a: any, b: any) =>
// a.name.localeCompare(b.name)
diff --git a/src/components/Settings/LocalSettings.tsx b/src/components/Settings/LocalSettings.tsx
index 7ee6cf5684..89d74be707 100644
--- a/src/components/Settings/LocalSettings.tsx
+++ b/src/components/Settings/LocalSettings.tsx
@@ -18,7 +18,7 @@ export const SettingsModal = ({ trigger }: any) => (
inverted
onClick={() => {
const newSetting = (document.getElementById(
- 'settings_textarea'
+ 'settings_textarea',
) as HTMLTextAreaElement)!.value;
try {
validateSettingsString(newSetting);
@@ -58,7 +58,7 @@ export function getCurrentSettings(): Settings {
* Validate a setting string. Return a parsed setting object if valid, otherwise throw exception
*/
export function validateSettingsString(
- setting: string | null
+ setting: string | null,
): Settings | null {
if (!setting) {
return {};
diff --git a/src/components/Settings/SettingsTab.tsx b/src/components/Settings/SettingsTab.tsx
index b61aebfe36..5ebfc2cd61 100644
--- a/src/components/Settings/SettingsTab.tsx
+++ b/src/components/Settings/SettingsTab.tsx
@@ -78,7 +78,7 @@ export const SettingsTab = ({
const [validVanityLoading, setValidVanityLoading] = useState(false);
const [adminSettingsChanged, setAdminSettingsChanged] = useState(false);
const [roomTitleInput, setRoomTitleInput] = useState(
- undefined
+ undefined,
);
const [roomDescriptionInput, setRoomDescriptionInput] = useState<
string | undefined
@@ -96,7 +96,7 @@ export const SettingsTab = ({
...data,
});
},
- [socket, user]
+ [socket, user],
);
const setRoomOwner = useCallback(
async (data: any) => {
@@ -107,7 +107,7 @@ export const SettingsTab = ({
...data,
});
},
- [socket, user]
+ [socket, user],
);
const checkValidVanity = useCallback(
async (input: string) => {
@@ -131,7 +131,7 @@ export const SettingsTab = ({
setValidVanity(true);
}
},
- [setValidVanity, roomLink]
+ [setValidVanity, roomLink],
);
const disableLocking =
!Boolean(user) || Boolean(roomLock && roomLock !== user?.uid);
@@ -423,7 +423,7 @@ export const SettingsTab = ({
JSON.stringify({
...getCurrentSettings(),
disableChatSound: data.checked,
- })
+ }),
);
setUpdateTS(Number(new Date()));
}}
diff --git a/src/components/TopBar/TopBar.tsx b/src/components/TopBar/TopBar.tsx
index c67d30f59c..b1982b0ba5 100644
--- a/src/components/TopBar/TopBar.tsx
+++ b/src/components/TopBar/TopBar.tsx
@@ -22,7 +22,7 @@ import { MetadataContext } from '../../MetadataContext';
export async function createRoom(
user: firebase.User | undefined,
openNewTab: boolean | undefined,
- video: string = ''
+ video: string = '',
) {
const uid = user?.uid;
const token = await user?.getIdToken();
@@ -191,7 +191,7 @@ export class ListRoomsButton extends React.Component<{}> {
if (this.context.user) {
const token = await this.context.user.getIdToken();
const response = await axios.get(
- serverPath + `/listRooms?uid=${this.context.user?.uid}&token=${token}`
+ serverPath + `/listRooms?uid=${this.context.user?.uid}&token=${token}`,
);
this.setState({ rooms: response.data });
}
@@ -202,7 +202,7 @@ export class ListRoomsButton extends React.Component<{}> {
const token = await this.context.user.getIdToken();
await axios.delete(
serverPath +
- `/deleteRoom?uid=${this.context.user?.uid}&token=${token}&roomId=${roomId}`
+ `/deleteRoom?uid=${this.context.user?.uid}&token=${token}&roomId=${roomId}`,
);
this.setState({
rooms: this.state.rooms.filter((room) => room.roomId !== roomId),
diff --git a/src/components/VBrowser/VBrowser.tsx b/src/components/VBrowser/VBrowser.tsx
index 9488a566f0..f67b92f065 100644
--- a/src/components/VBrowser/VBrowser.tsx
+++ b/src/components/VBrowser/VBrowser.tsx
@@ -41,7 +41,7 @@ export default class VBrowser extends React.Component<{
this.controlling = this.props.controlling;
this.keepAliveInterval = window.setInterval(
() => this.$client.sendMessage('chat/message'),
- 30000
+ 30000,
);
this.$client.on(EVENT.CONNECTED, () => {
@@ -67,7 +67,7 @@ export default class VBrowser extends React.Component<{
// Manually play audio for iPhone Safari since this seems to create two separate streams
if (stream.getTracks().length === 1 && track.kind === 'audio') {
const audio = document.getElementById(
- 'iPhoneAudio'
+ 'iPhoneAudio',
) as HTMLAudioElement;
audio.srcObject = new MediaStream([track]);
audio.play();
diff --git a/src/components/VBrowser/base.ts b/src/components/VBrowser/base.ts
index 6e6779829a..9fff25b0c0 100644
--- a/src/components/VBrowser/base.ts
+++ b/src/components/VBrowser/base.ts
@@ -64,7 +64,9 @@ export abstract class BaseClient extends EventEmitter {
if (!this.supported) {
this.onDisconnected(
- new Error('browser does not support webrtc (RTCPeerConnection missing)')
+ new Error(
+ 'browser does not support webrtc (RTCPeerConnection missing)',
+ ),
);
return;
}
@@ -74,7 +76,7 @@ export abstract class BaseClient extends EventEmitter {
try {
this._ws = new WebSocket(
- `${url}?password=${encodeURIComponent(password)}`
+ `${url}?password=${encodeURIComponent(password)}`,
);
this.emit('debug', `connecting to ${this._ws.url}`);
this._ws.onmessage = this.onMessage.bind(this);
@@ -140,11 +142,11 @@ export abstract class BaseClient extends EventEmitter {
public sendData(
event: 'wheel' | 'mousemove',
- data: { x: number; y: number }
+ data: { x: number; y: number },
): void;
public sendData(
event: 'mousedown' | 'mouseup' | 'keydown' | 'keyup',
- data: { key: number }
+ data: { key: number },
): void;
public sendData(event: string, data: any) {
if (!this.connected) {
@@ -205,7 +207,7 @@ export abstract class BaseClient extends EventEmitter {
this.emit(
'debug',
`sending event '${event}' ${payload ? `with payload: ` : ''}`,
- payload
+ payload,
);
this._ws!.send(JSON.stringify({ event, ...payload }));
}
@@ -216,7 +218,7 @@ export abstract class BaseClient extends EventEmitter {
this.emit(
'warn',
`attempting to create peer with no websocket: `,
- this._ws ? `state: ${this._ws.readyState}` : 'no socket'
+ this._ws ? `state: ${this._ws.readyState}` : 'no socket',
);
return;
}
@@ -238,7 +240,7 @@ export abstract class BaseClient extends EventEmitter {
this.emit(
'debug',
`peer connection state changed`,
- this._peer ? this._peer.connectionState : undefined
+ this._peer ? this._peer.connectionState : undefined,
);
};
@@ -246,7 +248,7 @@ export abstract class BaseClient extends EventEmitter {
this.emit(
'debug',
`peer signaling state changed`,
- this._peer ? this._peer.signalingState : undefined
+ this._peer ? this._peer.signalingState : undefined,
);
};
@@ -255,7 +257,7 @@ export abstract class BaseClient extends EventEmitter {
this.emit(
'debug',
- `peer ice connection state changed: ${this._peer!.iceConnectionState}`
+ `peer ice connection state changed: ${this._peer!.iceConnectionState}`,
);
switch (this._state) {
@@ -299,7 +301,7 @@ export abstract class BaseClient extends EventEmitter {
JSON.stringify({
event: EVENT.SIGNAL.CANDIDATE,
data: JSON.stringify(init),
- })
+ }),
);
};
@@ -313,7 +315,7 @@ export abstract class BaseClient extends EventEmitter {
JSON.stringify({
event: EVENT.SIGNAL.OFFER,
sdp: d.sdp,
- })
+ }),
);
};
@@ -322,7 +324,7 @@ export abstract class BaseClient extends EventEmitter {
this._channel.onmessage = this.onData.bind(this);
this._channel.onclose = this.onDisconnected.bind(
this,
- new Error('peer data channel closed')
+ new Error('peer data channel closed'),
);
}
@@ -345,7 +347,7 @@ export abstract class BaseClient extends EventEmitter {
// add stereo=1 to answer sdp to enable stereo audio for chromium
d.sdp = d.sdp?.replace(
/(stereo=1;)?useinbandfec=1/,
- 'useinbandfec=1;stereo=1'
+ 'useinbandfec=1;stereo=1',
);
this._peer!.setLocalDescription(d);
@@ -355,7 +357,7 @@ export abstract class BaseClient extends EventEmitter {
event: EVENT.SIGNAL.ANSWER,
sdp: d.sdp,
displayname: this._displayname,
- })
+ }),
);
} catch (err: any) {
this.emit('error', err);
@@ -377,7 +379,7 @@ export abstract class BaseClient extends EventEmitter {
this.emit(
'debug',
`received websocket event ${event} ${payload ? `with payload: ` : ''}`,
- payload
+ payload,
);
if (event === EVENT.SIGNAL.PROVIDE) {
@@ -428,13 +430,13 @@ export abstract class BaseClient extends EventEmitter {
this.emit(
'debug',
`received ${event.track.kind} track from peer: ${event.track.id}`,
- event
+ event,
);
const stream = event.streams[0];
if (!stream) {
this.emit(
'warn',
- `no stream provided for track ${event.track.id}(${event.track.label})`
+ `no stream provided for track ${event.track.id}(${event.track.label})`,
);
return;
}
diff --git a/src/components/VBrowser/guacamole-keyboard.js b/src/components/VBrowser/guacamole-keyboard.js
index 8d91702d68..ab8b9120f8 100644
--- a/src/components/VBrowser/guacamole-keyboard.js
+++ b/src/components/VBrowser/guacamole-keyboard.js
@@ -279,7 +279,7 @@ Guacamole.Keyboard = function Keyboard(element) {
this.keysym = keysym_from_key_identifier(
this.keyIdentifier,
this.location,
- this.modifiers.shift
+ this.modifiers.shift,
);
// If a key is pressed while meta is held down, the keyup will
@@ -753,7 +753,7 @@ Guacamole.Keyboard = function Keyboard(element) {
*/
var key_identifier_sane = function key_identifier_sane(
keyCode,
- keyIdentifier
+ keyIdentifier,
) {
// Missing identifier is not sane
if (!keyIdentifier) return false;
@@ -766,7 +766,7 @@ Guacamole.Keyboard = function Keyboard(element) {
// then the identifier is likely correct
var codepoint = parseInt(
keyIdentifier.substring(unicodePrefixLocation + 2),
- 16
+ 16,
);
if (keyCode !== codepoint) return true;
@@ -903,7 +903,7 @@ Guacamole.Keyboard = function Keyboard(element) {
var updateModifierState = function updateModifierState(
modifier,
keysyms,
- keyEvent
+ keyEvent,
) {
var localState = keyEvent.modifiers[modifier];
var remoteState = guac_keyboard.modifiers[modifier];
@@ -963,7 +963,7 @@ Guacamole.Keyboard = function Keyboard(element) {
0xffea, // Right alt
0xfe03, // AltGr
],
- keyEvent
+ keyEvent,
);
// Resync state of shift
@@ -973,7 +973,7 @@ Guacamole.Keyboard = function Keyboard(element) {
0xffe1, // Left shift
0xffe2, // Right shift
],
- keyEvent
+ keyEvent,
);
// Resync state of ctrl
@@ -983,7 +983,7 @@ Guacamole.Keyboard = function Keyboard(element) {
0xffe3, // Left ctrl
0xffe4, // Right ctrl
],
- keyEvent
+ keyEvent,
);
// Resync state of meta
@@ -993,7 +993,7 @@ Guacamole.Keyboard = function Keyboard(element) {
0xffe7, // Left meta
0xffe8, // Right meta
],
- keyEvent
+ keyEvent,
);
// Resync state of hyper
@@ -1003,7 +1003,7 @@ Guacamole.Keyboard = function Keyboard(element) {
0xffeb, // Left super/hyper
0xffec, // Right super/hyper
],
- keyEvent
+ keyEvent,
);
// Update state
@@ -1272,7 +1272,7 @@ Guacamole.Keyboard = function Keyboard(element) {
// Interpret as many events as possible, prevent default if indicated
if (interpret_events()) e.preventDefault();
},
- true
+ true,
);
// When key pressed
@@ -1291,7 +1291,7 @@ Guacamole.Keyboard = function Keyboard(element) {
// Interpret as many events as possible, prevent default if indicated
if (interpret_events()) e.preventDefault();
},
- true
+ true,
);
// When key released
@@ -1310,7 +1310,7 @@ Guacamole.Keyboard = function Keyboard(element) {
eventLog.push(new KeyupEvent(e));
interpret_events();
},
- true
+ true,
);
// NEKO: Do not automatically type text entered into the wrapped field
diff --git a/src/components/VideoChat/VideoChat.tsx b/src/components/VideoChat/VideoChat.tsx
index 161ef4448c..700729f10b 100644
--- a/src/components/VideoChat/VideoChat.tsx
+++ b/src/components/VideoChat/VideoChat.tsx
@@ -168,7 +168,7 @@ export class VideoChat extends React.Component {
const clientIds = new Set(
this.props.participants
.filter((p) => p.isVideoChat)
- .map((p) => p.clientId)
+ .map((p) => p.clientId),
);
Object.entries(videoPCs).forEach(([key, value]) => {
if (!clientIds.has(key)) {
@@ -359,7 +359,7 @@ export class VideoChat extends React.Component {
cursor: 'pointer',
opacity: 0.75,
visibility: Boolean(
- owner && owner === this.context.user?.uid
+ owner && owner === this.context.user?.uid,
)
? 'visible'
: 'hidden',
@@ -393,7 +393,7 @@ export class VideoChat extends React.Component {
pictureMap[p.id] ||
getDefaultPicture(
nameMap[p.id],
- getColorForStringHex(p.id)
+ getColorForStringHex(p.id),
)
}
alt=""
diff --git a/src/index.tsx b/src/index.tsx
index 55fc664e13..2c8de207f4 100644
--- a/src/index.tsx
+++ b/src/index.tsx
@@ -41,7 +41,7 @@ class WatchParty extends React.Component {
this.setState({ user });
const token = await user.getIdToken();
const response = await window.fetch(
- serverPath + `/metadata?uid=${user.uid}&token=${token}`
+ serverPath + `/metadata?uid=${user.uid}&token=${token}`,
);
const data = await response.json();
this.setState({
diff --git a/src/utils/index.ts b/src/utils/index.ts
index 2efcfe664c..12621ae2e9 100644
--- a/src/utils/index.ts
+++ b/src/utils/index.ts
@@ -248,7 +248,7 @@ export const serverPath =
export async function getMediaPathResults(
mediaPath: string,
- query: string
+ query: string,
): Promise {
const response = await window.fetch(mediaPath);
let results: SearchResult[] = [];
@@ -259,7 +259,7 @@ export async function getMediaPathResults(
const data = parser.parse(xml);
let filtered = data.ListBucketResult.Contents.filter(
// Exclude subdirectories
- (file: any) => !file.Key.includes('/')
+ (file: any) => !file.Key.includes('/'),
);
results = filtered.map((file: any) => ({
url: mediaPath + '/' + file.Key,
@@ -279,27 +279,27 @@ export async function getMediaPathResults(
(option: SearchResult) =>
// Exclude subtitles
!option.url.endsWith('.srt') &&
- option.name.toLowerCase().includes(query.toLowerCase())
+ option.name.toLowerCase().includes(query.toLowerCase()),
);
return results;
}
export async function getStreamPathResults(
streamPath: string,
- query: string
+ query: string,
): Promise {
const response = await window.fetch(
- streamPath + `/${query ? 'search' : 'top'}?q=` + encodeURIComponent(query)
+ streamPath + `/${query ? 'search' : 'top'}?q=` + encodeURIComponent(query),
);
const data = await response.json();
return data;
}
export async function getYouTubeResults(
- query: string
+ query: string,
): Promise {
const response = await window.fetch(
- serverPath + '/youtube?q=' + encodeURIComponent(query)
+ serverPath + '/youtube?q=' + encodeURIComponent(query),
);
const data = await response.json();
return data.map((d: any) => ({ ...d, type: 'youtube' }));
@@ -362,7 +362,7 @@ export function calculateMedian(array: number[]): number {
}
export async function getUserImage(
- user: firebase.User
+ user: firebase.User,
): Promise {
// Check if user has a Gravatar
const hash = user.email ? MD5.hash(user.email) : '';
@@ -385,6 +385,6 @@ export const getFileName = (input: string) => {
export const isEmojiString = (input: string): boolean => {
return /^(\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])+$/g.test(
- input
+ input,
);
};
diff --git a/src/utils/md5.ts b/src/utils/md5.ts
index f2a2a38f4e..e30e0a1a44 100644
--- a/src/utils/md5.ts
+++ b/src/utils/md5.ts
@@ -124,7 +124,7 @@ export class MD5 {
b: number,
x: number,
s: number,
- t: number
+ t: number,
): number {
return MD5.ad(MD5.rl(MD5.ad(MD5.ad(a, q), MD5.ad(x, t)), s), b);
}
@@ -136,7 +136,7 @@ export class MD5 {
d: number,
x: number,
s: number,
- t: number
+ t: number,
): number {
return MD5.cm((b & c) | (~b & d), a, b, x, s, t);
}
@@ -148,7 +148,7 @@ export class MD5 {
d: number,
x: number,
s: number,
- t: number
+ t: number,
): number {
return MD5.cm((b & d) | (c & ~d), a, b, x, s, t);
}
@@ -160,7 +160,7 @@ export class MD5 {
d: number,
x: number,
s: number,
- t: number
+ t: number,
): number {
return MD5.cm(b ^ c ^ d, a, b, x, s, t);
}
@@ -172,7 +172,7 @@ export class MD5 {
d: number,
x: number,
s: number,
- t: number
+ t: number,
): number {
return MD5.cm(c ^ (b | ~d), a, b, x, s, t);
}
diff --git a/tsconfig.json b/tsconfig.json
index f9bf4285a8..b202f6b240 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -15,12 +15,12 @@
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
- "types": ["vite/client", "youtube"]
+ "types": ["vite/client", "youtube"],
},
"include": ["src", "global.d.ts"],
"ts-node": {
"compilerOptions": {
- "module": "commonjs"
- }
- }
+ "module": "commonjs",
+ },
+ },
}