♻️ Refactor project
232
.gitignore
vendored
Normal file
@ -0,0 +1,232 @@
|
|||||||
|
# File created using '.gitignore Generator' for Visual Studio Code: https://bit.ly/vscode-gig
|
||||||
|
|
||||||
|
# Created by https://www.toptal.com/developers/gitignore/api/windows,visualstudiocode,macos,node
|
||||||
|
# Edit at https://www.toptal.com/developers/gitignore?templates=windows,visualstudiocode,macos,node
|
||||||
|
|
||||||
|
### macOS ###
|
||||||
|
# General
|
||||||
|
.DS_Store
|
||||||
|
.AppleDouble
|
||||||
|
.LSOverride
|
||||||
|
|
||||||
|
# Icon must end with two \r
|
||||||
|
Icon
|
||||||
|
|
||||||
|
# Thumbnails
|
||||||
|
._*
|
||||||
|
|
||||||
|
# Files that might appear in the root of a volume
|
||||||
|
.DocumentRevisions-V100
|
||||||
|
.fseventsd
|
||||||
|
.Spotlight-V100
|
||||||
|
.TemporaryItems
|
||||||
|
.Trashes
|
||||||
|
.VolumeIcon.icns
|
||||||
|
.com.apple.timemachine.donotpresent
|
||||||
|
|
||||||
|
# Directories potentially created on remote AFP share
|
||||||
|
.AppleDB
|
||||||
|
.AppleDesktop
|
||||||
|
Network Trash Folder
|
||||||
|
Temporary Items
|
||||||
|
.apdisk
|
||||||
|
|
||||||
|
### macOS Patch ###
|
||||||
|
# iCloud generated files
|
||||||
|
*.icloud
|
||||||
|
|
||||||
|
### Node ###
|
||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
.pnpm-debug.log*
|
||||||
|
|
||||||
|
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||||
|
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||||
|
|
||||||
|
# Runtime data
|
||||||
|
pids
|
||||||
|
*.pid
|
||||||
|
*.seed
|
||||||
|
*.pid.lock
|
||||||
|
|
||||||
|
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||||
|
lib-cov
|
||||||
|
|
||||||
|
# Coverage directory used by tools like istanbul
|
||||||
|
coverage
|
||||||
|
*.lcov
|
||||||
|
|
||||||
|
# nyc test coverage
|
||||||
|
.nyc_output
|
||||||
|
|
||||||
|
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||||
|
.grunt
|
||||||
|
|
||||||
|
# Bower dependency directory (https://bower.io/)
|
||||||
|
bower_components
|
||||||
|
|
||||||
|
# node-waf configuration
|
||||||
|
.lock-wscript
|
||||||
|
|
||||||
|
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||||
|
build/Release
|
||||||
|
|
||||||
|
# Dependency directories
|
||||||
|
node_modules/
|
||||||
|
jspm_packages/
|
||||||
|
|
||||||
|
# Snowpack dependency directory (https://snowpack.dev/)
|
||||||
|
web_modules/
|
||||||
|
|
||||||
|
# TypeScript cache
|
||||||
|
*.tsbuildinfo
|
||||||
|
|
||||||
|
# Optional npm cache directory
|
||||||
|
.npm
|
||||||
|
|
||||||
|
# Optional eslint cache
|
||||||
|
.eslintcache
|
||||||
|
|
||||||
|
# Optional stylelint cache
|
||||||
|
.stylelintcache
|
||||||
|
|
||||||
|
# Microbundle cache
|
||||||
|
.rpt2_cache/
|
||||||
|
.rts2_cache_cjs/
|
||||||
|
.rts2_cache_es/
|
||||||
|
.rts2_cache_umd/
|
||||||
|
|
||||||
|
# Optional REPL history
|
||||||
|
.node_repl_history
|
||||||
|
|
||||||
|
# Output of 'npm pack'
|
||||||
|
*.tgz
|
||||||
|
|
||||||
|
# Yarn Integrity file
|
||||||
|
.yarn-integrity
|
||||||
|
|
||||||
|
# dotenv environment variable files
|
||||||
|
.env
|
||||||
|
.env.development.local
|
||||||
|
.env.test.local
|
||||||
|
.env.production.local
|
||||||
|
.env.local
|
||||||
|
|
||||||
|
# parcel-bundler cache (https://parceljs.org/)
|
||||||
|
.cache
|
||||||
|
.parcel-cache
|
||||||
|
|
||||||
|
# Next.js build output
|
||||||
|
.next
|
||||||
|
out
|
||||||
|
|
||||||
|
# Nuxt.js build / generate output
|
||||||
|
.nuxt
|
||||||
|
dist
|
||||||
|
|
||||||
|
# Gatsby files
|
||||||
|
.cache/
|
||||||
|
# Comment in the public line in if your project uses Gatsby and not Next.js
|
||||||
|
# https://nextjs.org/blog/next-9-1#public-directory-support
|
||||||
|
# public
|
||||||
|
|
||||||
|
# vuepress build output
|
||||||
|
.vuepress/dist
|
||||||
|
|
||||||
|
# vuepress v2.x temp and cache directory
|
||||||
|
.temp
|
||||||
|
|
||||||
|
# Docusaurus cache and generated files
|
||||||
|
.docusaurus
|
||||||
|
|
||||||
|
# Serverless directories
|
||||||
|
.serverless/
|
||||||
|
|
||||||
|
# FuseBox cache
|
||||||
|
.fusebox/
|
||||||
|
|
||||||
|
# DynamoDB Local files
|
||||||
|
.dynamodb/
|
||||||
|
|
||||||
|
# TernJS port file
|
||||||
|
.tern-port
|
||||||
|
|
||||||
|
# Stores VSCode versions used for testing VSCode extensions
|
||||||
|
.vscode-test
|
||||||
|
|
||||||
|
# yarn v2
|
||||||
|
.yarn/cache
|
||||||
|
.yarn/unplugged
|
||||||
|
.yarn/build-state.yml
|
||||||
|
.yarn/install-state.gz
|
||||||
|
.pnp.*
|
||||||
|
|
||||||
|
### Node Patch ###
|
||||||
|
# Serverless Webpack directories
|
||||||
|
.webpack/
|
||||||
|
|
||||||
|
# Optional stylelint cache
|
||||||
|
|
||||||
|
# SvelteKit build / generate output
|
||||||
|
.svelte-kit
|
||||||
|
|
||||||
|
### VisualStudioCode ###
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/settings.json
|
||||||
|
!.vscode/tasks.json
|
||||||
|
!.vscode/launch.json
|
||||||
|
!.vscode/extensions.json
|
||||||
|
!.vscode/*.code-snippets
|
||||||
|
|
||||||
|
# Local History for Visual Studio Code
|
||||||
|
.history/
|
||||||
|
|
||||||
|
# Built Visual Studio Code Extensions
|
||||||
|
*.vsix
|
||||||
|
|
||||||
|
### VisualStudioCode Patch ###
|
||||||
|
# Ignore all local history of files
|
||||||
|
.history
|
||||||
|
.ionide
|
||||||
|
|
||||||
|
# Support for Project snippet scope
|
||||||
|
.vscode/*.code-snippets
|
||||||
|
|
||||||
|
# Ignore code-workspaces
|
||||||
|
*.code-workspace
|
||||||
|
|
||||||
|
### Windows ###
|
||||||
|
# Windows thumbnail cache files
|
||||||
|
Thumbs.db
|
||||||
|
Thumbs.db:encryptable
|
||||||
|
ehthumbs.db
|
||||||
|
ehthumbs_vista.db
|
||||||
|
|
||||||
|
# Dump file
|
||||||
|
*.stackdump
|
||||||
|
|
||||||
|
# Folder config file
|
||||||
|
[Dd]esktop.ini
|
||||||
|
|
||||||
|
# Recycle Bin used on file shares
|
||||||
|
$RECYCLE.BIN/
|
||||||
|
|
||||||
|
# Windows Installer files
|
||||||
|
*.cab
|
||||||
|
*.msi
|
||||||
|
*.msix
|
||||||
|
*.msm
|
||||||
|
*.msp
|
||||||
|
|
||||||
|
# Windows shortcuts
|
||||||
|
*.lnk
|
||||||
|
|
||||||
|
# End of https://www.toptal.com/developers/gitignore/api/windows,visualstudiocode,macos,node
|
||||||
|
|
||||||
|
# Custom rules (everything added below won't be overriden by 'Generate .gitignore File' if you use 'Update' option)
|
||||||
|
|
3
.prettierrc.json
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"arrowParens": "avoid"
|
||||||
|
}
|
59
README.md
@ -1,12 +1,59 @@
|
|||||||
# TTV.LOL browser extensions
|
<h1 align="center">
|
||||||
|
<img src="src/images/icon.png" height="100" width="100" alt="Icon" />
|
||||||
|
<br />
|
||||||
|
TTV LOL
|
||||||
|
<br />
|
||||||
|
</h1>
|
||||||
|
|
||||||
This respository contains the browser extensions for [TTV.LOL](https://ttv.lol).
|
<div align="center">
|
||||||
|
<a href="https://github.com/younesaassila/ttv-lol/issues">
|
||||||
|
<img
|
||||||
|
alt="GitHub issues"
|
||||||
|
src="https://img.shields.io/github/issues/younesaassila/ttv-lol"
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
<a href="https://github.com/younesaassila/ttv-lol/network">
|
||||||
|
<img
|
||||||
|
alt="GitHub forks"
|
||||||
|
src="https://img.shields.io/github/forks/younesaassila/ttv-lol"
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
<a href="https://github.com/younesaassila/ttv-lol/stargazers">
|
||||||
|
<img
|
||||||
|
alt="GitHub stars"
|
||||||
|
src="https://img.shields.io/github/stars/younesaassila/ttv-lol"
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
# Chrome webstore
|
<br />
|
||||||
|
|
||||||
The extension can be installed via the chrome webstore [here](https://chrome.google.com/webstore/detail/ttv-lol/ofbbahodfeppoklmgjiokgfdgcndngjm).
|
```text
|
||||||
|
This is a fork of the original project at https://github.com/TTV-LOL/extensions
|
||||||
|
```
|
||||||
|
|
||||||
# Firefox Addon
|
>
|
||||||
|
|
||||||
The extension can be installed via the Firefox addons store [here](https://addons.mozilla.org/en-US/firefox/addon/ttv-lol/).
|
[TTV LOL](https://ttv.lol/) removes livestream ads from [Twitch](https://www.twitch.tv/).
|
||||||
|
|
||||||
|
This fork:
|
||||||
|
|
||||||
|
- disables TTV LOL for channels you are subscribed to.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
### Chrome
|
||||||
|
|
||||||
|
1. Download the latest version of this extension in the "Releases" section (ZIP file)
|
||||||
|
1. Unzip the ZIP file you just downloaded
|
||||||
|
1. Go to `chrome://extensions`
|
||||||
|
1. Turn on `Developer mode`
|
||||||
|
1. Click on `Load unpacked`
|
||||||
|
1. Select the unzipped folder you just created
|
||||||
|
|
||||||
|
### Firefox
|
||||||
|
|
||||||
|
1. Download the latest version of this extension in the "Releases" section (ZIP file)
|
||||||
|
1. Go to `about:addons`
|
||||||
|
1. Click on the gear icon then select "Install Add-on From File…"
|
||||||
|
1. Select the ZIP file you just downloaded
|
||||||
|
@ -1,68 +0,0 @@
|
|||||||
html {
|
|
||||||
width: 300px;
|
|
||||||
height: 100px;
|
|
||||||
background: #151619;
|
|
||||||
color: #c9cbcd;
|
|
||||||
font-family: Open Sans,Segoe UI,sans-serif;
|
|
||||||
-webkit-font-smoothing: antialiased;
|
|
||||||
text-rendering: optimizeLegibility;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.container {
|
|
||||||
text-align: center;
|
|
||||||
padding-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.button-group {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.button {
|
|
||||||
border-radius: 6px;
|
|
||||||
color: #c3c4ca;
|
|
||||||
font-weight: bold;
|
|
||||||
padding: 10px 20px;
|
|
||||||
text-decoration: none;
|
|
||||||
transition: all 150ms ease-in-out;
|
|
||||||
}
|
|
||||||
.button:hover {
|
|
||||||
background-color: #1d1f23;
|
|
||||||
}
|
|
||||||
.button:not(:first-of-type) {
|
|
||||||
margin-left: 15px;
|
|
||||||
}
|
|
||||||
.discord {
|
|
||||||
overflow: visible;
|
|
||||||
margin-right: 3px;
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
.button-arrow .arrow-icon {
|
|
||||||
overflow: visible;
|
|
||||||
margin-left: 3px;
|
|
||||||
margin-bottom: -2px;
|
|
||||||
width: 8px;
|
|
||||||
}
|
|
||||||
.icon {
|
|
||||||
margin-bottom: -3px;
|
|
||||||
}
|
|
||||||
.buton-text{
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
.button-arrow .arrow-head {
|
|
||||||
transform: translateX(0);
|
|
||||||
transition: transform 150ms ease-in-out;
|
|
||||||
}
|
|
||||||
.button-arrow .arrow-body {
|
|
||||||
opacity: 0;
|
|
||||||
transform: scaleX(1);
|
|
||||||
transition: transform 150ms ease-in-out, opacity 150ms ease-in-out;
|
|
||||||
}
|
|
||||||
.button-arrow:hover .arrow-head {
|
|
||||||
transform: translateX(3px);
|
|
||||||
}
|
|
||||||
.button-arrow:hover .arrow-body {
|
|
||||||
opacity: 1;
|
|
||||||
transform: scaleX(2);
|
|
||||||
}
|
|
@ -1,48 +0,0 @@
|
|||||||
<html>
|
|
||||||
<head>
|
|
||||||
<link rel="stylesheet" href="../css/styles.css" />
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<div class="container">
|
|
||||||
<div style="background-color: #202127; border-radius: 8px; margin: 30px;">
|
|
||||||
<img width="60%" src="../img/ttvlol.png">
|
|
||||||
</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">
|
|
||||||
<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>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
@ -1,57 +0,0 @@
|
|||||||
function stripUnusedParams(str, params) {
|
|
||||||
if (!params) {
|
|
||||||
params = [ 'token', 'sig' ];
|
|
||||||
}
|
|
||||||
var tempUrl = new URL('https://localhost/' + str);
|
|
||||||
for (var i = 0; i < params.length; i++) {
|
|
||||||
tempUrl.searchParams.delete(params[i]);
|
|
||||||
}
|
|
||||||
return tempUrl.pathname.substring(1) + tempUrl.search;
|
|
||||||
}
|
|
||||||
|
|
||||||
function onPlaylistBeforeRequest(details) {
|
|
||||||
|
|
||||||
details.url = stripUnusedParams(details.url, null);
|
|
||||||
|
|
||||||
// (hls\/|vod\/)(.+?)$
|
|
||||||
const match = /(hls|vod)\/(.+?)$/gim.exec(details.url);
|
|
||||||
|
|
||||||
if (match !== null && match.length > 1) {
|
|
||||||
var playlistType = match[1] == "vod" ? "vod" : "playlist";
|
|
||||||
|
|
||||||
var req = new XMLHttpRequest();
|
|
||||||
req.open("GET", `https://api.ttv.lol/ping`, false);
|
|
||||||
req.send();
|
|
||||||
|
|
||||||
// validate that our API is online, if not fallback to standard stream with ads
|
|
||||||
if (req.status != 200) {
|
|
||||||
return {
|
|
||||||
redirectUrl: details.url
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
return {
|
|
||||||
redirectUrl: `https://api.ttv.lol/${playlistType}/${encodeURIComponent(match[2])}`,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
chrome.webRequest.onBeforeRequest.addListener(
|
|
||||||
onPlaylistBeforeRequest,
|
|
||||||
{ urls: ["https://usher.ttvnw.net/api/channel/hls/*", "https://usher.ttvnw.net/vod/*"] },
|
|
||||||
["blocking", "extraHeaders"]
|
|
||||||
);
|
|
||||||
|
|
||||||
function onBeforeSendHeaders(req) {
|
|
||||||
req.requestHeaders.push({ name: 'X-Donate-To', value: "https://ttv.lol/donate" })
|
|
||||||
return {
|
|
||||||
requestHeaders: req.requestHeaders
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
chrome.webRequest.onBeforeSendHeaders.addListener(
|
|
||||||
onBeforeSendHeaders,
|
|
||||||
{ urls: ["https://api.ttv.lol/playlist/*", "https://api.ttv.lol/vod/*"] },
|
|
||||||
["blocking", "requestHeaders"]
|
|
||||||
);
|
|
@ -1,29 +0,0 @@
|
|||||||
{
|
|
||||||
"background": {
|
|
||||||
"persistent": true,
|
|
||||||
"scripts": [
|
|
||||||
"js/background.js"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"browser_action": {
|
|
||||||
"default_icon": {
|
|
||||||
"128": "images/icon.png"
|
|
||||||
},
|
|
||||||
"default_popup": "common/html/popup.html",
|
|
||||||
"default_title": "TTV LOL"
|
|
||||||
},
|
|
||||||
"description": "TTV LOL",
|
|
||||||
"icons": {
|
|
||||||
"128": "images/icon.png"
|
|
||||||
},
|
|
||||||
"manifest_version": 2,
|
|
||||||
"name": "TTV LOL",
|
|
||||||
"permissions": [
|
|
||||||
"webRequest",
|
|
||||||
"webRequestBlocking",
|
|
||||||
"https://*.twitch.tv/*",
|
|
||||||
"https://usher.ttvnw.net/*",
|
|
||||||
"https://api.ttv.lol/*"
|
|
||||||
],
|
|
||||||
"version": "0.0.0.4"
|
|
||||||
}
|
|
@ -1,71 +0,0 @@
|
|||||||
html, body {
|
|
||||||
width: 300px;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
html {
|
|
||||||
background: #151619;
|
|
||||||
color: #c9cbcd;
|
|
||||||
font-family: Open Sans,Segoe UI,sans-serif;
|
|
||||||
-webkit-font-smoothing: antialiased;
|
|
||||||
text-rendering: optimizeLegibility;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.container {
|
|
||||||
text-align: center;
|
|
||||||
padding-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.button-group {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.button {
|
|
||||||
border-radius: 6px;
|
|
||||||
color: #c3c4ca;
|
|
||||||
font-weight: bold;
|
|
||||||
padding: 10px 20px;
|
|
||||||
text-decoration: none;
|
|
||||||
transition: all 150ms ease-in-out;
|
|
||||||
}
|
|
||||||
.button:hover {
|
|
||||||
background-color: #1d1f23;
|
|
||||||
}
|
|
||||||
.button:not(:first-of-type) {
|
|
||||||
margin-left: 15px;
|
|
||||||
}
|
|
||||||
.discord {
|
|
||||||
overflow: visible;
|
|
||||||
margin-right: 3px;
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
.button-arrow .arrow-icon {
|
|
||||||
overflow: visible;
|
|
||||||
margin-left: 3px;
|
|
||||||
margin-bottom: -2px;
|
|
||||||
width: 8px;
|
|
||||||
}
|
|
||||||
.icon {
|
|
||||||
margin-bottom: -3px;
|
|
||||||
}
|
|
||||||
.buton-text{
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
.button-arrow .arrow-head {
|
|
||||||
transform: translateX(0);
|
|
||||||
transition: transform 150ms ease-in-out;
|
|
||||||
}
|
|
||||||
.button-arrow .arrow-body {
|
|
||||||
opacity: 0;
|
|
||||||
transform: scaleX(1);
|
|
||||||
transition: transform 150ms ease-in-out, opacity 150ms ease-in-out;
|
|
||||||
}
|
|
||||||
.button-arrow:hover .arrow-head {
|
|
||||||
transform: translateX(3px);
|
|
||||||
}
|
|
||||||
.button-arrow:hover .arrow-body {
|
|
||||||
opacity: 1;
|
|
||||||
transform: scaleX(2);
|
|
||||||
}
|
|
Before Width: | Height: | Size: 70 KiB |
Before Width: | Height: | Size: 52 KiB |
Before Width: | Height: | Size: 4.0 KiB |
@ -1,58 +0,0 @@
|
|||||||
function stripUnusedParams(str, params) {
|
|
||||||
if (!params) {
|
|
||||||
params = [ 'token', 'sig' ];
|
|
||||||
}
|
|
||||||
var tempUrl = new URL('https://localhost/' + str);
|
|
||||||
for (var i = 0; i < params.length; i++) {
|
|
||||||
tempUrl.searchParams.delete(params[i]);
|
|
||||||
}
|
|
||||||
return tempUrl.pathname.substring(1) + tempUrl.search;
|
|
||||||
}
|
|
||||||
|
|
||||||
function onPlaylistBeforeRequest(details) {
|
|
||||||
|
|
||||||
details.url = stripUnusedParams(details.url, null);
|
|
||||||
|
|
||||||
// (hls\/|vod\/)(.+?)$
|
|
||||||
const match = /(hls|vod)\/(.+?)$/gim.exec(details.url);
|
|
||||||
|
|
||||||
if (match !== null && match.length > 1) {
|
|
||||||
var playlistType = match[1] == "vod" ? "vod" : "playlist";
|
|
||||||
|
|
||||||
return new Promise(resolve => {
|
|
||||||
fetch(
|
|
||||||
'https://api.ttv.lol/ping',
|
|
||||||
{
|
|
||||||
method: 'GET',
|
|
||||||
}).then(r => {
|
|
||||||
if (r.status == 200) {
|
|
||||||
resolve({ redirectUrl: `https://api.ttv.lol/${playlistType}/${encodeURIComponent(match[2])}` });
|
|
||||||
} else {
|
|
||||||
resolve({});
|
|
||||||
}
|
|
||||||
}).catch((error) => {
|
|
||||||
resolve({});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
browser.webRequest.onBeforeRequest.addListener(
|
|
||||||
onPlaylistBeforeRequest,
|
|
||||||
{ urls: ["https://usher.ttvnw.net/api/channel/hls/*", "https://usher.ttvnw.net/vod/*"] },
|
|
||||||
["blocking"]
|
|
||||||
);
|
|
||||||
|
|
||||||
function onBeforeSendHeaders(req) {
|
|
||||||
req.requestHeaders.push({ name: 'X-Donate-To', value: "https://ttv.lol/donate" })
|
|
||||||
return {
|
|
||||||
requestHeaders: req.requestHeaders
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
browser.webRequest.onBeforeSendHeaders.addListener(
|
|
||||||
onBeforeSendHeaders,
|
|
||||||
{ urls: ["https://api.ttv.lol/playlist/*", "https://api.ttv.lol/vod/*"] },
|
|
||||||
["blocking", "requestHeaders"]
|
|
||||||
);
|
|
@ -1,29 +0,0 @@
|
|||||||
{
|
|
||||||
"background": {
|
|
||||||
"persistent": true,
|
|
||||||
"scripts": [
|
|
||||||
"js/background.js"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"browser_action": {
|
|
||||||
"default_icon": {
|
|
||||||
"128": "images/icon.png"
|
|
||||||
},
|
|
||||||
"default_popup": "common/html/popup.html",
|
|
||||||
"default_title": "TTV LOL"
|
|
||||||
},
|
|
||||||
"description": "TTV LOL",
|
|
||||||
"icons": {
|
|
||||||
"128": "images/icon.png"
|
|
||||||
},
|
|
||||||
"manifest_version": 2,
|
|
||||||
"name": "TTV LOL",
|
|
||||||
"permissions": [
|
|
||||||
"webRequest",
|
|
||||||
"webRequestBlocking",
|
|
||||||
"https://*.twitch.tv/*",
|
|
||||||
"https://usher.ttvnw.net/*",
|
|
||||||
"https://api.ttv.lol/*"
|
|
||||||
],
|
|
||||||
"version": "0.0.0.4"
|
|
||||||
}
|
|
4364
package-lock.json
generated
Normal file
38
package.json
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
{
|
||||||
|
"name": "ttv-lol",
|
||||||
|
"version": "1.0.0-younesaassila",
|
||||||
|
"description": "TTV LOL removes livestream ads from twitch.tv",
|
||||||
|
"targets": {
|
||||||
|
"webext-dev": {
|
||||||
|
"sourceMap": {
|
||||||
|
"inline": true,
|
||||||
|
"inlineSources": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"webext-prod": {}
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"dev": "parcel src/manifest.json --host localhost --target webext-dev",
|
||||||
|
"lint": "prettier --write ./src",
|
||||||
|
"build": "parcel build src/manifest.json --target webext-prod"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"twitch",
|
||||||
|
"web-extension",
|
||||||
|
"adblocker"
|
||||||
|
],
|
||||||
|
"author": "TTV-LOL (https://github.com/TTV-LOL)",
|
||||||
|
"contributors": [
|
||||||
|
"Younes Aassila (https://github.com/younesaassila)"
|
||||||
|
],
|
||||||
|
"license": "UNLICENSED",
|
||||||
|
"devDependencies": {
|
||||||
|
"@parcel/config-webextension": "^2.5.0",
|
||||||
|
"@types/webextension-polyfill": "^0.8.3",
|
||||||
|
"parcel": "^2.5.0",
|
||||||
|
"prettier": "^2.6.2",
|
||||||
|
"typescript": "^4.6.4",
|
||||||
|
"webextension-polyfill": "^0.9.0"
|
||||||
|
},
|
||||||
|
"private": true
|
||||||
|
}
|
70
src/common/css/styles.css
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
html,
|
||||||
|
body {
|
||||||
|
width: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
html {
|
||||||
|
background: #151619;
|
||||||
|
color: #c9cbcd;
|
||||||
|
font-family: Open Sans, Segoe UI, sans-serif;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
text-rendering: optimizeLegibility;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
text-align: center;
|
||||||
|
padding-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-group {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
border-radius: 6px;
|
||||||
|
color: #c3c4ca;
|
||||||
|
font-weight: bold;
|
||||||
|
padding: 10px 20px;
|
||||||
|
text-decoration: none;
|
||||||
|
transition: all 150ms ease-in-out;
|
||||||
|
}
|
||||||
|
.button:hover {
|
||||||
|
background-color: #1d1f23;
|
||||||
|
}
|
||||||
|
.button:not(:first-of-type) {
|
||||||
|
margin-left: 15px;
|
||||||
|
}
|
||||||
|
.discord {
|
||||||
|
overflow: visible;
|
||||||
|
margin-right: 3px;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.button-arrow .arrow-icon {
|
||||||
|
overflow: visible;
|
||||||
|
margin-left: 3px;
|
||||||
|
margin-bottom: -2px;
|
||||||
|
width: 8px;
|
||||||
|
}
|
||||||
|
.icon {
|
||||||
|
margin-bottom: -3px;
|
||||||
|
}
|
||||||
|
.buton-text {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
.button-arrow .arrow-head {
|
||||||
|
transform: translateX(0);
|
||||||
|
transition: transform 150ms ease-in-out;
|
||||||
|
}
|
||||||
|
.button-arrow .arrow-body {
|
||||||
|
opacity: 0;
|
||||||
|
transform: scaleX(1);
|
||||||
|
transition: transform 150ms ease-in-out, opacity 150ms ease-in-out;
|
||||||
|
}
|
||||||
|
.button-arrow:hover .arrow-head {
|
||||||
|
transform: translateX(3px);
|
||||||
|
}
|
||||||
|
.button-arrow:hover .arrow-body {
|
||||||
|
opacity: 1;
|
||||||
|
transform: scaleX(2);
|
||||||
|
}
|
Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 70 KiB |
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 52 KiB |
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 4.0 KiB |
27
src/manifest.json
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"manifest_version": 2,
|
||||||
|
"name": "TTV LOL (Younes Aassila's Fork)",
|
||||||
|
"description": "TTV LOL removes livestream ads from twitch.tv",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"background": {
|
||||||
|
"persistent": true,
|
||||||
|
"scripts": ["ts/background.ts"]
|
||||||
|
},
|
||||||
|
"browser_action": {
|
||||||
|
"default_icon": {
|
||||||
|
"128": "images/icon.png"
|
||||||
|
},
|
||||||
|
"default_title": "TTV LOL",
|
||||||
|
"default_popup": "common/html/popup.html"
|
||||||
|
},
|
||||||
|
"icons": {
|
||||||
|
"128": "images/icon.png"
|
||||||
|
},
|
||||||
|
"permissions": [
|
||||||
|
"webRequest",
|
||||||
|
"webRequestBlocking",
|
||||||
|
"https://*.twitch.tv/*",
|
||||||
|
"https://usher.ttvnw.net/*",
|
||||||
|
"https://api.ttv.lol/*"
|
||||||
|
]
|
||||||
|
}
|
59
src/ts/background.ts
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
import browser, { WebRequest } from "webextension-polyfill";
|
||||||
|
import { PlaylistType } from "../types";
|
||||||
|
|
||||||
|
function onBeforeRequest(details: WebRequest.OnBeforeRequestDetailsType) {
|
||||||
|
const match = /(hls|vod)\/(.+?)$/gim.exec(details.url);
|
||||||
|
if (match == null) return {};
|
||||||
|
|
||||||
|
const [_, type, path] = match;
|
||||||
|
if (type == null || path == null) return {};
|
||||||
|
|
||||||
|
const playlistType =
|
||||||
|
type.toLowerCase() === "vod" ? PlaylistType.VOD : PlaylistType.Playlist;
|
||||||
|
|
||||||
|
// Synchronous XMLHttpRequest is required for the plugin to work in Chrome.
|
||||||
|
const request = new XMLHttpRequest();
|
||||||
|
request.open("GET", `https://api.ttv.lol/ping`, false);
|
||||||
|
request.send();
|
||||||
|
|
||||||
|
if (request.status === 200) {
|
||||||
|
console.info("[TTV LOL] Successfully pinged TTV LOL's server.");
|
||||||
|
return {
|
||||||
|
redirectUrl: `https://api.ttv.lol/${playlistType}/${encodeURIComponent(
|
||||||
|
path
|
||||||
|
)}`,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
browser.webRequest.onBeforeRequest.addListener(
|
||||||
|
onBeforeRequest,
|
||||||
|
{
|
||||||
|
urls: [
|
||||||
|
"https://usher.ttvnw.net/api/channel/hls/*",
|
||||||
|
"https://usher.ttvnw.net/vod/*",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
["blocking"]
|
||||||
|
);
|
||||||
|
|
||||||
|
function onBeforeSendHeaders(
|
||||||
|
details: WebRequest.OnBeforeSendHeadersDetailsType
|
||||||
|
) {
|
||||||
|
console.log(`[TTV LOL] ${details.method} ${details.url}`);
|
||||||
|
details.requestHeaders.push({
|
||||||
|
name: "X-Donate-To",
|
||||||
|
value: "https://ttv.lol/donate",
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
requestHeaders: details.requestHeaders,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
browser.webRequest.onBeforeSendHeaders.addListener(
|
||||||
|
onBeforeSendHeaders,
|
||||||
|
{ urls: ["https://api.ttv.lol/playlist/*", "https://api.ttv.lol/vod/*"] },
|
||||||
|
["blocking", "requestHeaders"]
|
||||||
|
);
|
4
src/types.ts
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
export enum PlaylistType {
|
||||||
|
Playlist = "playlist",
|
||||||
|
VOD = "vod",
|
||||||
|
}
|