Compare commits

...

14 Commits
4.1.6 ... 4.2.1

Author SHA1 Message Date
Ajay
821bbc969b bump version 2022-03-17 22:19:33 -04:00
Ajay
e20011ce08 Merge branch 'master' of https://github.com/ajayyy/SponsorBlock 2022-03-17 22:19:22 -04:00
Ajay
e30bccd2b7 Don't use virtual time on firefox 2022-03-17 22:19:21 -04:00
Ajay Ramachandran
5b62e76a63 Merge pull request #1234 from molniya0207/patch-1
Fix guidelines link
2022-03-17 12:29:11 -04:00
Stopper
15c73d7940 Fix guidelines link 2022-03-17 22:24:00 +06:00
Ajay
36f0fccd9c Force css 2022-03-17 00:29:33 -04:00
Ajay
d4544a7c47 Fixes for safari 2022-03-17 00:27:36 -04:00
Ajay Ramachandran
d9f1ee9bb8 New Crowdin updates (#1225) 2022-03-16 22:14:42 -04:00
Ajay Ramachandran
5f4c4332be bump version 2022-03-16 22:14:14 -04:00
Ajay
1acda5fe0a Improve precision on chromium using predicted virtual time 2022-03-16 16:17:44 -04:00
Ajay
21d4f0487c Fix skip notice behind controls on mobile youtube
Fix #1229
2022-03-16 13:30:20 -04:00
Ajay
340127a7f3 Switch font back to arial 2022-03-16 12:30:35 -04:00
Ajay Ramachandran
38ab10a191 Merge pull request #1227 from AlecRust/details-element
Refactor segment expanding to use <details>
2022-03-12 15:54:17 -05:00
Alec Rust
ced30c711e Refactor segment expanding to use <details> 2022-03-12 12:03:33 +00:00
10 changed files with 156 additions and 45 deletions

View File

@@ -1,7 +1,7 @@
{ {
"name": "__MSG_fullName__", "name": "__MSG_fullName__",
"short_name": "SponsorBlock", "short_name": "SponsorBlock",
"version": "4.1.6", "version": "4.2.1",
"default_locale": "en", "default_locale": "en",
"description": "__MSG_Description__", "description": "__MSG_Description__",
"homepage_url": "https://sponsor.ajay.app", "homepage_url": "https://sponsor.ajay.app",

View File

@@ -586,13 +586,13 @@
"message": "Titulky nebo když se objeví konečné karty YouTube. Není pro závěry s informacemi." "message": "Titulky nebo když se objeví konečné karty YouTube. Není pro závěry s informacemi."
}, },
"category_preview": { "category_preview": {
"message": "Náhled/shrnutí" "message": "Náhled / shrnutí"
}, },
"category_preview_description": { "category_preview_description": {
"message": "Rychlé shrnutí předchozích epizod nebo náhled toho, co se objeví v aktuálním videu. Myšleno pro upravené sloučené klipy, ne pro mluvená shrnutí." "message": "Rychlé shrnutí předchozích epizod nebo náhled toho, co se objeví v aktuálním videu. Myšleno pro upravené sloučené klipy, ne pro mluvená shrnutí."
}, },
"category_filler": { "category_filler": {
"message": "Výplň/vtipy" "message": "Výplň / vtipy"
}, },
"category_filler_description": { "category_filler_description": {
"message": "Výplňové scény přidané jen jako přídavek nebo humor, které nejsou vyžadovány pro pochopení hlavního obsahu videa. Toto by nemělo zahrnovat segmenty poskytující kontext nebo podrobnosti na pozadí." "message": "Výplňové scény přidané jen jako přídavek nebo humor, které nejsou vyžadovány pro pochopení hlavního obsahu videa. Toto by nemělo zahrnovat segmenty poskytující kontext nebo podrobnosti na pozadí."

View File

@@ -562,7 +562,7 @@
"description": "Short description for this category" "description": "Short description for this category"
}, },
"category_interaction": { "category_interaction": {
"message": "Promemoria di Interazione (Sottoscrizione)" "message": "Promemoria d'Interazione (Iscrizione)"
}, },
"category_interaction_description": { "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." "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."

View File

@@ -118,6 +118,34 @@
"submitCheck": { "submitCheck": {
"message": "Tem a certeza que pretende submeter?" "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": { "clearTimesButton": {
"message": "Limpar Intervalos" "message": "Limpar Intervalos"
}, },
@@ -127,9 +155,15 @@
"publicStats": { "publicStats": {
"message": "Isto é usado na página pública de estatísticas que mostra o quanto já contríbuíu. Veje-a" "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": { "setUsername": {
"message": "Criar nomde de utilizador" "message": "Criar nomde de utilizador"
}, },
"copyPublicID": {
"message": "Copiar UserID Publico"
},
"discordAdvert": { "discordAdvert": {
"message": "Junte-se ao discord oficial para sugerir dicas e sugestões!" "message": "Junte-se ao discord oficial para sugerir dicas e sugestões!"
}, },
@@ -148,18 +182,48 @@
"hideButtonsDescription": { "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." "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": { "showInfoButton": {
"message": "Mostrar botão de Informações no player do Youtube" "message": "Mostrar botão de Informações no player do Youtube"
}, },
"hideInfoButton": { "hideInfoButton": {
"message": "Esconder botão de Informações no player do Youtube" "message": "Esconder botão de Informações no player do Youtube"
}, },
"autoHideInfoButton": {
"message": "Ocultar automaticamente o Botão de Informação"
},
"hideDeleteButton": { "hideDeleteButton": {
"message": "Esconder botão de Apagar no player do Youtube" "message": "Esconder botão de Apagar no player do Youtube"
}, },
"showDeleteButton": { "showDeleteButton": {
"message": "Mostrar botão de Apagar no player do Youtube" "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": { "showNotice": {
"message": "Mostrar notificação outra vez" "message": "Mostrar notificação outra vez"
}, },

View File

@@ -352,6 +352,10 @@
filter: brightness(80%); filter: brightness(80%);
} }
.segmentSummary {
outline: none !important;
}
.submitButton { .submitButton {
background-color:#ec1c1c; background-color:#ec1c1c;
-moz-border-radius:28px; -moz-border-radius:28px;

View File

@@ -79,18 +79,30 @@
} }
/* /*
* Individual segments (<button> elements) * <details> wrapper around each segment
*/ */
.segmentTimeButton { .votingButtons {
background: transparent; font-family: Arial, Helvetica, sans-serif;
border: 0; }
.votingButtons[open] {
padding-bottom: 5px;
}
.votingButtons:hover {
background-color: var(--sb-grey-bg-color);
}
/*
* Individual segments summaries (clickable <summary>)
*/
.segmentSummary {
cursor: pointer; cursor: pointer;
color: var(--sb-main-fg-color);
font-weight: bold; font-weight: bold;
padding: 7px; padding: 7px;
outline: none; list-style: none;
width: 100%;
white-space: nowrap; white-space: nowrap;
} }
@@ -501,7 +513,3 @@
#sponsorBlockPopupBody .hidden { #sponsorBlockPopupBody .hidden {
display: none !important; display: none !important;
} }
.voteButtonsContainer--hide {
display: none;
}

View File

@@ -95,7 +95,7 @@ class SubmissionNoticeComponent extends React.Component<SubmissionNoticeProps, S
{/* Guidelines button */} {/* Guidelines button */}
<button className="sponsorSkipObject sponsorSkipNoticeButton sponsorSkipNoticeRightButton" <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")} {chrome.i18n.getMessage(Config.config.submissionCountSinceCategories > 3 ? "guidelines" : "readTheGuidelines")}
</button> </button>

View File

@@ -40,6 +40,11 @@ let videoInfo: VideoInfo = null;
let channelIDInfo: ChannelIDInfo; let channelIDInfo: ChannelIDInfo;
// Locked Categories in this tab, like: ["sponsor","intro","outro"] // Locked Categories in this tab, like: ["sponsor","intro","outro"]
let lockedCategories: Category[] = []; let lockedCategories: Category[] = [];
// Used to calculate a more precise "virtual" video time
let lastKnownVideoTime: { videoTime: number, preciseTime: number } = {
videoTime: null,
preciseTime: null
};
// Skips are scheduled to ensure precision. // Skips are scheduled to ensure precision.
// Skips are rescheduled every seeking event. // Skips are rescheduled every seeking event.
@@ -450,7 +455,15 @@ function startSponsorSchedule(includeIntersectingSegments = false, currentTime?:
} }
if (!video || video.paused) return; if (!video || video.paused) return;
if (currentTime === undefined || currentTime === null) currentTime = video.currentTime; if (currentTime === undefined || currentTime === null) {
const virtualTime = lastKnownVideoTime.videoTime ?
(performance.now() - lastKnownVideoTime.preciseTime) / 1000 + lastKnownVideoTime.videoTime : null;
if (!utils.isFirefox() && !isSafari() && virtualTime && Math.abs(virtualTime - video.currentTime) < 0.6){
currentTime = virtualTime;
} else {
currentTime = video.currentTime;
}
}
if (videoMuted && !inMuteSegment(currentTime)) { if (videoMuted && !inMuteSegment(currentTime)) {
video.muted = false; video.muted = false;
@@ -526,20 +539,26 @@ function startSponsorSchedule(includeIntersectingSegments = false, currentTime?:
skippingFunction(); skippingFunction();
} else { } else {
const delayTime = timeUntilSponsor * 1000 * (1 / video.playbackRate); 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 // For Firefox, use interval instead of timeout near the end to combat imprecise video time
const startIntervalTime = performance.now(); const startIntervalTime = performance.now();
const startVideoTime = video.currentTime; const startVideoTime = Math.max(currentTime, video.currentTime);
currentSkipInterval = setInterval(() => { currentSkipInterval = setInterval(() => {
const intervalDuration = performance.now() - startIntervalTime; const intervalDuration = performance.now() - startIntervalTime;
if (intervalDuration >= delayTime || video.currentTime >= skipTime[0]) { if (intervalDuration >= delayTime || video.currentTime >= skipTime[0]) {
clearInterval(currentSkipInterval); 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;
}
skippingFunction(Math.max(video.currentTime, startVideoTime + video.playbackRate * intervalDuration / 1000));
} }
}, 5); }, 1);
} else { } else {
// Schedule for right before to be more precise than normal timeout // 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));
} }
} }
} }
@@ -621,6 +640,8 @@ function setupVideoListeners() {
if (!firstEvent && video.currentTime === 0) return; if (!firstEvent && video.currentTime === 0) return;
firstEvent = false; firstEvent = false;
updateVirtualTime();
if (switchingVideos) { if (switchingVideos) {
switchingVideos = false; switchingVideos = false;
// If already segments loaded before video, retry to skip starting segments // If already segments loaded before video, retry to skip starting segments
@@ -641,6 +662,8 @@ function setupVideoListeners() {
}); });
video.addEventListener('playing', () => { video.addEventListener('playing', () => {
updateVirtualTime();
// Make sure it doesn't get double called with the play event // Make sure it doesn't get double called with the play event
if (Math.abs(lastCheckVideoTime - video.currentTime) > 0.3 if (Math.abs(lastCheckVideoTime - video.currentTime) > 0.3
|| (lastCheckVideoTime !== video.currentTime && Date.now() - lastCheckTime > 2000)) { || (lastCheckVideoTime !== video.currentTime && Date.now() - lastCheckTime > 2000)) {
@@ -656,24 +679,40 @@ function setupVideoListeners() {
lastCheckTime = Date.now(); lastCheckTime = Date.now();
lastCheckVideoTime = video.currentTime; lastCheckVideoTime = video.currentTime;
updateVirtualTime();
startSponsorSchedule(); startSponsorSchedule();
} }
}); });
video.addEventListener('ratechange', () => startSponsorSchedule()); video.addEventListener('ratechange', () => startSponsorSchedule());
// Used by videospeed extension (https://github.com/igrigorik/videospeed/pull/740) // Used by videospeed extension (https://github.com/igrigorik/videospeed/pull/740)
video.addEventListener('videoSpeed_ratechange', () => startSponsorSchedule()); video.addEventListener('videoSpeed_ratechange', () => startSponsorSchedule());
video.addEventListener('pause', () => { const paused = () => {
// Reset lastCheckVideoTime // Reset lastCheckVideoTime
lastCheckVideoTime = -1; lastCheckVideoTime = -1;
lastCheckTime = 0; lastCheckTime = 0;
lastKnownVideoTime = {
videoTime: null,
preciseTime: null
}
cancelSponsorSchedule(); cancelSponsorSchedule();
}); };
video.addEventListener('pause', paused);
video.addEventListener('waiting', paused);
startSponsorSchedule(); startSponsorSchedule();
} }
} }
function updateVirtualTime() {
lastKnownVideoTime = {
videoTime: video.currentTime,
preciseTime: performance.now()
};
}
function setupSkipButtonControlBar() { function setupSkipButtonControlBar() {
if (!skipButtonControlBar) { if (!skipButtonControlBar) {
skipButtonControlBar = new SkipButtonControlBar({ skipButtonControlBar = new SkipButtonControlBar({

View File

@@ -393,8 +393,8 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> {
const UUID = segmentTimes[i].UUID; const UUID = segmentTimes[i].UUID;
const locked = segmentTimes[i].locked; const locked = segmentTimes[i].locked;
const sponsorTimeButton = document.createElement("button"); const segmentSummary = document.createElement("summary");
sponsorTimeButton.className = "segmentTimeButton popupElement"; segmentSummary.className = "segmentSummary";
const categoryColorCircle = document.createElement("span"); const categoryColorCircle = document.createElement("span");
categoryColorCircle.id = "sponsorTimesCategoryColorCircle" + UUID; categoryColorCircle.id = "sponsorTimesCategoryColorCircle" + UUID;
@@ -426,18 +426,17 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> {
segmentTimeFromToNode.style.margin = "5px"; segmentTimeFromToNode.style.margin = "5px";
sponsorTimeButton.appendChild(categoryColorCircle); segmentSummary.appendChild(categoryColorCircle);
sponsorTimeButton.appendChild(textNode); segmentSummary.appendChild(textNode);
sponsorTimeButton.appendChild(segmentTimeFromToNode); segmentSummary.appendChild(segmentTimeFromToNode);
const votingButtons = document.createElement("div"); const votingButtons = document.createElement("details");
votingButtons.classList.add("votingButtons"); votingButtons.classList.add("votingButtons");
//thumbs up and down buttons //thumbs up and down buttons
const voteButtonsContainer = document.createElement("div"); const voteButtonsContainer = document.createElement("div");
voteButtonsContainer.id = "sponsorTimesVoteButtonsContainer" + UUID; voteButtonsContainer.id = "sponsorTimesVoteButtonsContainer" + UUID;
voteButtonsContainer.setAttribute("align", "center"); voteButtonsContainer.setAttribute("align", "center");
voteButtonsContainer.classList.add('voteButtonsContainer--hide');
const upvoteButton = document.createElement("img"); const upvoteButton = document.createElement("img");
upvoteButton.id = "sponsorTimesUpvoteButtonsContainer" + UUID; upvoteButton.id = "sponsorTimesUpvoteButtonsContainer" + UUID;
@@ -505,11 +504,6 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> {
voteButtonsContainer.appendChild(hideButton); voteButtonsContainer.appendChild(hideButton);
} }
//add click listener to open up vote panel
sponsorTimeButton.addEventListener("click", function () {
voteButtonsContainer.classList.toggle("voteButtonsContainer--hide");
});
// Will contain request status // Will contain request status
const voteStatusContainer = document.createElement("div"); const voteStatusContainer = document.createElement("div");
voteStatusContainer.id = "sponsorTimesVoteStatusContainer" + UUID; voteStatusContainer.id = "sponsorTimesVoteStatusContainer" + UUID;
@@ -521,7 +515,7 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> {
thanksForVotingText.classList.add("sponsorTimesThanksForVotingText"); thanksForVotingText.classList.add("sponsorTimesThanksForVotingText");
voteStatusContainer.appendChild(thanksForVotingText); voteStatusContainer.appendChild(thanksForVotingText);
votingButtons.append(sponsorTimeButton); votingButtons.append(segmentSummary);
votingButtons.append(voteButtonsContainer); votingButtons.append(voteButtonsContainer);
votingButtons.append(voteStatusContainer); votingButtons.append(voteStatusContainer);

View File

@@ -372,13 +372,15 @@ export default class Utils {
findReferenceNode(): HTMLElement { findReferenceNode(): HTMLElement {
const selectors = [ const selectors = [
"#player-container-id", // Mobile YouTube
"#movie_player", "#movie_player",
"#c4-player", // Channel Trailer "#c4-player", // Channel Trailer
"#player-container", // Preview on hover "#player-container", // Preview on hover
"#main-panel.ytmusic-player-page", // YouTube music "#main-panel.ytmusic-player-page", // YouTube music
"#player-container .video-js", // Invidious "#player-container .video-js", // Invidious
".main-video-section > .video-container" // Cloudtube ".main-video-section > .video-container" // Cloudtube
] ];
let referenceNode = findValidElementFromSelector(selectors) let referenceNode = findValidElementFromSelector(selectors)
if (referenceNode == null) { if (referenceNode == null) {
//for embeds //for embeds