mirror of
https://github.com/ajayyy/SponsorBlock.git
synced 2025-12-08 20:47:11 +03:00
Merge branch 'master' of https://github.com/ajayyy/SponsorBlock into chapters
This commit is contained in:
@@ -72,7 +72,7 @@ You must have [Node.js 16](https://nodejs.org/) and npm installed.
|
||||
|
||||
- You can also run `npm run build` (for Chrome) or `npm run build:firefox` (for Firefox) to generate a production build.
|
||||
|
||||
4. The built extension is now in `dist/`. You can load it in Chrome as an [unpacked extension](https://developer.chrome.com/docs/extensions/mv3/getstarted/#manifest) or in Firefox as a [temporary extension](https://developer.mozilla.org/en-US/docs/Tools/about:debugging#loading_a_temporary_extension).
|
||||
4. The built extension is now in `dist/`. You can load this folder directly in Chrome as an [unpacked extension](https://developer.chrome.com/docs/extensions/mv3/getstarted/#manifest), or convert it to a zip file to load it as a [temporary extension](https://developer.mozilla.org/en-US/docs/Tools/about:debugging#loading_a_temporary_extension) in Firefox.
|
||||
|
||||
### Developing with a clean profile and hot reloading
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
["yewtu.be","invidious.snopyta.org","vid.puffyan.us","invidious.kavin.rocks","invidio.xamh.de","inv.riverside.rocks","invidious-us.kavin.rocks","invidious.osi.kr","tube.cthd.icu","yt.artemislena.eu","youtube.076.ne.jp","invidious.namazso.eu"]
|
||||
["yewtu.be","vid.puffyan.us","invidious.snopyta.org","invidious.kavin.rocks","invidio.xamh.de","inv.riverside.rocks","invidious-us.kavin.rocks","invidious.osi.kr","tube.cthd.icu","invidious.flokinet.to","yt.artemislena.eu","youtube.076.ne.jp","invidious.namazso.eu"]
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "__MSG_fullName__",
|
||||
"short_name": "SponsorBlock",
|
||||
"version": "4.1.6",
|
||||
"version": "4.2.1",
|
||||
"default_locale": "en",
|
||||
"description": "__MSG_Description__",
|
||||
"homepage_url": "https://sponsor.ajay.app",
|
||||
|
||||
50
package-lock.json
generated
50
package-lock.json
generated
@@ -4256,24 +4256,6 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/copy-webpack-plugin/node_modules/schema-utils": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz",
|
||||
"integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/json-schema": "^7.0.8",
|
||||
"ajv": "^6.12.5",
|
||||
"ajv-keywords": "^3.5.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.13.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/webpack"
|
||||
}
|
||||
},
|
||||
"node_modules/copy-webpack-plugin/node_modules/slash": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz",
|
||||
@@ -9990,8 +9972,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/minimist": {
|
||||
"version": "1.2.5",
|
||||
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
|
||||
"version": "1.2.6",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
|
||||
"integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/mkdirp": {
|
||||
@@ -10007,9 +9990,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/moment": {
|
||||
"version": "2.29.1",
|
||||
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz",
|
||||
"integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==",
|
||||
"version": "2.29.2",
|
||||
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.2.tgz",
|
||||
"integrity": "sha512-UgzG4rvxYpN15jgCmVJwac49h9ly9NurikMWGPdVxm8GZD6XjkKPxDTjQQ43gtGgnV3X0cAyWDdP2Wexoquifg==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"engines": {
|
||||
@@ -17279,16 +17262,6 @@
|
||||
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
|
||||
"dev": true
|
||||
},
|
||||
"schema-utils": {
|
||||
"version": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz",
|
||||
"integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/json-schema": "^7.0.8",
|
||||
"ajv": "^6.12.5",
|
||||
"ajv-keywords": "^3.5.2"
|
||||
}
|
||||
},
|
||||
"slash": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz",
|
||||
@@ -21575,8 +21548,9 @@
|
||||
}
|
||||
},
|
||||
"minimist": {
|
||||
"version": "1.2.5",
|
||||
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
|
||||
"version": "1.2.6",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
|
||||
"integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
|
||||
"dev": true
|
||||
},
|
||||
"mkdirp": {
|
||||
@@ -21589,9 +21563,9 @@
|
||||
}
|
||||
},
|
||||
"moment": {
|
||||
"version": "2.29.1",
|
||||
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz",
|
||||
"integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==",
|
||||
"version": "2.29.2",
|
||||
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.2.tgz",
|
||||
"integrity": "sha512-UgzG4rvxYpN15jgCmVJwac49h9ly9NurikMWGPdVxm8GZD6XjkKPxDTjQQ43gtGgnV3X0cAyWDdP2Wexoquifg==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
|
||||
@@ -562,7 +562,7 @@
|
||||
"description": "Short description for this category"
|
||||
},
|
||||
"category_interaction": {
|
||||
"message": "Promemoria di Interazione (Sottoscrizione)"
|
||||
"message": "Promemoria d'Interazione (Iscrizione)"
|
||||
},
|
||||
"category_interaction_description": {
|
||||
"message": "Quando nel punto centrale del contenuto è presente un breve promemoria per aggiunta di mi piace, iscrizione o seguito. Se dovesse risultare esteso o riguardare qualcosa di specifico, potrebbe essere un'autopromozione."
|
||||
|
||||
@@ -118,6 +118,34 @@
|
||||
"submitCheck": {
|
||||
"message": "Tem a certeza que pretende submeter?"
|
||||
},
|
||||
"whitelistChannel": {
|
||||
"message": "Meter canal na Lista Branca"
|
||||
},
|
||||
"removeFromWhitelist": {
|
||||
"message": "Remover canal da Lista Branca"
|
||||
},
|
||||
"voteOnTime": {
|
||||
"message": "Votar em um segmento"
|
||||
},
|
||||
"Submissions": {
|
||||
"message": "Submissões"
|
||||
},
|
||||
"savedPeopleFrom": {
|
||||
"message": "Salvaste pessoas de "
|
||||
},
|
||||
"viewLeaderboard": {
|
||||
"message": "Tabela de Classificação"
|
||||
},
|
||||
"recordTimesDescription": {
|
||||
"message": "Enviar"
|
||||
},
|
||||
"submissionEditHint": {
|
||||
"message": "A edição da seção aparecerá depois que você clicar em enviar",
|
||||
"description": "Appears in the popup to inform them that editing has been moved to the video player."
|
||||
},
|
||||
"popupHint": {
|
||||
"message": "Dica: Você pode configurar atalhos de teclado para enviar nas opções"
|
||||
},
|
||||
"clearTimesButton": {
|
||||
"message": "Limpar Intervalos"
|
||||
},
|
||||
@@ -127,9 +155,15 @@
|
||||
"publicStats": {
|
||||
"message": "Isto é usado na página pública de estatísticas que mostra o quanto já contríbuíu. Veje-a"
|
||||
},
|
||||
"Username": {
|
||||
"message": "Nome de Utilizador"
|
||||
},
|
||||
"setUsername": {
|
||||
"message": "Criar nomde de utilizador"
|
||||
},
|
||||
"copyPublicID": {
|
||||
"message": "Copiar UserID Publico"
|
||||
},
|
||||
"discordAdvert": {
|
||||
"message": "Junte-se ao discord oficial para sugerir dicas e sugestões!"
|
||||
},
|
||||
@@ -148,18 +182,48 @@
|
||||
"hideButtonsDescription": {
|
||||
"message": "Isto esconde os botões que aparecem no player do Youtube para submeter patrocínios. Entendemos que possa ser\n incómodo a algumas pessoas. Em vez de usar esses botões pode usar os do popup. Para esconder a mensagem que aparece, \n ususe o botão na mesma que diz \"Don't show this again\". Pode sempre reactivar estas definições novamente."
|
||||
},
|
||||
"showSkipButton": {
|
||||
"message": "Mantenha o Botão Saltar para Destaque no Player"
|
||||
},
|
||||
"showInfoButton": {
|
||||
"message": "Mostrar botão de Informações no player do Youtube"
|
||||
},
|
||||
"hideInfoButton": {
|
||||
"message": "Esconder botão de Informações no player do Youtube"
|
||||
},
|
||||
"autoHideInfoButton": {
|
||||
"message": "Ocultar automaticamente o Botão de Informação"
|
||||
},
|
||||
"hideDeleteButton": {
|
||||
"message": "Esconder botão de Apagar no player do Youtube"
|
||||
},
|
||||
"showDeleteButton": {
|
||||
"message": "Mostrar botão de Apagar no player do Youtube"
|
||||
},
|
||||
"enableViewTracking": {
|
||||
"message": "Ativar Rastreamento de Contagem de Saltos"
|
||||
},
|
||||
"whatViewTracking": {
|
||||
"message": "Esse recurso rastreia quais segmentos você pulou para permitir que os usuários saibam o quanto seu envio ajudou outras pessoas e é usado como métrica junto com votos positivos para garantir que o spam não entre no banco de dados. A extensão envia uma mensagem ao servidor cada vez que você pular um segmento. Espero que a maioria das pessoas não altere essa configuração para que os números de visualização sejam precisos. :)"
|
||||
},
|
||||
"enableViewTrackingInPrivate": {
|
||||
"message": "Ativar o Rastreamento de Contagem de Saltos nas Guias Privadas/Anônimas"
|
||||
},
|
||||
"enableTrackDownvotes": {
|
||||
"message": "Guardar segmentos de votos negativos"
|
||||
},
|
||||
"whatTrackDownvotes": {
|
||||
"message": "Quaisquer segmentos que você votar negativo permanecerão ocultos mesmo após a atualização"
|
||||
},
|
||||
"trackDownvotesWarning": {
|
||||
"message": "Aviso: Ao desabilitar isso excluirá todos os votos negativos armazenados anteriormente"
|
||||
},
|
||||
"enableQueryByHashPrefix": {
|
||||
"message": "Consulta por Prefixo de Hash"
|
||||
},
|
||||
"whatQueryByHashPrefix": {
|
||||
"message": "Em vez de solicitar segmentos do servidor usando o ID do Vídeo, são enviados os primeiros 4 caracteres do hash do ID do Vídeo. Este servidor enviará de volta dados para todos os vídeos com hashes semelhantes."
|
||||
},
|
||||
"showNotice": {
|
||||
"message": "Mostrar notificação outra vez"
|
||||
},
|
||||
|
||||
@@ -391,6 +391,10 @@ div:hover > .sponsorBlockChapterBar {
|
||||
filter: brightness(80%);
|
||||
}
|
||||
|
||||
.segmentSummary {
|
||||
outline: none !important;
|
||||
}
|
||||
|
||||
.submitButton {
|
||||
background-color:#ec1c1c;
|
||||
-moz-border-radius:28px;
|
||||
@@ -666,6 +670,7 @@ input::-webkit-inner-spin-button {
|
||||
line-height: 1.5em;
|
||||
color: white;
|
||||
font-size: 12px;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.sponsorBlockTooltip a {
|
||||
@@ -726,3 +731,9 @@ input::-webkit-inner-spin-button {
|
||||
.sponsorBlockCategoryPill:hover .categoryPillClose {
|
||||
display: inherit;
|
||||
}
|
||||
|
||||
/* tweak for mobile duration */
|
||||
#sponsorBlockDurationAfterSkips.ytm-time-display {
|
||||
padding-left: 4px;
|
||||
margin: 0px;
|
||||
}
|
||||
@@ -7,14 +7,26 @@
|
||||
}
|
||||
|
||||
/*
|
||||
* IDs on container element (when inserted in page), <html> element,
|
||||
* <body> element and main container
|
||||
* Container when popup displayed in-page
|
||||
*/
|
||||
|
||||
#sponsorBlockPopupContainer {
|
||||
position: relative;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
/*
|
||||
* Disable fixed popup width when displayed in-page
|
||||
*/
|
||||
|
||||
#sponsorBlockPopupContainer #sponsorBlockPopupBody {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
/*
|
||||
* Main containers
|
||||
*/
|
||||
|
||||
#sponsorBlockPopupHTML {
|
||||
color-scheme: dark;
|
||||
}
|
||||
@@ -41,6 +53,25 @@
|
||||
transition: none !important;
|
||||
}
|
||||
|
||||
/*
|
||||
* Close popup button when displayed in-page
|
||||
*/
|
||||
|
||||
.sbCloseButton {
|
||||
background: transparent;
|
||||
border: 0;
|
||||
padding: 8px;
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
right: 5px;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.sbCloseButton:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Header logo
|
||||
*/
|
||||
@@ -82,6 +113,10 @@
|
||||
* <details> wrapper around each segment
|
||||
*/
|
||||
|
||||
.votingButtons {
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
}
|
||||
|
||||
.votingButtons[open] {
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
|
||||
@@ -102,7 +102,7 @@ class SubmissionNoticeComponent extends React.Component<SubmissionNoticeProps, S
|
||||
|
||||
{/* Guidelines button */}
|
||||
<button className="sponsorSkipObject sponsorSkipNoticeButton sponsorSkipNoticeRightButton"
|
||||
onClick={() => window.open("https://wiki.sponsor.ajay.app/index.php/Guidelines")}>
|
||||
onClick={() => window.open("https://wiki.sponsor.ajay.app/w/Guidelines")}>
|
||||
|
||||
{chrome.i18n.getMessage(Config.config.submissionCountSinceCategories > 3 ? "guidelines" : "readTheGuidelines")}
|
||||
</button>
|
||||
|
||||
103
src/content.ts
103
src/content.ts
@@ -41,6 +41,13 @@ let videoInfo: VideoInfo = null;
|
||||
let channelIDInfo: ChannelIDInfo;
|
||||
// Locked Categories in this tab, like: ["sponsor","intro","outro"]
|
||||
let lockedCategories: Category[] = [];
|
||||
// Used to calculate a more precise "virtual" video time
|
||||
let lastKnownVideoTime: { videoTime: number, preciseTime: number } = {
|
||||
videoTime: null,
|
||||
preciseTime: null
|
||||
};
|
||||
// It resumes with a slightly later time on chromium
|
||||
let lastTimeFromWaitingEvent = null;
|
||||
|
||||
// Skips are scheduled to ensure precision.
|
||||
// Skips are rescheduled every seeking event.
|
||||
@@ -455,7 +462,17 @@ function startSponsorSchedule(includeIntersectingSegments = false, currentTime?:
|
||||
}
|
||||
|
||||
if (!video) return;
|
||||
if (currentTime === undefined || currentTime === null) currentTime = video.currentTime;
|
||||
if (currentTime === undefined || currentTime === null) {
|
||||
const virtualTime = lastTimeFromWaitingEvent ?? (lastKnownVideoTime.videoTime ?
|
||||
(performance.now() - lastKnownVideoTime.preciseTime) / 1000 + lastKnownVideoTime.videoTime : null);
|
||||
if ((lastTimeFromWaitingEvent || !utils.isFirefox())
|
||||
&& !isSafari() && virtualTime && Math.abs(virtualTime - video.currentTime) < 0.6){
|
||||
currentTime = virtualTime;
|
||||
} else {
|
||||
currentTime = video.currentTime;
|
||||
}
|
||||
}
|
||||
lastTimeFromWaitingEvent = null;
|
||||
|
||||
previewBar?.updateChapterText(sponsorTimes, sponsorTimesSubmitting, currentTime);
|
||||
|
||||
@@ -531,24 +548,30 @@ function startSponsorSchedule(includeIntersectingSegments = false, currentTime?:
|
||||
startSponsorSchedule(forcedIncludeIntersectingSegments, forcedSkipTime, forcedIncludeNonIntersectingSegments);
|
||||
};
|
||||
|
||||
if (timeUntilSponsor <= 0) {
|
||||
skippingFunction();
|
||||
if (timeUntilSponsor < 0.003) {
|
||||
skippingFunction(currentTime);
|
||||
} else {
|
||||
const delayTime = timeUntilSponsor * 1000 * (1 / video.playbackRate);
|
||||
if (delayTime < 300 && utils.isFirefox() && !isSafari()) {
|
||||
if (delayTime < 300) {
|
||||
// For Firefox, use interval instead of timeout near the end to combat imprecise video time
|
||||
const startIntervalTime = performance.now();
|
||||
const startVideoTime = video.currentTime;
|
||||
const startVideoTime = Math.max(currentTime, video.currentTime);
|
||||
currentSkipInterval = setInterval(() => {
|
||||
const intervalDuration = performance.now() - startIntervalTime;
|
||||
if (intervalDuration >= delayTime || video.currentTime >= skipTime[0]) {
|
||||
clearInterval(currentSkipInterval);
|
||||
skippingFunction(Math.max(video.currentTime, startVideoTime + intervalDuration / 1000));
|
||||
if (!utils.isFirefox() && !video.muted) {
|
||||
// Workaround for more accurate skipping on Chromium
|
||||
video.muted = true;
|
||||
video.muted = false;
|
||||
}
|
||||
}, 5);
|
||||
|
||||
skippingFunction(Math.max(video.currentTime, startVideoTime + video.playbackRate * intervalDuration / 1000));
|
||||
}
|
||||
}, 1);
|
||||
} else {
|
||||
// Schedule for right before to be more precise than normal timeout
|
||||
currentSkipSchedule = setTimeout(skippingFunction, Math.max(0, delayTime - 30));
|
||||
currentSkipSchedule = setTimeout(skippingFunction, Math.max(0, delayTime - 100));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -630,6 +653,8 @@ function setupVideoListeners() {
|
||||
if (!firstEvent && video.currentTime === 0) return;
|
||||
firstEvent = false;
|
||||
|
||||
updateVirtualTime();
|
||||
|
||||
if (switchingVideos) {
|
||||
switchingVideos = false;
|
||||
// If already segments loaded before video, retry to skip starting segments
|
||||
@@ -650,6 +675,8 @@ function setupVideoListeners() {
|
||||
|
||||
});
|
||||
video.addEventListener('playing', () => {
|
||||
updateVirtualTime();
|
||||
|
||||
// Make sure it doesn't get double called with the play event
|
||||
if (Math.abs(lastCheckVideoTime - video.currentTime) > 0.3
|
||||
|| (lastCheckVideoTime !== video.currentTime && Date.now() - lastCheckTime > 2000)) {
|
||||
@@ -665,6 +692,9 @@ function setupVideoListeners() {
|
||||
lastCheckTime = Date.now();
|
||||
lastCheckVideoTime = video.currentTime;
|
||||
|
||||
updateVirtualTime();
|
||||
lastTimeFromWaitingEvent = null;
|
||||
|
||||
startSponsorSchedule();
|
||||
} else {
|
||||
previewBar?.updateChapterText(sponsorTimes, sponsorTimesSubmitting, video.currentTime);
|
||||
@@ -673,18 +703,33 @@ function setupVideoListeners() {
|
||||
video.addEventListener('ratechange', () => startSponsorSchedule());
|
||||
// Used by videospeed extension (https://github.com/igrigorik/videospeed/pull/740)
|
||||
video.addEventListener('videoSpeed_ratechange', () => startSponsorSchedule());
|
||||
video.addEventListener('pause', () => {
|
||||
const paused = () => {
|
||||
// Reset lastCheckVideoTime
|
||||
lastCheckVideoTime = -1;
|
||||
lastCheckTime = 0;
|
||||
|
||||
lastKnownVideoTime = {
|
||||
videoTime: null,
|
||||
preciseTime: null
|
||||
}
|
||||
lastTimeFromWaitingEvent = video.currentTime;
|
||||
|
||||
cancelSponsorSchedule();
|
||||
});
|
||||
};
|
||||
video.addEventListener('pause', paused);
|
||||
video.addEventListener('waiting', paused);
|
||||
|
||||
startSponsorSchedule();
|
||||
}
|
||||
}
|
||||
|
||||
function updateVirtualTime() {
|
||||
lastKnownVideoTime = {
|
||||
videoTime: video.currentTime,
|
||||
preciseTime: performance.now()
|
||||
};
|
||||
}
|
||||
|
||||
function setupSkipButtonControlBar() {
|
||||
if (!skipButtonControlBar) {
|
||||
skipButtonControlBar = new SkipButtonControlBar({
|
||||
@@ -990,10 +1035,10 @@ function getYouTubeVideoID(document: Document): string | boolean {
|
||||
const url = document.URL;
|
||||
// clips should never skip, going from clip to full video has no indications.
|
||||
if (url.includes("youtube.com/clip/")) return false;
|
||||
// skip to document and don't hide if on /embed/
|
||||
if (url.includes("/embed/") && url.includes("youtube.com")) return getYouTubeVideoIDFromDocument(document, false);
|
||||
// skip to URL if matches youtube watch or invidious or matches youtube pattern
|
||||
if ((!url.includes("youtube.com")) || url.includes("/watch") || url.includes("/shorts/") || url.includes("playlist")) return getYouTubeVideoIDFromURL(url);
|
||||
// skip to document and don't hide if on /embed/
|
||||
if (url.includes("/embed/")) return getYouTubeVideoIDFromDocument(document, false);
|
||||
// skip to document if matches pattern
|
||||
if (url.includes("/channel/") || url.includes("/user/") || url.includes("/c/")) return getYouTubeVideoIDFromDocument(document);
|
||||
// not sure, try URL then document
|
||||
@@ -1117,11 +1162,12 @@ function updatePreviewBar(): void {
|
||||
async function whitelistCheck() {
|
||||
const whitelistedChannels = Config.config.whitelistedChannels;
|
||||
|
||||
const getChannelID = () => videoInfo?.videoDetails?.channelId
|
||||
?? document.querySelector(".ytd-channel-name a")?.getAttribute("href")?.replace(/\/.+\//, "") // YouTube
|
||||
?? document.querySelector(".ytp-title-channel-logo")?.getAttribute("href")?.replace(/https:\/.+\//, "") // YouTube Embed
|
||||
?? document.querySelector("a > .channel-profile")?.parentElement?.getAttribute("href")?.replace(/\/.+\//, "") // Invidious
|
||||
?? document.querySelector("a.slim-owner-icon-and-title")?.getAttribute("href")?.replace(/\/.+\//, ""); // Mobile YouTube
|
||||
const getChannelID = () =>
|
||||
(document.querySelector("a.ytd-video-owner-renderer") // YouTube
|
||||
?? document.querySelector("a.ytp-title-channel-logo") // YouTube Embed
|
||||
?? document.querySelector(".channel-profile #channel-name")?.parentElement.parentElement // Invidious
|
||||
?? document.querySelector("a.slim-owner-icon-and-title")) // Mobile YouTube
|
||||
?.getAttribute("href")?.match(/\/channel\/(UC[a-zA-Z0-9_-]{22})/)[1];
|
||||
|
||||
try {
|
||||
await utils.wait(() => !!getChannelID(), 6000, 20);
|
||||
@@ -1680,13 +1726,15 @@ function openInfoMenu() {
|
||||
popup.innerHTML = htmlData;
|
||||
|
||||
//close button
|
||||
const closeButton = document.createElement("div");
|
||||
closeButton.innerText = chrome.i18n.getMessage("closePopup");
|
||||
closeButton.classList.add("smallLink");
|
||||
closeButton.setAttribute("align", "center");
|
||||
const closeButton = document.createElement("button");
|
||||
const closeButtonIcon = document.createElement("img");
|
||||
closeButtonIcon.src = chrome.extension.getURL("icons/close.png");
|
||||
closeButtonIcon.width = 15;
|
||||
closeButtonIcon.height = 15;
|
||||
closeButton.appendChild(closeButtonIcon);
|
||||
closeButton.setAttribute("title", chrome.i18n.getMessage("closePopup"));
|
||||
closeButton.classList.add("sbCloseButton");
|
||||
closeButton.addEventListener("click", closeInfoMenu);
|
||||
// Theme based color
|
||||
closeButton.style.color = "var(--yt-spec-text-primary)";
|
||||
|
||||
//add the close button
|
||||
popup.prepend(closeButton);
|
||||
@@ -2120,14 +2168,15 @@ function updateAdFlag(): void {
|
||||
}
|
||||
|
||||
function showTimeWithoutSkips(skippedDuration: number): void {
|
||||
if (onMobileYouTube || onInvidious) return;
|
||||
if (onInvidious) return;
|
||||
|
||||
if (isNaN(skippedDuration) || skippedDuration < 0) {
|
||||
skippedDuration = 0;
|
||||
}
|
||||
|
||||
// YouTube player time display
|
||||
const display = document.querySelector(".ytp-time-display.notranslate");
|
||||
const displayClass = onMobileYouTube ? "ytm-time-display" : "ytp-time-display.notranslate"
|
||||
const display = document.querySelector(`.${displayClass}`);
|
||||
if (!display) return;
|
||||
|
||||
const durationID = "sponsorBlockDurationAfterSkips";
|
||||
@@ -2137,12 +2186,12 @@ function showTimeWithoutSkips(skippedDuration: number): void {
|
||||
if (duration === null) {
|
||||
duration = document.createElement('span');
|
||||
duration.id = durationID;
|
||||
duration.classList.add("ytp-time-duration");
|
||||
duration.classList.add(displayClass);
|
||||
|
||||
display.appendChild(duration);
|
||||
}
|
||||
|
||||
const durationAfterSkips = GenericUtils.getFormattedTime(video?.duration - skippedDuration)
|
||||
const durationAfterSkips = GenericUtils.getFormattedTime(video?.duration - skippedDuration);
|
||||
|
||||
duration.innerText = (durationAfterSkips == null || skippedDuration <= 0) ? "" : " (" + durationAfterSkips + ")";
|
||||
}
|
||||
|
||||
@@ -190,7 +190,7 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> {
|
||||
PageElements.sponsorTimesViewsDisplayEndWord.innerText = chrome.i18n.getMessage("Segment");
|
||||
}
|
||||
PageElements.sponsorTimesViewsDisplay.innerText = viewCount.toLocaleString();
|
||||
PageElements.sponsorTimesViewsContainer.style.display = "unset";
|
||||
PageElements.sponsorTimesViewsContainer.style.display = "block";
|
||||
}
|
||||
|
||||
showDonateWidget(viewCount);
|
||||
@@ -222,7 +222,7 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> {
|
||||
}
|
||||
|
||||
PageElements.sponsorTimesSkipsDoneDisplay.innerText = Config.config.skipCount.toLocaleString();
|
||||
PageElements.sponsorTimesSkipsDoneContainer.style.display = "unset";
|
||||
PageElements.sponsorTimesSkipsDoneContainer.style.display = "block";
|
||||
}
|
||||
|
||||
//get the amount of time this user has saved.
|
||||
|
||||
@@ -354,13 +354,15 @@ export default class Utils {
|
||||
|
||||
findReferenceNode(): HTMLElement {
|
||||
const selectors = [
|
||||
"#player-container-id", // Mobile YouTube
|
||||
"#movie_player",
|
||||
"#c4-player", // Channel Trailer
|
||||
"#player-container", // Preview on hover
|
||||
"#main-panel.ytmusic-player-page", // YouTube music
|
||||
"#player-container .video-js", // Invidious
|
||||
".main-video-section > .video-container" // Cloudtube
|
||||
]
|
||||
];
|
||||
|
||||
let referenceNode = findValidElementFromSelector(selectors)
|
||||
if (referenceNode == null) {
|
||||
//for embeds
|
||||
|
||||
Reference in New Issue
Block a user