🔖 Release version 1.9.0 (#112)

* ⬆️ Bump version number to 1.9.0

* ⬆️ Upgrade dependencies

*  Add #95

* Add permission to use player and embed links

* Update package-lock.json

---------

Co-authored-by: UnderAndOver <18629496+UnderAndOver@users.noreply.github.com>

*  Add #82

*  New popup (#110)

* 🚧 WIP

* 🚧 WIP

* 🔧 Improve defaults for the update check

* 🚧 WIP

* 🚧 WIP

* 🚧 Done remake of Whitelist button

* 🐛 Fix stream status display style

* 🐛 Fix proxy country not showing after unallowlisted

*  Done

* 🐛 Limit player resets to 3 per 15 seconds (#111)

*  Add #78

* 🐛 Fix timestamps

* ⬆️ Upgrade dependencies

* 💄 Cleanup styles

* 💬 Make stream status reason friendlier

* 🩹 Temporary patch for Firefox Nightly

*  Cleanup

* 📝 Update README.md

---------

Co-authored-by: UnderAndOver <18629496+UnderAndOver@users.noreply.github.com>
This commit is contained in:
Younes Aassila 2023-04-06 15:42:11 +02:00 committed by GitHub
parent 9ac83fbe78
commit eb34f3b3de
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 714 additions and 446 deletions

View File

@ -59,8 +59,9 @@ This fork:
<div align="center">
<img
src="https://user-images.githubusercontent.com/47226184/210093901-2d0c7f62-5e1f-4ce2-83f3-e35812361e20.png"
src="https://user-images.githubusercontent.com/47226184/230387477-fa47fc75-69d5-42d2-b3ea-fb4e8f513035.png"
alt="Popup on Firefox"
height="450"
/>
</div>

300
package-lock.json generated
View File

@ -1,25 +1,25 @@
{
"name": "ttv-lol-pro",
"version": "1.8.1",
"version": "1.9.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "ttv-lol-pro",
"version": "1.8.1",
"version": "1.9.0",
"license": "GPL-3.0",
"dependencies": {
"semver-compare": "^1.0.0"
},
"devDependencies": {
"@parcel/config-webextension": "^2.8.3",
"@types/react": "^18.0.28",
"@types/react": "^18.0.33",
"@types/semver-compare": "^1.0.1",
"@types/webextension-polyfill": "^0.10.0",
"amazon-ivs-player": "^1.16.0",
"amazon-ivs-player": "^1.18.0",
"parcel": "^2.8.3",
"postcss": "^8.4.21",
"prettier": "^2.8.4",
"prettier": "^2.8.7",
"prettier-plugin-css-order": "^1.3.0",
"prettier-plugin-organize-imports": "^3.2.2",
"typescript": "^4.9.5",
@ -27,9 +27,9 @@
}
},
"node_modules/@babel/code-frame": {
"version": "7.18.6",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
"integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==",
"version": "7.21.4",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.21.4.tgz",
"integrity": "sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g==",
"dev": true,
"dependencies": {
"@babel/highlight": "^7.18.6"
@ -124,9 +124,9 @@
}
},
"node_modules/@babel/runtime": {
"version": "7.20.13",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.13.tgz",
"integrity": "sha512-gt3PKXs0DBoL9xCvOIIZ2NEqAGZqHjAnmVbfQtB620V0uReIQutpel14KcneZuer7UioY8ALKZ7iocavvzTNFA==",
"version": "7.21.0",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.21.0.tgz",
"integrity": "sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw==",
"dev": true,
"dependencies": {
"regenerator-runtime": "^0.13.11"
@ -301,9 +301,9 @@
}
},
"node_modules/@msgpackr-extract/msgpackr-extract-darwin-arm64": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.0.tgz",
"integrity": "sha512-5qpnNHUyyEj9H3sm/4Um/bnx1lrQGhe8iqry/1d+cQYCRd/gzYA0YLeq0ezlk4hKx4vO+dsEsNyeowqRqslwQA==",
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.2.tgz",
"integrity": "sha512-9bfjwDxIDWmmOKusUcqdS4Rw+SETlp9Dy39Xui9BEGEk19dDwH0jhipwFzEff/pFg95NKymc6TOTbRKcWeRqyQ==",
"cpu": [
"arm64"
],
@ -314,9 +314,9 @@
]
},
"node_modules/@msgpackr-extract/msgpackr-extract-darwin-x64": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-3.0.0.tgz",
"integrity": "sha512-ZphTFFd6SFweNAMKD+QJCrWpgkjf4qBuHltiMkKkD6FFrB3NOTRVmetAGTkJ57pa+s6J0yCH06LujWB9rZe94g==",
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-3.0.2.tgz",
"integrity": "sha512-lwriRAHm1Yg4iDf23Oxm9n/t5Zpw1lVnxYU3HnJPTi2lJRkKTrps1KVgvL6m7WvmhYVt/FIsssWay+k45QHeuw==",
"cpu": [
"x64"
],
@ -327,9 +327,9 @@
]
},
"node_modules/@msgpackr-extract/msgpackr-extract-linux-arm": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-3.0.0.tgz",
"integrity": "sha512-ztKVV1dO/sSZyGse0PBCq3Pk1PkYjsA/dsEWE7lfrGoAK3i9HpS2o7XjGQ7V4va6nX+xPPOiuYpQwa4Bi6vlww==",
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-3.0.2.tgz",
"integrity": "sha512-MOI9Dlfrpi2Cuc7i5dXdxPbFIgbDBGgKR5F2yWEa6FVEtSWncfVNKW5AKjImAQ6CZlBK9tympdsZJ2xThBiWWA==",
"cpu": [
"arm"
],
@ -340,9 +340,9 @@
]
},
"node_modules/@msgpackr-extract/msgpackr-extract-linux-arm64": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-3.0.0.tgz",
"integrity": "sha512-NEX6hdSvP4BmVyegaIbrGxvHzHvTzzsPaxXCsUt0mbLbPpEftsvNwaEVKOowXnLoeuGeD4MaqSwL3BUK2elsUA==",
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-3.0.2.tgz",
"integrity": "sha512-FU20Bo66/f7He9Fp9sP2zaJ1Q8L9uLPZQDub/WlUip78JlPeMbVL8546HbZfcW9LNciEXc8d+tThSJjSC+tmsg==",
"cpu": [
"arm64"
],
@ -353,9 +353,9 @@
]
},
"node_modules/@msgpackr-extract/msgpackr-extract-linux-x64": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-3.0.0.tgz",
"integrity": "sha512-9uvdAkZMOPCY7SPRxZLW8XGqBOVNVEhqlgffenN8shA1XR9FWVsSM13nr/oHtNgXg6iVyML7RwWPyqUeThlwxg==",
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-3.0.2.tgz",
"integrity": "sha512-gsWNDCklNy7Ajk0vBBf9jEx04RUxuDQfBse918Ww+Qb9HCPoGzS+XJTLe96iN3BVK7grnLiYghP/M4L8VsaHeA==",
"cpu": [
"x64"
],
@ -366,9 +366,9 @@
]
},
"node_modules/@msgpackr-extract/msgpackr-extract-win32-x64": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-3.0.0.tgz",
"integrity": "sha512-Wg0+9615kHKlr9iLVcG5I+/CHnf6w3x5UADRv8Ad16yA0Bu5l9eVOROjV7aHPG6uC8ZPFIVVaoSjDChD+Y0pzg==",
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-3.0.2.tgz",
"integrity": "sha512-O+6Gs8UeDbyFpbSh2CPEz/UOrrdWPTBYNblZK5CxxLisYt4kGX3Sc+czffFonyjiGSq3jWLwJS/CCJc7tBr4sQ==",
"cpu": [
"x64"
],
@ -1542,9 +1542,9 @@
"dev": true
},
"node_modules/@types/react": {
"version": "18.0.28",
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.28.tgz",
"integrity": "sha512-RD0ivG1kEztNBdoAK7lekI9M+azSnitIn85h4iOiaLjaTrMjzslhaqCGaI4IyCJ1RljWiLCEu4jyrLLgqxBTew==",
"version": "18.0.33",
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.33.tgz",
"integrity": "sha512-sHxzVxeanvQyQ1lr8NSHaj0kDzcNiGpILEVt69g9S31/7PfMvNCKLKcsHw4lYKjs3cGNJjXSP4mYzX43QlnjNA==",
"dev": true,
"dependencies": {
"@types/prop-types": "*",
@ -1553,9 +1553,9 @@
}
},
"node_modules/@types/scheduler": {
"version": "0.16.2",
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz",
"integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==",
"version": "0.16.3",
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz",
"integrity": "sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==",
"dev": true
},
"node_modules/@types/semver-compare": {
@ -1589,9 +1589,9 @@
}
},
"node_modules/amazon-ivs-player": {
"version": "1.16.0",
"resolved": "https://registry.npmjs.org/amazon-ivs-player/-/amazon-ivs-player-1.16.0.tgz",
"integrity": "sha512-wwVJ6ajuWKX3aJWjcDSrhWBmk9qtkmF9gU8Waop3SZqKYv6vrsiKf8/VxPKREaUxfQwEwzB3CvUMEcho527jbA==",
"version": "1.18.0",
"resolved": "https://registry.npmjs.org/amazon-ivs-player/-/amazon-ivs-player-1.18.0.tgz",
"integrity": "sha512-iGi7No/464Twb6cQHzK1xf5Bb8pa9uffR2wdqoReZmWBV4VIZGn64ynpncgiC7IfM1TL40qf59IDLjMBlIiV2A==",
"dev": true,
"dependencies": {
"@babel/runtime": "^7.9.2",
@ -1695,9 +1695,9 @@
}
},
"node_modules/caniuse-lite": {
"version": "1.0.30001456",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001456.tgz",
"integrity": "sha512-XFHJY5dUgmpMV25UqaD4kVq2LsiaU5rS8fb0f17pCoXQiQslzmFgnfOxfvo1bTpTqf7dwG/N/05CnLCnOEKmzA==",
"version": "1.0.30001474",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001474.tgz",
"integrity": "sha512-iaIZ8gVrWfemh5DG3T9/YqarVZoYf0r188IjaGwx68j4Pf0SGY6CQkmJUIE+NZHkkecQGohzXmBGEwWDr9aM3Q==",
"dev": true,
"funding": [
{
@ -1707,6 +1707,10 @@
{
"type": "tidelift",
"url": "https://tidelift.com/funding/github/npm/caniuse-lite"
},
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
]
},
@ -1797,9 +1801,9 @@
}
},
"node_modules/css-declaration-sorter": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.3.1.tgz",
"integrity": "sha512-fBffmak0bPAnyqc/HO8C3n2sHrp9wcqQz6ES9koRF2/mLOVAx9zIQ3Y7R29sYCteTPqMCwns4WYQoCX91Xl3+w==",
"version": "6.4.0",
"resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.4.0.tgz",
"integrity": "sha512-jDfsatwWMWN0MODAFuHszfjphEXfNw9JUAhmY4pLu3TyTU+ohUpsbVtbU+1MZn4a47D9kqh03i4eyOm+74+zew==",
"dev": true,
"engines": {
"node": "^10 || ^12 || >=14"
@ -1862,9 +1866,9 @@
}
},
"node_modules/csstype": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz",
"integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==",
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz",
"integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==",
"dev": true
},
"node_modules/detect-libc": {
@ -1959,9 +1963,9 @@
"dev": true
},
"node_modules/electron-to-chromium": {
"version": "1.4.302",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.302.tgz",
"integrity": "sha512-Uk7C+7aPBryUR1Fwvk9VmipBcN9fVsqBO57jV2ZjTm+IZ6BMNqu7EDVEg2HxCNufk6QcWlFsBkhQyQroB2VWKw==",
"version": "1.4.353",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.353.tgz",
"integrity": "sha512-IdJVpMHJoBT/nn0GQ02wPfbhogDVpd1ud95lP//FTf5l35wzxKJwibB4HBdY7Q+xKPA1nkZ0UDLOMyRj5U5IAQ==",
"dev": true
},
"node_modules/entities": {
@ -2436,18 +2440,18 @@
}
},
"node_modules/msgpackr": {
"version": "1.8.3",
"resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.8.3.tgz",
"integrity": "sha512-m2JefwcKNzoHYXkH/5jzHRxAw7XLWsAdvu0FOJ+OLwwozwOV/J6UA62iLkfIMbg7G8+dIuRwgg6oz+QoQ4YkoA==",
"version": "1.8.5",
"resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.8.5.tgz",
"integrity": "sha512-mpPs3qqTug6ahbblkThoUY2DQdNXcm4IapwOS3Vm/87vmpzLVelvp9h3It1y9l1VPpiFLV11vfOXnmeEwiIXwg==",
"dev": true,
"optionalDependencies": {
"msgpackr-extract": "^3.0.0"
"msgpackr-extract": "^3.0.1"
}
},
"node_modules/msgpackr-extract": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/msgpackr-extract/-/msgpackr-extract-3.0.0.tgz",
"integrity": "sha512-oy6KCk1+X4Bn5m6Ycq5N1EWl9npqG/cLrE8ga8NX7ZqfqYUUBS08beCQaGq80fjbKBySur0E6x//yZjzNJDt3A==",
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/msgpackr-extract/-/msgpackr-extract-3.0.2.tgz",
"integrity": "sha512-SdzXp4kD/Qf8agZ9+iTu6eql0m3kWm1A2y1hkpTeVNENutaB0BwHlSvAIaMxwntmRUAUjon2V4L8Z/njd0Ct8A==",
"dev": true,
"hasInstallScript": true,
"optional": true,
@ -2458,12 +2462,12 @@
"download-msgpackr-prebuilds": "bin/download-prebuilds.js"
},
"optionalDependencies": {
"@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.0",
"@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.0",
"@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.0",
"@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.0",
"@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.0",
"@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.0"
"@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.2",
"@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.2",
"@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.2",
"@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.2",
"@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.2",
"@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.2"
}
},
"node_modules/msgpackr-extract/node_modules/node-gyp-build-optional-packages": {
@ -2479,10 +2483,16 @@
}
},
"node_modules/nanoid": {
"version": "3.3.4",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz",
"integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==",
"version": "3.3.6",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
"integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"bin": {
"nanoid": "bin/nanoid.cjs"
},
@ -2751,9 +2761,9 @@
}
},
"node_modules/prettier": {
"version": "2.8.4",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.4.tgz",
"integrity": "sha512-vIS4Rlc2FNh0BySk3Wkd6xmwxB0FpOndW5fisM5H8hsZSxU2VWVB5CWIkIjWvrHjIhxk2g3bfMKM87zNTrZddw==",
"version": "2.8.7",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.7.tgz",
"integrity": "sha512-yPngTo3aXUUmyuTjeTUT75txrf+aMh9FiD7q9ZE/i6r0bPb22g4FsE6Y338PQX1bmfy08i9QQCB7/rcUAVntfw==",
"dev": true,
"bin": {
"prettier": "bin-prettier.js"
@ -2972,9 +2982,9 @@
}
},
"node_modules/terser": {
"version": "5.16.4",
"resolved": "https://registry.npmjs.org/terser/-/terser-5.16.4.tgz",
"integrity": "sha512-5yEGuZ3DZradbogeYQ1NaGz7rXVBDWujWlx1PT8efXO6Txn+eWbfKqB2bTDVmFXmePFkoLU6XI8UektMIEA0ug==",
"version": "5.16.8",
"resolved": "https://registry.npmjs.org/terser/-/terser-5.16.8.tgz",
"integrity": "sha512-QI5g1E/ef7d+PsDifb+a6nnVgC4F22Bg6T0xrBrz6iloVB4PUkkunp6V8nzoOOZJIzjWVdAGqCdlKlhLq/TbIA==",
"dev": true,
"dependencies": {
"@jridgewell/source-map": "^0.3.2",
@ -3115,9 +3125,9 @@
},
"dependencies": {
"@babel/code-frame": {
"version": "7.18.6",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
"integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==",
"version": "7.21.4",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.21.4.tgz",
"integrity": "sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g==",
"dev": true,
"requires": {
"@babel/highlight": "^7.18.6"
@ -3193,9 +3203,9 @@
}
},
"@babel/runtime": {
"version": "7.20.13",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.13.tgz",
"integrity": "sha512-gt3PKXs0DBoL9xCvOIIZ2NEqAGZqHjAnmVbfQtB620V0uReIQutpel14KcneZuer7UioY8ALKZ7iocavvzTNFA==",
"version": "7.21.0",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.21.0.tgz",
"integrity": "sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw==",
"dev": true,
"requires": {
"regenerator-runtime": "^0.13.11"
@ -3319,44 +3329,44 @@
}
},
"@msgpackr-extract/msgpackr-extract-darwin-arm64": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.0.tgz",
"integrity": "sha512-5qpnNHUyyEj9H3sm/4Um/bnx1lrQGhe8iqry/1d+cQYCRd/gzYA0YLeq0ezlk4hKx4vO+dsEsNyeowqRqslwQA==",
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.2.tgz",
"integrity": "sha512-9bfjwDxIDWmmOKusUcqdS4Rw+SETlp9Dy39Xui9BEGEk19dDwH0jhipwFzEff/pFg95NKymc6TOTbRKcWeRqyQ==",
"dev": true,
"optional": true
},
"@msgpackr-extract/msgpackr-extract-darwin-x64": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-3.0.0.tgz",
"integrity": "sha512-ZphTFFd6SFweNAMKD+QJCrWpgkjf4qBuHltiMkKkD6FFrB3NOTRVmetAGTkJ57pa+s6J0yCH06LujWB9rZe94g==",
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-3.0.2.tgz",
"integrity": "sha512-lwriRAHm1Yg4iDf23Oxm9n/t5Zpw1lVnxYU3HnJPTi2lJRkKTrps1KVgvL6m7WvmhYVt/FIsssWay+k45QHeuw==",
"dev": true,
"optional": true
},
"@msgpackr-extract/msgpackr-extract-linux-arm": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-3.0.0.tgz",
"integrity": "sha512-ztKVV1dO/sSZyGse0PBCq3Pk1PkYjsA/dsEWE7lfrGoAK3i9HpS2o7XjGQ7V4va6nX+xPPOiuYpQwa4Bi6vlww==",
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-3.0.2.tgz",
"integrity": "sha512-MOI9Dlfrpi2Cuc7i5dXdxPbFIgbDBGgKR5F2yWEa6FVEtSWncfVNKW5AKjImAQ6CZlBK9tympdsZJ2xThBiWWA==",
"dev": true,
"optional": true
},
"@msgpackr-extract/msgpackr-extract-linux-arm64": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-3.0.0.tgz",
"integrity": "sha512-NEX6hdSvP4BmVyegaIbrGxvHzHvTzzsPaxXCsUt0mbLbPpEftsvNwaEVKOowXnLoeuGeD4MaqSwL3BUK2elsUA==",
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-3.0.2.tgz",
"integrity": "sha512-FU20Bo66/f7He9Fp9sP2zaJ1Q8L9uLPZQDub/WlUip78JlPeMbVL8546HbZfcW9LNciEXc8d+tThSJjSC+tmsg==",
"dev": true,
"optional": true
},
"@msgpackr-extract/msgpackr-extract-linux-x64": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-3.0.0.tgz",
"integrity": "sha512-9uvdAkZMOPCY7SPRxZLW8XGqBOVNVEhqlgffenN8shA1XR9FWVsSM13nr/oHtNgXg6iVyML7RwWPyqUeThlwxg==",
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-3.0.2.tgz",
"integrity": "sha512-gsWNDCklNy7Ajk0vBBf9jEx04RUxuDQfBse918Ww+Qb9HCPoGzS+XJTLe96iN3BVK7grnLiYghP/M4L8VsaHeA==",
"dev": true,
"optional": true
},
"@msgpackr-extract/msgpackr-extract-win32-x64": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-3.0.0.tgz",
"integrity": "sha512-Wg0+9615kHKlr9iLVcG5I+/CHnf6w3x5UADRv8Ad16yA0Bu5l9eVOROjV7aHPG6uC8ZPFIVVaoSjDChD+Y0pzg==",
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-3.0.2.tgz",
"integrity": "sha512-O+6Gs8UeDbyFpbSh2CPEz/UOrrdWPTBYNblZK5CxxLisYt4kGX3Sc+czffFonyjiGSq3jWLwJS/CCJc7tBr4sQ==",
"dev": true,
"optional": true
},
@ -4099,9 +4109,9 @@
"dev": true
},
"@types/react": {
"version": "18.0.28",
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.28.tgz",
"integrity": "sha512-RD0ivG1kEztNBdoAK7lekI9M+azSnitIn85h4iOiaLjaTrMjzslhaqCGaI4IyCJ1RljWiLCEu4jyrLLgqxBTew==",
"version": "18.0.33",
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.33.tgz",
"integrity": "sha512-sHxzVxeanvQyQ1lr8NSHaj0kDzcNiGpILEVt69g9S31/7PfMvNCKLKcsHw4lYKjs3cGNJjXSP4mYzX43QlnjNA==",
"dev": true,
"requires": {
"@types/prop-types": "*",
@ -4110,9 +4120,9 @@
}
},
"@types/scheduler": {
"version": "0.16.2",
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz",
"integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==",
"version": "0.16.3",
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz",
"integrity": "sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==",
"dev": true
},
"@types/semver-compare": {
@ -4140,9 +4150,9 @@
"dev": true
},
"amazon-ivs-player": {
"version": "1.16.0",
"resolved": "https://registry.npmjs.org/amazon-ivs-player/-/amazon-ivs-player-1.16.0.tgz",
"integrity": "sha512-wwVJ6ajuWKX3aJWjcDSrhWBmk9qtkmF9gU8Waop3SZqKYv6vrsiKf8/VxPKREaUxfQwEwzB3CvUMEcho527jbA==",
"version": "1.18.0",
"resolved": "https://registry.npmjs.org/amazon-ivs-player/-/amazon-ivs-player-1.18.0.tgz",
"integrity": "sha512-iGi7No/464Twb6cQHzK1xf5Bb8pa9uffR2wdqoReZmWBV4VIZGn64ynpncgiC7IfM1TL40qf59IDLjMBlIiV2A==",
"dev": true,
"requires": {
"@babel/runtime": "^7.9.2",
@ -4215,9 +4225,9 @@
"dev": true
},
"caniuse-lite": {
"version": "1.0.30001456",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001456.tgz",
"integrity": "sha512-XFHJY5dUgmpMV25UqaD4kVq2LsiaU5rS8fb0f17pCoXQiQslzmFgnfOxfvo1bTpTqf7dwG/N/05CnLCnOEKmzA==",
"version": "1.0.30001474",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001474.tgz",
"integrity": "sha512-iaIZ8gVrWfemh5DG3T9/YqarVZoYf0r188IjaGwx68j4Pf0SGY6CQkmJUIE+NZHkkecQGohzXmBGEwWDr9aM3Q==",
"dev": true
},
"chalk": {
@ -4283,10 +4293,11 @@
}
},
"css-declaration-sorter": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.3.1.tgz",
"integrity": "sha512-fBffmak0bPAnyqc/HO8C3n2sHrp9wcqQz6ES9koRF2/mLOVAx9zIQ3Y7R29sYCteTPqMCwns4WYQoCX91Xl3+w==",
"dev": true
"version": "6.4.0",
"resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.4.0.tgz",
"integrity": "sha512-jDfsatwWMWN0MODAFuHszfjphEXfNw9JUAhmY4pLu3TyTU+ohUpsbVtbU+1MZn4a47D9kqh03i4eyOm+74+zew==",
"dev": true,
"requires": {}
},
"css-select": {
"version": "4.3.0",
@ -4327,9 +4338,9 @@
}
},
"csstype": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz",
"integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==",
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz",
"integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==",
"dev": true
},
"detect-libc": {
@ -4396,9 +4407,9 @@
"dev": true
},
"electron-to-chromium": {
"version": "1.4.302",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.302.tgz",
"integrity": "sha512-Uk7C+7aPBryUR1Fwvk9VmipBcN9fVsqBO57jV2ZjTm+IZ6BMNqu7EDVEg2HxCNufk6QcWlFsBkhQyQroB2VWKw==",
"version": "1.4.353",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.353.tgz",
"integrity": "sha512-IdJVpMHJoBT/nn0GQ02wPfbhogDVpd1ud95lP//FTf5l35wzxKJwibB4HBdY7Q+xKPA1nkZ0UDLOMyRj5U5IAQ==",
"dev": true
},
"entities": {
@ -4665,27 +4676,27 @@
}
},
"msgpackr": {
"version": "1.8.3",
"resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.8.3.tgz",
"integrity": "sha512-m2JefwcKNzoHYXkH/5jzHRxAw7XLWsAdvu0FOJ+OLwwozwOV/J6UA62iLkfIMbg7G8+dIuRwgg6oz+QoQ4YkoA==",
"version": "1.8.5",
"resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.8.5.tgz",
"integrity": "sha512-mpPs3qqTug6ahbblkThoUY2DQdNXcm4IapwOS3Vm/87vmpzLVelvp9h3It1y9l1VPpiFLV11vfOXnmeEwiIXwg==",
"dev": true,
"requires": {
"msgpackr-extract": "^3.0.0"
"msgpackr-extract": "^3.0.1"
}
},
"msgpackr-extract": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/msgpackr-extract/-/msgpackr-extract-3.0.0.tgz",
"integrity": "sha512-oy6KCk1+X4Bn5m6Ycq5N1EWl9npqG/cLrE8ga8NX7ZqfqYUUBS08beCQaGq80fjbKBySur0E6x//yZjzNJDt3A==",
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/msgpackr-extract/-/msgpackr-extract-3.0.2.tgz",
"integrity": "sha512-SdzXp4kD/Qf8agZ9+iTu6eql0m3kWm1A2y1hkpTeVNENutaB0BwHlSvAIaMxwntmRUAUjon2V4L8Z/njd0Ct8A==",
"dev": true,
"optional": true,
"requires": {
"@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.0",
"@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.0",
"@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.0",
"@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.0",
"@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.0",
"@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.0",
"@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.2",
"@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.2",
"@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.2",
"@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.2",
"@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.2",
"@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.2",
"node-gyp-build-optional-packages": "5.0.7"
},
"dependencies": {
@ -4699,9 +4710,9 @@
}
},
"nanoid": {
"version": "3.3.4",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz",
"integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==",
"version": "3.3.6",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
"integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==",
"dev": true
},
"node-addon-api": {
@ -4825,13 +4836,15 @@
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/postcss-less/-/postcss-less-6.0.0.tgz",
"integrity": "sha512-FPX16mQLyEjLzEuuJtxA8X3ejDLNGGEG503d2YGZR5Ask1SpDN8KmZUMpzCvyalWRywAn1n1VOA5dcqfCLo5rg==",
"dev": true
"dev": true,
"requires": {}
},
"postcss-scss": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-4.0.6.tgz",
"integrity": "sha512-rLDPhJY4z/i4nVFZ27j9GqLxj1pwxE80eAzUNRMXtcpipFYIeowerzBgG3yJhMtObGEXidtIgbUpQ3eLDsf5OQ==",
"dev": true
"dev": true,
"requires": {}
},
"postcss-value-parser": {
"version": "4.2.0",
@ -4879,9 +4892,9 @@
}
},
"prettier": {
"version": "2.8.4",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.4.tgz",
"integrity": "sha512-vIS4Rlc2FNh0BySk3Wkd6xmwxB0FpOndW5fisM5H8hsZSxU2VWVB5CWIkIjWvrHjIhxk2g3bfMKM87zNTrZddw==",
"version": "2.8.7",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.7.tgz",
"integrity": "sha512-yPngTo3aXUUmyuTjeTUT75txrf+aMh9FiD7q9ZE/i6r0bPb22g4FsE6Y338PQX1bmfy08i9QQCB7/rcUAVntfw==",
"dev": true
},
"prettier-plugin-css-order": {
@ -4900,7 +4913,8 @@
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/prettier-plugin-organize-imports/-/prettier-plugin-organize-imports-3.2.2.tgz",
"integrity": "sha512-e97lE6odGSiHonHJMTYC0q0iLXQyw0u5z/PJpvP/3vRy6/Zi9kLBwFAbEGjDzIowpjQv8b+J04PDamoUSQbzGA==",
"dev": true
"dev": true,
"requires": {}
},
"promise-polyfill": {
"version": "8.3.0",
@ -5020,9 +5034,9 @@
"dev": true
},
"terser": {
"version": "5.16.4",
"resolved": "https://registry.npmjs.org/terser/-/terser-5.16.4.tgz",
"integrity": "sha512-5yEGuZ3DZradbogeYQ1NaGz7rXVBDWujWlx1PT8efXO6Txn+eWbfKqB2bTDVmFXmePFkoLU6XI8UektMIEA0ug==",
"version": "5.16.8",
"resolved": "https://registry.npmjs.org/terser/-/terser-5.16.8.tgz",
"integrity": "sha512-QI5g1E/ef7d+PsDifb+a6nnVgC4F22Bg6T0xrBrz6iloVB4PUkkunp6V8nzoOOZJIzjWVdAGqCdlKlhLq/TbIA==",
"dev": true,
"requires": {
"@jridgewell/source-map": "^0.3.2",

View File

@ -1,6 +1,6 @@
{
"name": "ttv-lol-pro",
"version": "1.8.1",
"version": "1.9.0",
"description": "TTV LOL PRO removes livestream ads from Twitch",
"@parcel/bundler-default": {
"minBundles": 10000000,
@ -38,13 +38,13 @@
},
"devDependencies": {
"@parcel/config-webextension": "^2.8.3",
"@types/react": "^18.0.28",
"@types/react": "^18.0.33",
"@types/semver-compare": "^1.0.1",
"@types/webextension-polyfill": "^0.10.0",
"amazon-ivs-player": "^1.16.0",
"amazon-ivs-player": "^1.18.0",
"parcel": "^2.8.3",
"postcss": "^8.4.21",
"prettier": "^2.8.4",
"prettier": "^2.8.7",
"prettier-plugin-css-order": "^1.3.0",
"prettier-plugin-organize-imports": "^3.2.2",
"typescript": "^4.9.5",

View File

@ -3,10 +3,14 @@ import onApiHeadersReceived from "./handlers/onApiHeadersReceived";
import onBeforeManifestRequest from "./handlers/onBeforeManifestRequest";
import onBeforeSendApiHeaders from "./handlers/onBeforeSendApiHeaders";
import onStartupStoreCleanup from "./handlers/onStartupStoreCleanup";
import onStartupUpdateCheck from "./handlers/onStartupUpdateCheck";
// Cleanup the session-related data in the store on startup.
browser.runtime.onStartup.addListener(onStartupStoreCleanup);
// Check for updates on startup.
browser.runtime.onStartup.addListener(onStartupUpdateCheck);
// Redirect the HLS master manifest request to TTV LOL's API.
browser.webRequest.onBeforeRequest.addListener(
onBeforeManifestRequest,

View File

@ -50,12 +50,12 @@ export default function onBeforeManifestRequest(
);
if (isExemptFromAds && !isIgnoredChannelSubscription) {
console.log(
`${streamId}: No redirect (User is a subscriber, has Twitch Turbo, or is a partner)`
`${streamId}: No redirect (User is a subscriber or has Twitch Turbo)`
);
setStreamStatus(
streamId,
false,
"User is a subscriber, has Twitch Turbo, or is a partner"
"User is a subscriber or has Twitch Turbo"
);
return {};
}
@ -114,6 +114,13 @@ function setStreamStatus(
};
}
function getServerStem(server: string): string {
const match = /^https?:\/\/(.*?)\/?$/i.exec(server);
if (!match) return server;
const [, stem] = match;
return stem;
}
function redirectChrome(
playlistType: PlaylistType,
streamId: string,
@ -137,7 +144,7 @@ function redirectChrome(
if (request.status === 200) {
console.log(`${streamId}: Redirecting to ${server}`);
setStreamStatus(streamId, true, `Redirected to ${server}`);
setStreamStatus(streamId, true, `Proxied via ${getServerStem(server)}`);
return { redirectUrl };
} else {
console.log(`${streamId}: Ping to ${server} failed`);
@ -185,7 +192,11 @@ function redirectFirefox(
.then(response => {
if (response.status === 200) {
console.log(`${streamId}: Redirecting to ${server}`);
setStreamStatus(streamId, true, `Redirected to ${server}`);
setStreamStatus(
streamId,
true,
`Proxied via ${getServerStem(server)}`
);
resolve({ redirectUrl });
} else fallback();
})

View File

@ -0,0 +1,48 @@
import semverCompare from "semver-compare";
import browser from "webextension-polyfill";
import store from "../../store";
//#region Types
type Update = {
version: string;
update_link: string;
};
//#endregion
export default async function onStartupUpdateCheck(): Promise<void> {
if (store.readyState !== "complete")
return store.addEventListener("load", onStartupUpdateCheck);
if (!store.state.checkForUpdates) return;
// Check for updates once every 24 hours.
if (
!store.state.isUpdateAvailable &&
Date.now() - store.state.lastUpdateCheck < 24 * 60 * 60 * 1000
) {
return;
}
const manifest = browser.runtime.getManifest();
const currentVersion = manifest.version;
const updateUrl = manifest.browser_specific_settings?.gecko?.update_url;
if (!updateUrl) {
console.warn("Update URL not found.");
store.state.isUpdateAvailable = false;
return;
}
try {
const response = await fetch(updateUrl);
const json = await response.json();
const updates = json.addons["{76ef94a4-e3d0-4c6f-961a-d38a429a332b}"]
.updates as Update[];
updates.sort((a, b) => semverCompare(a.version, b.version));
const latestVersion = updates[updates.length - 1].version;
store.state.isUpdateAvailable =
semverCompare(currentVersion, latestVersion) < 0; // currentVersion < latestVersion
store.state.lastUpdateCheck = Date.now();
} catch {
store.state.isUpdateAvailable = false;
}
}

Binary file not shown.

View File

@ -2,7 +2,7 @@
"manifest_version": 2,
"name": "TTV LOL PRO",
"description": "TTV LOL PRO removes livestream ads from Twitch.",
"version": "1.8.1",
"version": "1.9.0",
"background": {
"persistent": true,
"scripts": ["background/background.ts"]
@ -41,7 +41,9 @@
"https://*.ttvnw.net/*",
"https://api.ttv.lol/*",
"https://www.twitch.tv/*",
"https://m.twitch.tv/*"
"https://m.twitch.tv/*",
"https://player.twitch.tv/*",
"https://embed.twitch.tv/*"
],
"update_url": "https://younesaassila.github.io/ttv-lol-pro/updates.xml"
}

View File

@ -27,6 +27,9 @@ type ListOptions = {
const resetPlayerOnMidrollCheckboxElement = $(
"#reset-player-on-midroll-checkbox"
) as HTMLInputElement;
const checkForUpdatesCheckboxElement = $(
"#check-for-updates-checkbox"
) as HTMLInputElement;
// Whitelisted channels
const whitelistedChannelsListElement = $(
"#whitelisted-channels-list"
@ -83,6 +86,12 @@ function main() {
const checkbox = e.target as HTMLInputElement;
store.state.resetPlayerOnMidroll = checkbox.checked;
});
// Check for updates
checkForUpdatesCheckboxElement.checked = store.state.checkForUpdates;
checkForUpdatesCheckboxElement.addEventListener("change", e => {
const checkbox = e.target as HTMLInputElement;
store.state.checkForUpdates = checkbox.checked;
});
// Disable VOD proxying
disableVodRedirectCheckboxElement.checked = store.state.disableVodRedirect;
disableVodRedirectCheckboxElement.addEventListener("change", e => {
@ -284,6 +293,7 @@ exportButtonElement.addEventListener("click", () => {
saveFile(
"ttv-lol-pro_backup.json",
JSON.stringify({
checkForUpdates: store.state.checkForUpdates,
disableVodRedirect: store.state.disableVodRedirect,
ignoredChannelSubscriptions: store.state.ignoredChannelSubscriptions,
resetPlayerOnMidroll: store.state.resetPlayerOnMidroll,

View File

@ -6,12 +6,6 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Options - TTV LOL PRO</title>
<link rel="icon" href="../images/brand/favicon.ico" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap"
rel="stylesheet"
/>
<link rel="stylesheet" href="../common/css/boilerplate.css" />
<link rel="stylesheet" href="./style.css" />
</head>
@ -35,10 +29,29 @@
id="reset-player-on-midroll-checkbox"
/>
<label for="reset-player-on-midroll-checkbox">
Reset player on midroll
Reset the player when a midroll ad is detected
</label>
<br />
<small>Reset the player when a midroll ad is detected.</small>
<small>
Player resets may show a momentary black screen. This feature is
only available on Twitch's desktop website.
</small>
</li>
<li>
<input
type="checkbox"
name="check-for-updates-checkbox"
id="check-for-updates-checkbox"
/>
<label for="check-for-updates-checkbox">
Show a banner in the extension's popup when a new version is
available
</label>
<br />
<small>
This option is handy for users who have used the ZIP file
installation method.
</small>
</li>
</ul>
</section>

View File

@ -1,3 +1,8 @@
@font-face {
src: url("../fonts/Inter-VariableFont_slnt\,wght.ttf");
font-family: "Inter";
}
:root {
--font-primary: "Inter", "Roobert", "Helvetica Neue", Helvetica, Arial,
sans-serif;

View File

@ -140,10 +140,6 @@ namespace TTV_LOL_PRO {
resetPlayer(playerInstance, playerSourceInstance);
}
function importFunctions(functions: WorkerFunctions) {
return Object.values(functions).map(fn => fn.functionBody);
}
function onVideoWeaverResponse(responseText: string) {
const AD_SIGNIFIER = "stitched"; // From https://github.com/cleanlock/VideoAdBlockForTwitch/blob/145921a822e830da62d39e36e8aafb8ef22c7be6/firefox/content.js#L87
const START_DATE_REGEX =
@ -207,6 +203,18 @@ namespace TTV_LOL_PRO {
console.log("[TTV LOL PRO] Hooked into fetch.");
}
function importFunctions(functions: WorkerFunctions) {
return Object.values(functions).map(fn => fn.functionBody);
}
// From https://github.com/cleanlock/VideoAdBlockForTwitch/blob/145921a822e830da62d39e36e8aafb8ef22c7be6/chrome/remove_video_ads.js#L296-L301
function getWasmWorkerUrl(twitchBlobUrl: string) {
var req = new XMLHttpRequest();
req.open("GET", twitchBlobUrl, false);
req.send();
return req.responseText.split("'")[1];
}
// From https://github.com/cleanlock/VideoAdBlockForTwitch/blob/145921a822e830da62d39e36e8aafb8ef22c7be6/chrome/remove_video_ads.js#L95-L135
export class Worker extends REAL_WORKER {
constructor(Url: string | URL) {
@ -234,17 +242,29 @@ namespace TTV_LOL_PRO {
const ttvlolBlobUrl = URL.createObjectURL(new Blob([ttvlolBlobPart]));
// Prevents VideoAdBlockForTwitch from throwing an error.
const workerBlobPart = `
importScripts('${ttvlolBlobUrl}');
try {
importScripts('${ttvlolBlobUrl}');
} catch (error) {
console.error('[TTV LOL PRO] Error importing worker:', error);
importScripts('${getWasmWorkerUrl(twitchBlobUrl)}');
}
` as BlobPart;
const workerBlobUrl = URL.createObjectURL(new Blob([workerBlobPart]));
super(workerBlobUrl);
twitchMainWorker = this;
let lastResetsTimestamps = [] as number[];
// Listen for messages from the worker.
this.addEventListener("message", event => {
switch (event.data?.type) {
case "midroll":
const recentResets = lastResetsTimestamps.filter(
timestamp => Date.now() - timestamp < 15000 // 15 seconds
);
if (recentResets.length >= 3) return; // Limit to 3 player resets per 15 seconds.
lastResetsTimestamps = [...recentResets, Date.now()];
onMidroll();
break;
}

View File

@ -5,127 +5,174 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Popup - TTV LOL PRO</title>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap"
rel="stylesheet"
/>
<link rel="stylesheet" href="../common/css/boilerplate.css" />
<link rel="stylesheet" href="./style.css" />
</head>
<body>
<div class="container">
<div id="update-banner">
A new update is available. Download it from the
<a
href="https://github.com/younesaassila/ttv-lol-pro/releases"
target="_blank"
>
GitHub repo's Releases page
</a>
</div>
<!-- Update banner -->
<div id="update-banner">
A new update is available. Download it from the
<a
href="https://github.com/younesaassila/ttv-lol-pro/releases"
target="_blank"
class="update-banner-link"
>
GitHub releases page
</a>
</div>
<main>
<!-- Logo -->
<div class="logo-wrapper">
<img width="60%" src="../images/brand/logo.png" />
<img src="../images/brand/logo.png" alt="TTV LOL" />
</div>
<!-- Stream status -->
<div id="stream-status">
<div>
<span id="redirected"></span>
</div>
<div>
<span id="stream-id"></span>
<br />
<small id="reason"></small>
<br />
<div id="proxy-status">
<div id="redirected">
<!-- https://icons.getbootstrap.com/icons/circle-fill/ -->
<svg
xmlns="http://www.w3.org/2000/svg"
width="7"
height="7"
fill="currentColor"
class="bi bi-circle-fill"
viewBox="0 0 16 16"
>
<circle cx="8" cy="8" r="8" />
</svg>
</div>
<h3 id="stream-id"></h3>
<p id="reason"></p>
<small id="proxy-country"></small>
</div>
<div id="whitelist-status" data-whitelisted="false">
<input
type="checkbox"
name="whitelist-toggle"
id="whitelist-toggle"
/>
<label for="whitelist-toggle" id="whitelist-toggle-label">
<span id="whitelist-toggle-icon">
<!-- If data-whitelisted="false" -->
<!-- https://icons.getbootstrap.com/icons/plus/ -->
<svg
xmlns="http://www.w3.org/2000/svg"
width="20"
height="20"
fill="currentColor"
class="bi bi-plus"
viewBox="0 0 16 16"
>
<path
d="M8 4a.5.5 0 0 1 .5.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3A.5.5 0 0 1 8 4z"
/>
</svg>
<!-- Else if data-whitelisted="true" -->
<!-- https://icons.getbootstrap.com/icons/check-lg/ -->
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
fill="currentColor"
class="bi bi-check-lg"
viewBox="0 0 16 16"
>
<path
d="M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06.733.733 0 0 1 1.047 0l3.052 3.093 5.4-6.425a.247.247 0 0 1 .02-.022Z"
/>
</svg>
</span>
<!-- Label content in ::after -->
</label>
</div>
</div>
<div id="whitelist-toggle-wrapper">
<input type="checkbox" name="whitelist-toggle" id="whitelist-toggle" />
<label for="whitelist-toggle" id="whitelist-toggle-label"></label>
</div>
<div class="button-group">
<a
href="https://ttv.lol/donate"
target="_blank"
class="button button-arrow"
>
<svg
xmlns="http://www.w3.org/2000/svg"
class="icon"
width="16"
height="16"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
fill-rule="evenodd"
d="M3.172 5.172a4 4 0 015.656 0L10 6.343l1.172-1.171a4 4 0 115.656 5.656L10 17.657l-6.828-6.829a4 4 0 010-5.656z"
clip-rule="evenodd"
/>
</svg>
Donate
<svg
viewBox="0 0 6 9"
fill="none"
xmlns="http://www.w3.org/2000/svg"
class="arrow-icon"
>
<g class="arrow-head">
<path
d="M1 1C4.5 4 5 4.38484 5 4.5C5 4.61516 4.5 5 1 8"
stroke="currentColor"
stroke-width="2"
/>
</g>
<g class="arrow-body">
<path d="M3.5 4.5H0" stroke="currentColor" stroke-width="2" />
</g>
</svg>
</a>
<a
href="https://discord.gg/NAv7AFAyTF"
target="_blank"
class="button button-arrow"
>
<svg
xmlns="http://www.w3.org/2000/svg"
class="icon"
style="margin-right: 3px"
width="16"
height="16"
fill="currentColor"
class="bi bi-discord"
viewBox="0 0 16 16"
<!-- Links -->
<ol class="list">
<li>
<a href="../options/page.html" target="_blank" class="list-item">
<div class="list-item-icon">
<!-- https://icons.getbootstrap.com/icons/gear-fill/ -->
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
fill="currentColor"
class="bi bi-gear-fill"
viewBox="0 0 16 16"
>
<path
d="M9.405 1.05c-.413-1.4-2.397-1.4-2.81 0l-.1.34a1.464 1.464 0 0 1-2.105.872l-.31-.17c-1.283-.698-2.686.705-1.987 1.987l.169.311c.446.82.023 1.841-.872 2.105l-.34.1c-1.4.413-1.4 2.397 0 2.81l.34.1a1.464 1.464 0 0 1 .872 2.105l-.17.31c-.698 1.283.705 2.686 1.987 1.987l.311-.169a1.464 1.464 0 0 1 2.105.872l.1.34c.413 1.4 2.397 1.4 2.81 0l.1-.34a1.464 1.464 0 0 1 2.105-.872l.31.17c1.283.698 2.686-.705 1.987-1.987l-.169-.311a1.464 1.464 0 0 1 .872-2.105l.34-.1c1.4-.413 1.4-2.397 0-2.81l-.34-.1a1.464 1.464 0 0 1-.872-2.105l.17-.31c.698-1.283-.705-2.686-1.987-1.987l-.311.169a1.464 1.464 0 0 1-2.105-.872l-.1-.34zM8 10.93a2.929 2.929 0 1 1 0-5.86 2.929 2.929 0 0 1 0 5.858z"
/>
</svg>
</div>
<div class="list-item-text">
<h3 class="list-item-title">Options</h3>
<p class="list-item-description">
Configure proxies, whitelist, and more.
</p>
</div>
</a>
</li>
<li>
<a href="https://ttv.lol/donate" target="_blank" class="list-item">
<div class="list-item-icon">
<!-- https://icons.getbootstrap.com/icons/suit-heart-fill/ -->
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
fill="currentColor"
class="bi bi-suit-heart-fill"
viewBox="0 0 16 16"
>
<path
d="M4 1c2.21 0 4 1.755 4 3.92C8 2.755 9.79 1 12 1s4 1.755 4 3.92c0 3.263-3.234 4.414-7.608 9.608a.513.513 0 0 1-.784 0C3.234 9.334 0 8.183 0 4.92 0 2.755 1.79 1 4 1z"
/>
</svg>
</div>
<div class="list-item-text">
<h3 class="list-item-title">Donate</h3>
<p class="list-item-description">
Support the TTV LOL API (not affiliated).
</p>
</div>
</a>
</li>
<li>
<a
href="https://discord.gg/NAv7AFAyTF"
target="_blank"
class="list-item"
>
<path
d="M6.552 6.712c-.456 0-.816.4-.816.888s.368.888.816.888c.456 0 .816-.4.816-.888.008-.488-.36-.888-.816-.888zm2.92 0c-.456 0-.816.4-.816.888s.368.888.816.888c.456 0 .816-.4.816-.888s-.36-.888-.816-.888z"
/>
<path
d="M13.36 0H2.64C1.736 0 1 .736 1 1.648v10.816c0 .912.736 1.648 1.64 1.648h9.072l-.424-1.48 1.024.952.968.896L15 16V1.648C15 .736 14.264 0 13.36 0zm-3.088 10.448s-.288-.344-.528-.648c1.048-.296 1.448-.952 1.448-.952-.328.216-.64.368-.92.472-.4.168-.784.28-1.16.344a5.604 5.604 0 0 1-2.072-.008 6.716 6.716 0 0 1-1.176-.344 4.688 4.688 0 0 1-.584-.272c-.024-.016-.048-.024-.072-.04-.016-.008-.024-.016-.032-.024-.144-.08-.224-.136-.224-.136s.384.64 1.4.944c-.24.304-.536.664-.536.664-1.768-.056-2.44-1.216-2.44-1.216 0-2.576 1.152-4.664 1.152-4.664 1.152-.864 2.248-.84 2.248-.84l.08.096c-1.44.416-2.104 1.048-2.104 1.048s.176-.096.472-.232c.856-.376 1.536-.48 1.816-.504.048-.008.088-.016.136-.016a6.521 6.521 0 0 1 4.024.752s-.632-.6-1.992-1.016l.112-.128s1.096-.024 2.248.84c0 0 1.152 2.088 1.152 4.664 0 0-.68 1.16-2.448 1.216z"
/>
</svg>
Discord
<svg
viewBox="0 0 6 9"
fill="none"
xmlns="http://www.w3.org/2000/svg"
class="arrow-icon"
>
<g class="arrow-head">
<path
d="M1 1C4.5 4 5 4.38484 5 4.5C5 4.61516 4.5 5 1 8"
stroke="currentColor"
stroke-width="2"
/>
</g>
<g class="arrow-body">
<path d="M3.5 4.5H0" stroke="currentColor" stroke-width="2" />
</g>
</svg>
</a>
</div>
</div>
<div class="list-item-icon">
<!-- https://icons.getbootstrap.com/icons/discord/ -->
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
fill="currentColor"
class="bi bi-discord"
viewBox="0 0 16 16"
>
<path
d="M13.545 2.907a13.227 13.227 0 0 0-3.257-1.011.05.05 0 0 0-.052.025c-.141.25-.297.577-.406.833a12.19 12.19 0 0 0-3.658 0 8.258 8.258 0 0 0-.412-.833.051.051 0 0 0-.052-.025c-1.125.194-2.22.534-3.257 1.011a.041.041 0 0 0-.021.018C.356 6.024-.213 9.047.066 12.032c.001.014.01.028.021.037a13.276 13.276 0 0 0 3.995 2.02.05.05 0 0 0 .056-.019c.308-.42.582-.863.818-1.329a.05.05 0 0 0-.01-.059.051.051 0 0 0-.018-.011 8.875 8.875 0 0 1-1.248-.595.05.05 0 0 1-.02-.066.051.051 0 0 1 .015-.019c.084-.063.168-.129.248-.195a.05.05 0 0 1 .051-.007c2.619 1.196 5.454 1.196 8.041 0a.052.052 0 0 1 .053.007c.08.066.164.132.248.195a.051.051 0 0 1-.004.085 8.254 8.254 0 0 1-1.249.594.05.05 0 0 0-.03.03.052.052 0 0 0 .003.041c.24.465.515.909.817 1.329a.05.05 0 0 0 .056.019 13.235 13.235 0 0 0 4.001-2.02.049.049 0 0 0 .021-.037c.334-3.451-.559-6.449-2.366-9.106a.034.034 0 0 0-.02-.019Zm-8.198 7.307c-.789 0-1.438-.724-1.438-1.612 0-.889.637-1.613 1.438-1.613.807 0 1.45.73 1.438 1.613 0 .888-.637 1.612-1.438 1.612Zm5.316 0c-.788 0-1.438-.724-1.438-1.612 0-.889.637-1.613 1.438-1.613.807 0 1.451.73 1.438 1.613 0 .888-.631 1.612-1.438 1.612Z"
/>
</svg>
</div>
<div class="list-item-text">
<h3 class="list-item-title">Discord</h3>
<p class="list-item-description">
TTV LOL Discord server (not affiliated).
</p>
</div>
</a>
</li>
</ol>
</main>
<script type="module" src="./popup.ts"></script>
</body>
</html>

View File

@ -2,17 +2,17 @@ import browser from "webextension-polyfill";
import $ from "../common/ts/$";
import { TWITCH_URL_REGEX } from "../common/ts/regexes";
import store from "../store";
import type { StreamStatus } from "../types";
//#region HTML Elements
const updateBannerElement = $("#update-banner") as HTMLDivElement;
const streamStatusElement = $("#stream-status") as HTMLDivElement;
const redirectedElement = $("#redirected") as HTMLSpanElement;
const streamIdElement = $("#stream-id") as HTMLSpanElement;
const reasonElement = $("#reason") as HTMLElement;
const redirectedElement = $("#redirected") as HTMLDivElement;
const streamIdElement = $("#stream-id") as HTMLHeadingElement;
const reasonElement = $("#reason") as HTMLParagraphElement;
const proxyCountryElement = $("#proxy-country") as HTMLElement;
const whitelistToggleWrapper = $("#whitelist-toggle-wrapper") as HTMLDivElement;
const whitelistToggle = $("#whitelist-toggle") as HTMLInputElement;
const whitelistToggleLabel = $("#whitelist-toggle-label") as HTMLLabelElement;
const whitelistStatusElement = $("#whitelist-status") as HTMLDivElement;
const whitelistToggleElement = $("#whitelist-toggle") as HTMLInputElement;
//#endregion
if (store.readyState === "complete") main();
@ -34,7 +34,6 @@ async function main() {
if (!streamId) return;
setStreamStatusElement(streamId);
setWhitelistToggleElement(streamId);
store.addEventListener("change", () => setStreamStatusElement(streamId));
}
@ -42,58 +41,61 @@ function setStreamStatusElement(streamId: string) {
const streamIdLower = streamId.toLowerCase();
const status = store.state.streamStatuses[streamIdLower];
if (status) {
setProxyStatus(streamIdLower, status);
setWhitelistStatus(streamIdLower);
streamStatusElement.style.display = "flex";
if (status.redirected) {
redirectedElement.classList.remove("error");
redirectedElement.classList.add("success");
} else {
redirectedElement.classList.remove("success");
redirectedElement.classList.add("error");
}
streamIdElement.textContent = streamId;
if (status.reason) {
reasonElement.textContent = status.reason;
} else {
reasonElement.style.display = "none";
}
if (status.proxyCountry) {
proxyCountryElement.textContent = `Proxy country (Beta): ${status.proxyCountry}`;
} else {
proxyCountryElement.style.display = "none";
}
} else {
streamStatusElement.style.display = "none";
}
}
function setWhitelistToggleElement(streamId: string) {
const streamIdLower = streamId.toLowerCase();
const status = store.state.streamStatuses[streamIdLower];
if (status) {
whitelistToggle.checked =
store.state.whitelistedChannels.includes(streamId);
whitelistToggle.addEventListener("change", e => {
const target = e.target as HTMLInputElement;
if (target.checked) {
store.state.whitelistedChannels.push(streamId);
} else {
store.state.whitelistedChannels =
store.state.whitelistedChannels.filter(id => id !== streamId);
}
updateWhitelistToggleLabel(target.checked);
browser.tabs.reload();
});
updateWhitelistToggleLabel(whitelistToggle.checked);
whitelistToggleWrapper.style.display = "block";
function setProxyStatus(streamIdLower: string, status: StreamStatus) {
// Redirected
if (status.redirected) {
redirectedElement.classList.remove("error");
redirectedElement.classList.add("success");
} else {
whitelistToggleWrapper.style.display = "none";
redirectedElement.classList.remove("success");
redirectedElement.classList.add("error");
}
// Stream ID
streamIdElement.textContent = streamIdLower;
// Reason
if (status.reason) {
reasonElement.textContent = status.reason;
reasonElement.style.display = "";
} else {
reasonElement.style.display = "none";
}
// Proxy country
if (status.proxyCountry) {
proxyCountryElement.textContent = `Proxy country: ${status.proxyCountry}`;
proxyCountryElement.style.display = "";
} else {
proxyCountryElement.style.display = "none";
}
}
function updateWhitelistToggleLabel(checked: boolean) {
if (checked) {
whitelistToggleLabel.textContent = "✓ Whitelisted";
} else {
whitelistToggleLabel.textContent = "+ Whitelist";
}
function setWhitelistStatus(streamIdLower: string) {
const whitelistedChannelsLower = store.state.whitelistedChannels.map(id =>
id.toLowerCase()
);
const isWhitelisted = whitelistedChannelsLower.includes(streamIdLower);
whitelistStatusElement.setAttribute("data-whitelisted", `${isWhitelisted}`);
whitelistToggleElement.checked = isWhitelisted;
whitelistToggleElement.addEventListener("change", e => {
const target = e.target as HTMLInputElement;
const isWhitelisted = target.checked;
if (isWhitelisted) {
// Add stream ID to whitelist.
store.state.whitelistedChannels.push(streamIdLower);
} else {
// Remove stream ID from whitelist.
store.state.whitelistedChannels = store.state.whitelistedChannels.filter(
id => id !== streamIdLower
);
}
whitelistStatusElement.setAttribute("data-whitelisted", `${isWhitelisted}`);
browser.tabs.reload();
});
}

View File

@ -1,164 +1,246 @@
html {
-webkit-font-smoothing: antialiased;
background: #151619;
color: #c9cbcd;
font-family: "Inter", "Roobert", "Helvetica Neue", Helvetica, Arial,
@font-face {
src: url("../fonts/Inter-VariableFont_slnt\,wght.ttf");
font-family: "Inter";
}
:root {
--popup-width: 310px;
--font-family: "Inter", "Roobert", "Helvetica Neue", Helvetica, Arial,
sans-serif;
text-rendering: optimizeLegibility;
--background: #151619;
--background-secondary: #202127;
--background-tertiary: #292b32;
--border-radius: 8px;
--text-color: #c9cbcd;
--success-color: #43b581;
--error-color: #f04747;
--whitelisted-color: #baaadb;
}
body {
width: 300px;
margin-top: 0;
margin-right: auto;
margin-left: auto;
font-size: 100%;
width: var(--popup-width);
margin: 0;
padding: 0;
background-color: var(--background);
color: var(--text-color);
font-family: var(--font-family);
}
.container {
padding-bottom: 10px;
text-align: center;
}
.logo-wrapper {
margin: 30px 30px 15px 30px;
border-radius: 8px;
background-color: #202127;
}
.button-group {
main {
display: flex;
justify-content: center;
padding-top: 15px;
flex-direction: column;
align-items: center;
justify-content: start;
padding: 20px;
gap: 15px;
}
.button {
padding: 10px 20px;
border-radius: 6px;
color: #c3c4ca;
font-weight: bold;
text-decoration: none;
transition: all 150ms ease-in-out;
}
.button:hover {
background-color: #1d1f23;
}
.button:not(:first-of-type) {
margin-left: 15px;
}
.discord {
display: inline-block;
margin-right: 3px;
overflow: visible;
}
.button-arrow .arrow-icon {
width: 8px;
margin-bottom: -2px;
margin-left: 3px;
overflow: visible;
}
.icon {
margin-bottom: -3px;
}
.button-text {
margin-bottom: 10px;
}
.button-arrow .arrow-head {
transform: translateX(0);
transition: transform 150ms ease-in-out;
}
.button-arrow .arrow-body {
transform: scaleX(1);
opacity: 0;
transition: transform 150ms ease-in-out, opacity 150ms ease-in-out;
}
.button-arrow:hover .arrow-head {
transform: translateX(3px);
}
.button-arrow:hover .arrow-body {
transform: scaleX(2);
opacity: 1;
main > * {
width: 100%;
margin: 0;
overflow: hidden;
border-radius: var(--border-radius);
}
/* Update banner */
#update-banner {
display: none;
margin: 8px 8px 0 8px;
margin: 3px 3px 0 3px;
padding: 15px;
border-radius: 8px;
background-color: #7d5eba;
border: 1px solid #7d5eba;
border-radius: 5px;
background-color: #7d5eba4d;
color: #ffffff;
font-size: 10pt;
text-align: left;
font-size: 9pt;
}
#update-banner a,
#update-banner a:visited {
color: #ffffff;
#update-banner .update-banner-link,
#update-banner .update-banner-link:visited {
color: currentColor;
transition: opacity 100ms ease-in-out;
}
#update-banner a:hover,
#update-banner a:hover:visited {
color: #ffffff;
#update-banner .update-banner-link:hover,
#update-banner .update-banner-link:hover:visited {
color: currentColor;
opacity: 0.8;
}
/* Logo */
.logo-wrapper {
background-color: var(--background-secondary);
text-align: center;
}
.logo-wrapper > img {
width: 60%;
}
/* Stream status */
#stream-status {
display: none;
margin: 0 30px;
padding: 18px 14px 14px 14px;
gap: 7px;
border-bottom: 1px solid #3d4042;
border-radius: 8px;
border-bottom-right-radius: 0;
border-bottom-left-radius: 0;
background-color: #202127;
text-align: start;
flex-direction: column;
background-color: var(--background-secondary);
}
/* Proxy status */
#stream-status #proxy-status {
display: grid;
grid-template-rows: min-content min-content min-content;
grid-template-columns: min-content auto;
grid-template-areas:
"top-left top-right"
"middle-left middle-right"
"bottom-left bottom-right";
padding: 15px;
}
/* Proxy status icon */
#stream-status #redirected {
display: flex;
grid-area: top-left;
align-items: center;
justify-content: center;
margin-right: 10px;
}
#stream-status #redirected.success {
color: #43b581;
color: var(--success-color);
}
#stream-status #redirected.error {
color: #f04747;
color: var(--error-color);
}
/* Proxy status stream ID */
#stream-status #stream-id {
font-weight: bold;
grid-area: top-right;
margin: 0;
font-size: 11pt;
}
/* Proxy status reason */
#stream-status #reason {
grid-area: middle-right;
margin: 2px 0 0 0;
font-size: 9pt;
opacity: 0.8;
}
/* Proxy status country */
#stream-status #proxy-country {
display: inline-block;
margin-top: 10px;
grid-area: bottom-right;
margin: 10px 0 0 0;
font-size: 7pt;
opacity: 0.6;
}
#whitelist-toggle-wrapper {
display: none;
margin-top: 0;
margin-right: 30px;
margin-bottom: 0;
margin-left: 30px;
border-radius: 8px;
border-top-right-radius: 0;
border-top-left-radius: 0;
background-color: #202127;
transition: background-color 150ms ease-in-out;
/* Whitelist status */
#whitelist-status {
height: 40px;
border-top: 1px solid #3d4042;
background-color: var(--background-secondary);
text-align: center;
transition: background-color 100ms ease-in-out;
}
#whitelist-toggle-wrapper:hover {
background-color: #292b32;
#whitelist-status:hover {
background-color: var(--background-tertiary);
}
/* Whitelist toggle */
#whitelist-toggle {
display: none;
}
#whitelist-toggle:checked + #whitelist-toggle-label {
color: #baaadb;
/* Whitelist toggle icon */
#whitelist-status #whitelist-toggle-icon {
display: inline-flex;
align-items: center;
justify-content: center;
width: 20px;
height: 20px;
margin-right: 3px;
}
#whitelist-toggle-label {
display: block;
margin: 0;
padding: 10px 15px;
#whitelist-status[data-whitelisted="false"] #whitelist-toggle-icon .bi-plus {
display: initial;
}
#whitelist-status[data-whitelisted="false"]
#whitelist-toggle-icon
.bi-check-lg {
display: none;
}
#whitelist-status[data-whitelisted="true"] #whitelist-toggle-icon .bi-plus {
display: none;
}
#whitelist-status[data-whitelisted="true"] #whitelist-toggle-icon .bi-check-lg {
display: initial;
color: var(--whitelisted-color);
}
/* Whitelist toggle label */
#whitelist-status #whitelist-toggle-label {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
font-weight: bold;
font-size: 11pt;
cursor: pointer;
}
#whitelist-status[data-whitelisted="false"] #whitelist-toggle-label::after {
content: "Whitelist";
}
#whitelist-status[data-whitelisted="true"] #whitelist-toggle-label::after {
content: "Whitelisted";
color: var(--whitelisted-color);
}
/* Links */
.list {
margin: 0;
padding: 0;
list-style: none;
}
.list li {
border-bottom: 1px solid #3d4042;
}
.list li:last-child {
border-bottom: none;
}
.list .list-item,
.list .list-item:visited {
display: flex;
flex-direction: row;
align-items: center;
justify-content: start;
padding: 10px 15px;
background-color: var(--background-secondary);
color: var(--text-color);
text-decoration: none;
transition: background-color 100ms ease-in-out;
}
.list .list-item:hover,
.list .list-item:visited:hover {
background-color: var(--background-tertiary);
}
.list .list-item .list-item-icon {
display: flex;
align-items: center;
justify-content: center;
width: 16px;
height: 16px;
margin-right: 10px;
}
.list .list-item .list-item-title {
margin: 0 0 2px 0;
font-weight: bold;
font-size: 11pt;
}
.list .list-item .list-item-description {
margin: 0;
font-size: 8pt;
opacity: 0.8;
}

View File

@ -2,8 +2,9 @@ import type { State } from "./types";
export default function getDefaultState() {
return {
disableVodRedirect: true,
ignoredChannelSubscriptions: [],
checkForUpdates: false, // No need to check for updates on startup for CRX and XPI installs. The default value is set in the store initializer.
disableVodRedirect: true, // Most ad-blockers already remove ads from VODs (VOD proxying requires a Twitch token).
ignoredChannelSubscriptions: [], // Some channels might show ads even if you're subscribed to them.
isUpdateAvailable: false,
lastUpdateCheck: 0,
resetPlayerOnMidroll: true,

View File

@ -36,6 +36,13 @@ class Store {
const storage = await browser.storage[this._areaName].get(null);
this._state = getDefaultState();
// Check for updates on startup for unpacked installs.
if (browser.management?.getSelf != null) {
const info = await browser.management.getSelf();
if (info.installType === "development") {
this._state.checkForUpdates = true;
}
}
for (const [key, value] of Object.entries(storage)) {
this._state[key] = value;
}

View File

@ -5,6 +5,7 @@ export type ReadyState = "loading" | "complete";
export type StorageAreaName = "local" | "managed" | "sync";
export interface State {
checkForUpdates: boolean;
disableVodRedirect: boolean;
ignoredChannelSubscriptions: string[];
isUpdateAvailable: boolean;