From 898cbef6435a316b3a9d76630f2c2b9c468e2d3a Mon Sep 17 00:00:00 2001 From: Ramon Quitales Date: Thu, 4 Mar 2021 20:45:33 +1300 Subject: [PATCH] Add helper hint to skip button This commit will add more information within the `skip intro` button to allow the user to determine how the extension is extracting the introduction end timestamp. This commit also allows timestamp only comments to be used, ie. if a commenter posted only a timestamp such as "1:21". We make the assumption that the commenter's timestamp relates to when the into ends. --- src/background_script.ts | 64 ++++++++++++++++++++++++++++++---------- src/content_script.ts | 28 +++++++++--------- 2 files changed, 63 insertions(+), 29 deletions(-) diff --git a/src/background_script.ts b/src/background_script.ts index 5201974..0407daa 100644 --- a/src/background_script.ts +++ b/src/background_script.ts @@ -1,8 +1,15 @@ -chrome.runtime.onMessage.addListener(function ({ }, { }, sendResponse: (response: any) => void): boolean { +const TimeStampRegex = /^[0-9]+\:[0-9]{1,2}$/; +const CommentKeywordRegex = /time|title|tc|card|intro|recap|end/i; + +chrome.runtime.onMessage.addListener(function ( + {}, + {}, + sendResponse: (response: any) => void +): boolean { chrome.tabs.query({ currentWindow: true, active: true }, function (tabs) { let sourceURL = tabs[0].url; if (!sourceURL) { - return + return; } fetch(sourceURL) @@ -25,16 +32,24 @@ chrome.runtime.onMessage.addListener(function ({ }, { }, sendResponse: (response return true; }); -function useAdBreaks(sourceURL: string, sendResponse: (response: any) => void): void { +function useAdBreaks( + sourceURL: string, + sendResponse: (response: any) => void +): void { fetch(sourceURL) .then((response) => response.text()) .then((data) => { - let resp = parseInt(data.substr(data.search('ad_breaks') + 69, 10)) / 1000; - sendResponse({ interval: resp, source: 'ad_breaks' }); + let resp = + parseInt(data.substr(data.search('ad_breaks') + 69, 10)) / 1000; + sendResponse({ interval: resp, source: 'ad_breaks', text: `Ad-break: ${Math.floor(resp/60)}:${Math.floor(resp%60)}` }); }); } -async function checkComments(talkboxID: string, referralID: string, sendResponse: (response: any) => void): Promise { +async function checkComments( + talkboxID: string, + referralID: string, + sendResponse: (response: any) => void +): Promise { let url = `https://www.crunchyroll.com/comments?pg=0&talkboxid=${talkboxID}&sort=score_desc%2Cdate_desc&replycount=10&threadlimit=5&pagelimit=10`; let useComments = await fetch(url, { @@ -61,10 +76,10 @@ async function checkComments(talkboxID: string, referralID: string, sendResponse return useComments; } -function parseComments(data: any, sendResponse: (response: any) => void): boolean { - var timestampRegex = /^[0-9]+\:[0-9]{1,2}$/; - var tcRegex = /time|title|tc|card|intro|recap|end/i; - +function parseComments( + data: any, + sendResponse: (response: any) => void +): boolean { let stack = []; for (let div of data) { stack.push(div); @@ -86,10 +101,21 @@ function parseComments(data: any, sendResponse: (response: any) => void): boolea continue; } let words = curr.comment.body.split(' '); + + // Check if the only comment is a timestamp, and assume that works... + if (words.length === 1) { + let ts = checkWordForTS(words[0]); + if (ts) { + sendResponse({ interval: ts, source: 'comments', text: curr.comment.body }); + return true; + } + } + + // Check if keyword present in comment... let ok = false; for (const word of words) { - if (tcRegex.test(word)) { + if (CommentKeywordRegex.test(word)) { ok = true; break; } @@ -97,10 +123,9 @@ function parseComments(data: any, sendResponse: (response: any) => void): boolea if (ok) { for (const word of words) { - if (timestampRegex.test(word)) { - let minutes = parseInt(word.split(':')[0]) * 60; - let seconds = parseInt(word.split(':')[1]); - sendResponse({ interval: minutes + seconds, source: 'comments' }); + let ts = checkWordForTS(word); + if (ts) { + sendResponse({ interval: ts, source: 'comments', text: curr.comment.body }); return true; } } @@ -108,3 +133,12 @@ function parseComments(data: any, sendResponse: (response: any) => void): boolea } return false; } + +function checkWordForTS(word: string): number | undefined { + if (TimeStampRegex.test(word)) { + let minutes = parseInt(word.split(':')[0]) * 60; + let seconds = parseInt(word.split(':')[1]); + return minutes + seconds; + } + return undefined; +} diff --git a/src/content_script.ts b/src/content_script.ts index b134b8d..c136550 100644 --- a/src/content_script.ts +++ b/src/content_script.ts @@ -1,23 +1,23 @@ function init() { chrome.runtime.sendMessage('trigger', (response) => { console.log('Skip intro button:', response); - addSkipButton(response.interval); + addSkipButton(response); }); } -function addSkipButton(introTS: number) { +function addSkipButton(resp: any) { let root = document.getElementById('vilosRoot'); if (!root) { - return + return; } let button = document.createElement('div'); let player = document.getElementById('player0'); - button.style.zIndex = "999"; + button.style.zIndex = '999'; button.style.color = 'white'; button.style.position = 'fixed'; - button.style.right = "0"; + button.style.right = '0'; button.style.bottom = '80px'; button.style.backgroundColor = 'rgba(0,0,0,0.3)'; @@ -28,27 +28,27 @@ function addSkipButton(introTS: number) { button.style.cursor = 'pointer'; button.style.display = 'none'; button.id = 'skipButton'; + button.innerHTML = `SKIP INTRO
${resp.text}`; button.onclick = () => { - (player).currentTime = introTS; + (player).currentTime = resp.interval; }; root.append(button); - window.setInterval(showHideSkipButton(introTS), 1000); + window.setInterval(showHideSkipButton(resp.interval), 1000); } -function showHideSkipButton(introTS: number) { - let intro = introTS; +function showHideSkipButton(ts: number) { + let intro = ts; + let skipButton = document.getElementById('skipButton'); + let player = document.getElementById('player0'); return function () { - let skipButton = document.getElementById('skipButton'); - let player = document.getElementById('player0'); if (!skipButton || !player) { - return + return; } let time = parseInt((player).currentTime); - if (time < intro) { - skipButton.innerText = 'SKIP INTRO'; + if (time < intro ) { skipButton.style.display = 'block'; } else { skipButton.style.display = 'none';