diff --git a/public/_locales/en/messages.json b/public/_locales/en/messages.json index 11807407..d9a87493 100644 --- a/public/_locales/en/messages.json +++ b/public/_locales/en/messages.json @@ -540,5 +540,8 @@ }, "hiddenDueToDuration": { "message": "hidden: too short" + }, + "channelDataNotFound": { + "message": "Channel ID not loaded yet" } } diff --git a/src/content.ts b/src/content.ts index 901ce761..a2a1a5ab 100644 --- a/src/content.ts +++ b/src/content.ts @@ -24,6 +24,11 @@ var sponsorTimes: SponsorTime[] = null; //what video id are these sponsors for var sponsorVideoID: VideoID = null; +// JSON video info +var videoInfo: any = null; +//the channel this video is about +var channelID; + // Skips are scheduled to ensure precision. // Skips are rescheduled every seeking event. // Skips are canceled every seeking event @@ -56,12 +61,6 @@ var switchingVideos = null; var lastCheckTime = 0; var lastCheckVideoTime = -1; -//the channel this video is about -var channelURL; - -//the title of the last video loaded. Used to make sure the channel URL has been updated yet. -var title; - //is this channel whitelised from getting sponsors skipped var channelWhitelisted = false; @@ -183,9 +182,9 @@ function messageListener(request: any, sender: any, sendResponse: (response: any }); break; - case "getChannelURL": + case "getChannelID": sendResponse({ - channelURL: channelURL + channelID: channelID }); break; @@ -262,6 +261,10 @@ function resetValues() { sponsorTimes = null; sponsorLookupRetries = 0; + videoInfo = null; + channelWhitelisted = false; + channelID = null; + //empty the preview bar if (previewBar !== null) { previewBar.set([], [], 0); @@ -293,6 +296,9 @@ async function videoIDChange(id) { // Wait for options to be ready await utils.wait(() => Config.config !== null, 5000, 1); + // Get new video info + getVideoInfo(); + // If enabled, it will check if this video is private or unlisted and double check with the user if the sponsors should be looked up if (Config.config.checkForUnlistedVideos) { await utils.wait(isPrivacyInfoAvailable); @@ -303,10 +309,8 @@ async function videoIDChange(id) { } } - // TODO: Use a better method here than using type any - // This is done to be able to do channelIDPromise.isFulfilled and channelIDPromise.isRejected - let channelIDPromise: any = utils.wait(getChannelID); - channelIDPromise.then(() => channelIDPromise.isFulfilled = true).catch(() => channelIDPromise.isRejected = true); + // Update whitelist data when the video data is loaded + utils.wait(() => !!videoInfo).then(whitelistCheck); //setup the preview bar if (previewBar === null) { @@ -346,7 +350,7 @@ async function videoIDChange(id) { //close popup closeInfoMenu(); - sponsorsLookup(id, channelIDPromise); + sponsorsLookup(id); //make sure everything is properly added updateVisibilityOfPlayerControlsButton().then(() => { @@ -523,11 +527,11 @@ function incorrectVideoIDCheck(): boolean { } } -function sponsorsLookup(id: string, channelIDPromise?) { +function sponsorsLookup(id: string) { video = document.querySelector('video') // Youtube video player //there is no video here if (video == null) { - setTimeout(() => sponsorsLookup(id, channelIDPromise), 100); + setTimeout(() => sponsorsLookup(id), 100); return; } @@ -586,18 +590,6 @@ function sponsorsLookup(id: string, channelIDPromise?) { startSponsorSchedule(); } - if (channelIDPromise !== undefined) { - if (channelIDPromise.isFulfilled) { - whitelistCheck(); - } else if (channelIDPromise.isRejected) { - //try again - utils.wait(getChannelID).then(whitelistCheck).catch(); - } else { - //add it as a then statement - channelIDPromise.then(whitelistCheck); - } - } - //check database for sponsor times //made true once a setTimeout has been created to try again after a server error let recheckStarted = false; @@ -682,23 +674,13 @@ function sponsorsLookup(id: string, channelIDPromise?) { sponsorDataFound = false; //check if this video was uploaded recently - //use the invidious api to get the time published - sendRequestToCustomServer('GET', "https://www.youtube.com/get_video_info?video_id=" + id, function(xmlhttp, error) { - if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { - let decodedData = decodeURIComponent(xmlhttp.responseText).match(/player_response=([^&]*)/)[1]; + utils.wait(() => !!videoInfo).then(() => { + let dateUploaded = videoInfo.microformat.playerMicroformatRenderer.uploadDate; - if (decodedData === undefined) { - console.error("[SB] Failed at getting video upload date info from YouTube."); - return; - } - - let dateUploaded = JSON.parse(decodedData).microformat.playerMicroformatRenderer.uploadDate; - - //if less than 3 days old - if (Date.now() - new Date(dateUploaded).getTime() < 259200000) { - //TODO lower when server becomes better - setTimeout(() => sponsorsLookup(id, channelIDPromise), 180000); - } + //if less than 3 days old + if (Date.now() - new Date(dateUploaded).getTime() < 259200000) { + //TODO lower when server becomes better + setTimeout(() => sponsorsLookup(id), 180000); } }); @@ -708,13 +690,30 @@ function sponsorsLookup(id: string, channelIDPromise?) { //TODO lower when server becomes better (back to 1 second) //some error occurred, try again in a second - setTimeout(() => sponsorsLookup(id, channelIDPromise), 10000); + setTimeout(() => sponsorsLookup(id), 10000); sponsorLookupRetries++; } }); } +/** + * Get the video info for the current tab from YouTube + */ +function getVideoInfo() { + sendRequestToCustomServer('GET', "https://www.youtube.com/get_video_info?video_id=" + sponsorVideoID, function(xmlhttp, error) { + if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { + let decodedData = decodeURIComponent(xmlhttp.responseText).match(/player_response=([^&]*)/)[1]; + if (!decodedData) { + console.error("[SB] Failed at getting video info from YouTube."); + return; + } + + videoInfo = JSON.parse(decodedData); + } + }); +} + function getYouTubeVideoID(url: string) { // For YouTube TV support if(url.startsWith("https://www.youtube.com/tv#/")) url = url.replace("#", ""); @@ -757,55 +756,6 @@ function getYouTubeVideoID(url: string) { return false; } -function getChannelID() { - //get channel id - let channelURLContainer = null; - - channelURLContainer = document.querySelector("#channel-name > #container > #text-container > #text"); - if (channelURLContainer !== null) { - channelURLContainer = channelURLContainer.firstElementChild; - } else if (onInvidious) { - // Unfortunately, the Invidious HTML doesn't have much in the way of element identifiers... - channelURLContainer = document.querySelector("body > div > div.pure-u-1.pure-u-md-20-24 div.pure-u-1.pure-u-lg-3-5 > div > a"); - } else { - //old YouTube theme - let channelContainers = document.getElementsByClassName("yt-user-info"); - if (channelContainers.length != 0) { - channelURLContainer = channelContainers[0].firstElementChild; - } - } - - if (channelURLContainer === null) { - //try later - return false; - } - - //first get the title to make sure a title change has occurred (otherwise the next video might still be loading) - let titleInfoContainer = document.getElementById("info-contents"); - let currentTitle = ""; - if (titleInfoContainer != null) { - currentTitle = ( titleInfoContainer.firstElementChild.firstElementChild.querySelector(".title").firstElementChild).innerText; - } else if (onInvidious) { - // Unfortunately, the Invidious HTML doesn't have much in the way of element identifiers... - currentTitle = document.querySelector("body > div > div.pure-u-1.pure-u-md-20-24 div.pure-u-1.pure-u-lg-3-5 > div > a > div > span").textContent; - } else { - //old YouTube theme - currentTitle = document.getElementById("eow-title").innerText; - } - - if (title == currentTitle) { - //video hasn't changed yet, wait - //try later - return false; - } - title = currentTitle; - - channelURL = channelURLContainer.getAttribute("href"); - - //reset variables - channelWhitelisted = false; -} - /** * This function is required on mobile YouTube and will keep getting called whenever the preview bar disapears */ @@ -845,10 +795,12 @@ function updatePreviewBar() { //checks if this channel is whitelisted, should be done only after the channelID has been loaded function whitelistCheck() { + channelID = videoInfo.videoDetails.channelId; + //see if this is a whitelisted channel let whitelistedChannels = Config.config.whitelistedChannels; - if (whitelistedChannels != undefined && whitelistedChannels.includes(channelURL)) { + if (whitelistedChannels != undefined && whitelistedChannels.includes(channelID)) { channelWhitelisted = true; } } diff --git a/src/popup.ts b/src/popup.ts index 14041132..0df67c40 100644 --- a/src/popup.ts +++ b/src/popup.ts @@ -919,39 +919,44 @@ async function runThePopup(messageListener?: MessageListener) { }, tabs => { messageHandler.sendMessage( tabs[0].id, - {message: 'getChannelURL'}, + {message: 'getChannelID'}, function(response) { + if (!response.channelID) { + alert(chrome.i18n.getMessage("channelDataNotFound")); + return; + } + //get whitelisted channels - let whitelistedChannels = Config.config.whitelistedChannels; - if (whitelistedChannels == undefined) { - whitelistedChannels = []; + let whitelistedChannels = Config.config.whitelistedChannels; + if (whitelistedChannels == undefined) { + whitelistedChannels = []; + } + + //add on this channel + whitelistedChannels.push(response.channelID); + + //change button + PageElements.whitelistChannel.style.display = "none"; + PageElements.unwhitelistChannel.style.display = "unset"; + + PageElements.downloadedSponsorMessageTimes.innerText = chrome.i18n.getMessage("channelWhitelisted"); + PageElements.downloadedSponsorMessageTimes.style.fontWeight = "bold"; + + //save this + Config.config.whitelistedChannels = whitelistedChannels; + + //send a message to the client + messageHandler.query({ + active: true, + currentWindow: true + }, tabs => { + messageHandler.sendMessage( + tabs[0].id, { + message: 'whitelistChange', + value: true + }); } - - //add on this channel - whitelistedChannels.push(response.channelURL); - - //change button - PageElements.whitelistChannel.style.display = "none"; - PageElements.unwhitelistChannel.style.display = "unset"; - - PageElements.downloadedSponsorMessageTimes.innerText = chrome.i18n.getMessage("channelWhitelisted"); - PageElements.downloadedSponsorMessageTimes.style.fontWeight = "bold"; - - //save this - Config.config.whitelistedChannels = whitelistedChannels; - - //send a message to the client - messageHandler.query({ - active: true, - currentWindow: true - }, tabs => { - messageHandler.sendMessage( - tabs[0].id, { - message: 'whitelistChange', - value: true - }); - } - ); + ); } ); });