commit e449edf887ced9ec1e7dda2bceb8efffc1b55819 Author: CatAClock <CatAClock@proton.me> Date: Tue Apr 15 11:59:49 2025 -0700 codeberg copy diff --git a/ContentScripts/StudioModify.js b/ContentScripts/StudioModify.js new file mode 100644 index 0000000..222a8b9 --- /dev/null +++ b/ContentScripts/StudioModify.js @@ -0,0 +1,406 @@ +let TheHref = document.location.href; +let TheTimeout = null; +let SettingsStay = false; + +const StringArray = ["What was the video about? Can you give an in-depth explaination of what you did?", + "START - What are some things that you can do to improve this video? What can you start doing? List the sections you want improved WITH TIMESTAMPS.", + "STOP - What are things that shouldn't be done or should not have began in the first place?", + "CONTINUE - What can you keep doing to make the same effect happen? These are things that don't need to be changed.", + "You did it! No Further typing is needed."]; + +// Observe changes to the Href and do things accordingly. +const observer = new MutationObserver(mutations => { + if (TheHref !== document.location.href) { + TheHref = document.location.href; + clearTimeout(TheTimeout); + TheTimeout = setTimeout(() => VideoOrChannel(), 1500); + } +}); +observer.observe(document.body, { childList: true, subtree: true }); + +// Do some things on load. +window.onload = function() { + setTimeout(() => { + VideoOrChannel(); + }, 2000); + document.getElementsByTagName("ytcp-send-feedback-button")[0].remove(); + if (document.location.href.includes("channel")) { + document.getElementsByTagName("ytcp-ve")[9].parentElement.remove(); + SettingsStay = true; + } +}; + +// Simple function to not have stuff die. +function VideoOrChannel(){ + if (TheHref.includes("channel") && SettingsStay == false) { + document.getElementsByTagName("ytcp-ve")[9].parentElement.remove(); + SettingsStay = true; + } + + if (document.location.href.includes("channel")) { + ModifyChannelElements(); + } + else { + ModifyVideoElements(); + } +} + +// Remove and add elements in the video area. +function ModifyVideoElements() { + SettingsStay = false; + if (document.location.href.includes("analytics")) { + if (document.location.href.includes("tab-overview")) { + console.log("Do nothing here"); + } + if (document.location.href.includes("tab-reach_viewers")) { + console.log("Do nothing here"); + } + if (document.location.href.includes("tab-interest_viewers")) { + console.log("Do nothing here"); + } + if (document.location.href.includes("tab-build_audience")) { + console.log("Do nothing here"); + } + console.log("You are in analytics!"); + return; + } + + if (document.location.href.includes("editor")) { + console.log("You are in the editor!"); + return; + } + + if (document.location.href.includes("comments")) { + console.log("You are in comments!"); + return; + } + + if (document.location.href.includes("translations")) { + console.log("You are in the translations!"); + return; + } + + if (document.location.href.includes("copyright")) { + console.log("You are in copyright!"); + return; + } + + // Livestream is seperated? Why? + if (document.location.href.includes("livestreaming")) { + console.log("You are streemin!"); + return; + } + console.log("You are in the overview!"); +} + +// Remove and add elements in the channel area. +function ModifyChannelElements() { + if (document.location.href.includes("videos") || document.location.href.includes("content")) { + if (document.getElementsByTagName("ytcp-primary-action-bar")[0].classList.contains("PersistentElements") == false) { + document.getElementsByTagName("ytcp-primary-action-bar")[0].classList.add("PersistentElements"); + document.getElementsByTagName("tp-yt-paper-tab")[7].remove(); + } + console.log("Content elements have been altered!"); + return; + } + + if (document.location.href.includes("analytics")) { + if (document.location.href.includes("tab-overview")) { + let Items = document.getElementsByTagName("yta-personalized-overview-bottom-card"); + Items[0].remove(); + if (document.getElementsByTagName("yta-section")[0].classList.contains("PersistentElements") == false) { + document.getElementsByTagName("yta-section")[0].classList.add("PersistentElements"); + Items = document.getElementsByTagName("yta-entity-snapshot-carousel"); + Items[0].remove(); + } + + // Create Topic Buttons. + browser.storage.local.get("TopicList").then( + (List) => { + let Card = document.createElement("tp-yt-paper-card"); + Card.classList.add("staple-card"); + Card.classList.add("style-scope"); + Card.classList.add("yta-card-container"); + Card.style.marginTop = "24px"; + let Text = document.createElement("div"); + Text.classList.add("style-scope"); + Text.style.margin = "24px"; + Text.style.fontSize = "18px"; + Text.style.fontWeight = "bold"; + Text.innerHTML = "Interesting topics from the week!"; + Card.appendChild(Text); + document.getElementsByTagName("yta-key-metric-card")[0].appendChild(Card); + // Yes, if there is nothing in storage, this errors. + // This is my fix: ignore it. Also fuck off. + for (let i of Object.values(List)[0]) { + // Style elements + let Button = document.createElement("button"); + Button.style.width = "45%"; + Button.style.height = "50px"; + Button.style.border = "25%"; + Button.style.margin = "12px"; + Button.style.background = "rgba(255, 255, 255, 0.1)"; + Button.style.color = "white"; + Button.style.border = "0px solid"; + Button.style.borderRadius = "20px"; + Button.style.fontSize = "20px"; + Button.style.fontWeight = "bold"; + // Events to behave like a button + Button.addEventListener("mouseenter", (event) => { + Button.style.background = "rgba(255, 255, 255, 0.2)"; + }); + Button.addEventListener("mouseleave", (event) => { + Button.style.background = "rgba(255, 255, 255, 0.1)"; + }); + Button.addEventListener("mousedown", (event) => { + Button.style.background = "rgba(255, 255, 255, 0.15)"; + }); + Button.addEventListener("mouseup", (event) => { + Button.style.background = "rgba(255, 255, 255, 0.2)"; + }); + Button.innerHTML = i; + i = i.replaceAll(" ", "+"); + Button.addEventListener("click", (event) => { + document.location.href = "https://www.google.com/search?q=" + i + "&udm=7&tbs=qdr:w"; + }); + Card.appendChild(Button); + } + } + ); + } + if (document.location.href.includes("tab-content")) { + console.log("Do nothing here"); + } + if (document.location.href.includes("tab-build_audience")) { + console.log("Do nothing here"); + } + if (document.location.href.includes("tab-research")) { + console.log("Do nothing here"); + } + console.log("Analytic elements have been altered!"); + return; + } + + if (document.location.href.includes("comments")) { + console.log("You are in comments!"); + return; + } + + if (document.location.href.includes("translations")) { + console.log("You are in translations!"); + return; + } + + if (document.location.href.includes("copyright")) { + console.log("you are in copyright!"); + return; + } + + if (document.location.href.includes("monetization")) { + console.log("You are in monitization"); + return; + } + + if (document.location.href.includes("editing")) { + console.log("You are in customization!"); + return; + } + + // Dashboard + // Remove the quick actions (they are useless) + if (document.getElementsByTagName("ytcp-quick-actions").length > 0) { + document.getElementsByTagName("ytcp-quick-actions")[0].remove(); + } + + // Adjust the cards in certain columns. + for (let Element of document.getElementsByTagName("ytcd-card")) { + // remove cards + if (Element.getAttribute("test-id") == "channel-dashboard-snapshot-card") { + Element.remove(); + } + } + + // Livestream is seperated? Why? + if (document.location.href.includes("livestreaming")) { + console.log("You are streemin!"); + return; + } + + // Past this point is the dashboard. + // Alter all of the columns to suit the needs of me. + let Counter = 0; + while (Counter <= 2) { + switch (Counter) { + case 0: + document.getElementsByTagName("ytcd-card-column")[Counter].setAttribute("style", "width: calc(50% - var(--card-margin));"); + case 1: + document.getElementsByTagName("ytcd-card-column")[Counter].setAttribute("style", "width: calc(50% - var(--card-margin));"); + break; + case 2: + document.getElementsByTagName("ytcd-card-column")[Counter].remove(); + break; + } + Counter++; + } + + // Create objects in the Dashboard. + // This if statement is for elements that don't go away once deleted. + const Dashboard = document.getElementsByTagName("ytcd-channel-dashboard") + if (document.getElementsByClassName("PersistentObject").length == 0) { + // Create the progress bar. + let Progress = document.createElement("div"); + Progress.classList.add("PersistentObject"); + // Style elements. + Progress.style.height = "50px"; + Progress.style.width = "100% - 24px"; + Progress.style.margin = "24px"; + Progress.style.border = "1px solid rgba(255, 255, 255, 0.1"; + // Create the inside of the progress bar. + let Meter = document.createElement("div"); + // Style elements. + Meter.style.background = "rgb(255, 0, 0)"; + Meter.classList.add("liquid"); + Meter.style.width = "0%"; + Meter.style.height = "100%"; + Progress.appendChild(Meter); + // Place the progress bar on top. + Dashboard[0].parentElement.insertBefore(Progress, Dashboard[0]); + // Create the text box. + let Textbox = document.createElement("textarea"); + // Style elements. + Textbox.style.marginLeft = "24px"; + Textbox.style.marginRight = "24px"; + Textbox.style.height = "200px"; + Textbox.style.background = "rgba(0, 0, 0, 0.2)"; + Textbox.style.border = "1px solid rgba(255, 255, 255, 0.1"; + Textbox.style.color = "white"; + Textbox.placeholder = StringArray[0]; + Textbox.style.resize = "none"; + Dashboard[0].parentElement.insertBefore(Textbox, Dashboard[0]); + // Create the continue button. + let Button = document.createElement("button"); + // Style elements. + Button.style.width = "250px"; + Button.style.height = "40px"; + Button.style.border = "25%"; + Button.style.margin = "24px"; + Button.style.marginBottom = "0"; + Button.innerHTML = "Continue"; + Button.style.background = "rgba(255, 255, 255, 0.1)"; + Button.style.color = "white"; + Button.style.border = "0px solid"; + Button.style.borderRadius = "20px"; + Button.style.fontSize = "18px"; + Button.style.fontWeight = "bold"; + // Change style like a button + Button.addEventListener("mouseenter", (event) => { + Button.style.background = "rgba(255, 255, 255, 0.2)"; + }); + Button.addEventListener("mouseleave", (event) => { + Button.style.background = "rgba(255, 255, 255, 0.1)"; + }); + Button.addEventListener("mousedown", (event) => { + Button.style.background = "rgba(255, 255, 255, 0.15)"; + }); + Button.addEventListener("mouseup", (event) => { + Button.style.background = "rgba(255, 255, 255, 0.2)"; + }); + Button.addEventListener("click", (event) => { + // Button to not only progress the bar, but to also clear the textbox! + const Liquid = document.getElementsByClassName("liquid")[0]; + if (Liquid.clientWidth != Liquid.parentElement.clientWidth) { + // If the thing is full, don't do anything + if (Liquid.clientWidth - 1 == Liquid.parentElement.clientWidth) { + Textbox.disabled = true; + } + else { + let BigAssCalc = (Liquid.clientWidth + (Liquid.parentElement.clientWidth / 4)) / Liquid.parentElement.clientWidth; + document.cookie = "ProgressAmount=" + (BigAssCalc * 100).toString() + ";max-age=28800"; + Liquid.style.width = (BigAssCalc * 100) + "%"; + Textbox.value = ""; + Textbox.placeholder = StringArray[parseInt(Liquid.style.width) / 25]; + } + } + }); + Dashboard[0].parentElement.insertBefore(Button, Dashboard[0]); + // Check for cookies. + if (document.cookie.split("; ").find((row) => row.startsWith("ProgressAmount="))?.split("=")[1] != undefined) { + const Liquid = document.getElementsByClassName("liquid")[0]; + document.getElementsByClassName("liquid")[0].style.width = document.cookie.split("; ").find((row) => row.startsWith("ProgressAmount="))?.split("=")[1] + "%"; + Textbox.placeholder = StringArray[parseInt(Liquid.style.width) / 25]; + if (Liquid.clientWidth - 1 == Liquid.parentElement.clientWidth) { + Textbox.disabled = true; + } + } + } + + // Elements that go away go here. + // Create Channel Buttons. + browser.storage.local.get("ChannelList").then( + (List) => { + let Card = document.createElement("ytcd-card"); + Card.classList.add("card"); + Card.classList.add("style-scope"); + Card.classList.add("ytcd-card"); + let Text = document.createElement("div"); + Text.classList.add("title-text"); + Text.classList.add("style-scope"); + Text.classList.add("ytcd-list-card"); + Text.classList.add("card-title"); + Text.innerHTML = "Cool channels on YouYube!"; + Text.style.fontSize = "18px"; + Text.style.margin = "24px 24px 0px 24px"; + Card.appendChild(Text); + Dashboard[0].getElementsByTagName("ytcd-card-column")[0].appendChild(Card); + // Yes, if there is nothing in storage, this errors. + // This is my fix: ignore it. Also fuck off. + for (let i of Object.values(List)[0]) { + // Style elements + let Button = document.createElement("button"); + Button.style.minWidth = "300px"; + Button.style.height = "30px"; + Button.style.border = "25%"; + Button.style.margin = "12px"; + Button.style.background = "rgba(255, 255, 255, 0.1)"; + Button.style.color = "white"; + Button.style.border = "0px solid"; + Button.style.borderRadius = "20px"; + Button.style.fontSize = "13px"; + Button.style.fontWeight = "bold"; + // Change style like a button. + Button.addEventListener("mouseenter", (event) => { + Button.style.background = "rgba(255, 255, 255, 0.2)"; + }); + Button.addEventListener("mouseleave", (event) => { + Button.style.background = "rgba(255, 255, 255, 0.1)"; + }); + Button.addEventListener("mousedown", (event) => { + Button.style.background = "rgba(255, 255, 255, 0.15)"; + }); + Button.addEventListener("mouseup", (event) => { + Button.style.background = "rgba(255, 255, 255, 0.2)"; + }); + // Different cases for what the user wants to do. + if (i.indexOf("http://") == 0) { + i = i.slice(7); + } + if (i.indexOf("https://") == 0) { + i = i.slice(8); + } + if (i.indexOf("@") == 0) { + i = "www.youtube.com/" + i; + } + if (i.indexOf("http://") != 0 && i.indexOf("https://") != 0 && i.indexOf("@") != 0 && i.indexOf("www.youtube.com")) { + console.warn("The extension has no idea what to do with this string. Please consider removing it."); + console.warn(i); + } + Button.innerHTML = i; + Button.addEventListener("click", (event) => { + document.location.href = "https://" + i; + }); + Card.appendChild(Button); + } + } + ); + console.log("Home elements have been altered!"); +} diff --git a/Icons/Icon.png b/Icons/Icon.png new file mode 100644 index 0000000..25613f0 Binary files /dev/null and b/Icons/Icon.png differ diff --git a/Icons/Icon.svg b/Icons/Icon.svg new file mode 100644 index 0000000..c640766 --- /dev/null +++ b/Icons/Icon.svg @@ -0,0 +1,49 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools --> + +<svg + sodipodi:docname="Icon.svg" + xml:space="preserve" + viewBox="0 0 36.88008 36.88008" + id="Layer_1" + version="1.1" + width="64" + height="64" + inkscape:version="1.2.2 (b0a8486541, 2022-12-01)" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg"><defs + id="defs9" /><sodipodi:namedview + id="namedview7" + pagecolor="#505050" + bordercolor="#eeeeee" + borderopacity="1" + inkscape:showpageshadow="0" + inkscape:pageopacity="0" + inkscape:pagecheckerboard="0" + inkscape:deskcolor="#505050" + showgrid="false" + inkscape:zoom="8.42" + inkscape:cx="35.807601" + inkscape:cy="44.833729" + inkscape:window-width="1920" + inkscape:window-height="1011" + inkscape:window-x="1600" + inkscape:window-y="204" + inkscape:window-maximized="1" + inkscape:current-layer="layer1" /> + +<g + inkscape:groupmode="layer" + id="layer1" + inkscape:label="Icon"><path + style="fill:#f61c0d;stroke:#000000;stroke-width:0.56558;stroke-dasharray:none;stroke-opacity:1" + d="M 29.055355,5.4690511 H 7.8249675 c -4.1653666,0 -7.54205637,3.3520816 -7.54205637,7.4870919 v 10.535605 c 0,4.13501 3.37668977,7.487092 7.54205637,7.487092 H 29.055355 c 4.165367,0 7.542056,-3.352082 7.542056,-7.487092 V 12.956143 c 0,-4.1350103 -3.376689,-7.4870919 -7.542056,-7.4870919 z m -5.10064,13.2674889 -9.930143,4.701564 c -0.2646,0.125274 -0.570239,-0.06623 -0.570239,-0.357213 v -9.696999 c 0,-0.295124 0.313675,-0.486398 0.578825,-0.352991 l 9.930143,4.995435 c 0.295242,0.1485 0.290122,0.568821 -0.0086,0.710204 z" + id="path2" + inkscape:label="Logo" /><path + style="fill:#a53d00;fill-opacity:1;stroke:#000000;stroke-width:0.864377;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none" + d="m 32.816038,30.181436 c -6.721004,1.134313 -6.281454,1.752767 -7.290779,-2.242656 -0.743965,-4.708547 -1.416971,-3.973407 5.691576,-5.325395 l -6.391144,-1.412823 -4.828585,4.100428 -15.5875085,3.171506 0.814735,5.717867 15.8452785,-2.717766 6.242811,1.974352 z" + id="path722" + sodipodi:nodetypes="cccccccccc" + inkscape:label="Tool" /></g></svg> diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..fe70743 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,131 @@ +# PolyForm Noncommercial License 1.0.0 + +<https://polyformproject.org/licenses/noncommercial/1.0.0> + +## Acceptance + +In order to get any license under these terms, you must agree +to them as both strict obligations and conditions to all +your licenses. + +## Copyright License + +The licensor grants you a copyright license for the +software to do everything you might do with the software +that would otherwise infringe the licensor's copyright +in it for any permitted purpose. However, you may +only distribute the software according to [Distribution +License](#distribution-license) and make changes or new works +based on the software according to [Changes and New Works +License](#changes-and-new-works-license). + +## Distribution License + +The licensor grants you an additional copyright license +to distribute copies of the software. Your license +to distribute covers distributing the software with +changes and new works permitted by [Changes and New Works +License](#changes-and-new-works-license). + +## Notices + +You must ensure that anyone who gets a copy of any part of +the software from you also gets a copy of these terms or the +URL for them above, as well as copies of any plain-text lines +beginning with `Required Notice:` that the licensor provided +with the software. For example: + +> Required Notice: Copyright Yoyodyne, Inc. (http://example.com) + +## Changes and New Works License + +The licensor grants you an additional copyright license to +make changes and new works based on the software for any +permitted purpose. + +## Patent License + +The licensor grants you a patent license for the software that +covers patent claims the licensor can license, or becomes able +to license, that you would infringe by using the software. + +## Noncommercial Purposes + +Any noncommercial purpose is a permitted purpose. + +## Personal Uses + +Personal use for research, experiment, and testing for +the benefit of public knowledge, personal study, private +entertainment, hobby projects, amateur pursuits, or religious +observance, without any anticipated commercial application, +is use for a permitted purpose. + +## Noncommercial Organizations + +Use by any charitable organization, educational institution, +public research organization, public safety or health +organization, environmental protection organization, +or government institution is use for a permitted purpose +regardless of the source of funding or obligations resulting +from the funding. + +## Fair Use + +You may have "fair use" rights for the software under the +law. These terms do not limit them. + +## No Other Rights + +These terms do not allow you to sublicense or transfer any of +your licenses to anyone else, or prevent the licensor from +granting licenses to anyone else. These terms do not imply +any other licenses. + +## Patent Defense + +If you make any written claim that the software infringes or +contributes to infringement of any patent, your patent license +for the software granted under these terms ends immediately. If +your company makes such a claim, your patent license ends +immediately for work on behalf of your company. + +## Violations + +The first time you are notified in writing that you have +violated any of these terms, or done anything with the software +not covered by your licenses, your licenses can nonetheless +continue if you come into full compliance with these terms, +and take practical steps to correct past violations, within +32 days of receiving notice. Otherwise, all your licenses +end immediately. + +## No Liability + +***As far as the law allows, the software comes as is, without +any warranty or condition, and the licensor will not be liable +to you for any damages arising out of these terms or the use +or nature of the software, under any kind of legal claim.*** + +## Definitions + +The **licensor** is the individual or entity offering these +terms, and the **software** is the software the licensor makes +available under these terms. + +**You** refers to the individual or entity agreeing to these +terms. + +**Your company** is any legal entity, sole proprietorship, +or other kind of organization that you work for, plus all +organizations that have control over, are under the control of, +or are under common control with that organization. **Control** +means ownership of substantially all the assets of an entity, +or the power to direct its management and policies by vote, +contract, or otherwise. Control can be direct or indirect. + +**Your licenses** are all the licenses granted to you for the +software under these terms. + +**Use** means anything you do with the software requiring one +of your licenses. \ No newline at end of file diff --git a/Options/Main.html b/Options/Main.html new file mode 100644 index 0000000..e6e281c --- /dev/null +++ b/Options/Main.html @@ -0,0 +1,16 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="utf-8" /> + </head> + <body> + <p>The extension does everything automatically.</p> + + <h1>FAQ</h1> + <h2>The extension does not work when loading into YouTube Studio!</h2> + <p>Solution 1: This is because you are using an adblocker or another javascript-intensive extension. It's weird, I know. Get it to only disable on studio.youtube.com and the extension should work.</p> + <p>Solution 2: Try bookmarking "https://studio.youtube.com/channel/" instead of your personal link to give it more time to load and respond.</p> + <h2>Where are the items in the extension popup located?</h2> + <p>In the dashboard and analytics respectively.</p> + </body> +</html> diff --git a/Popups/Main.css b/Popups/Main.css new file mode 100644 index 0000000..e59fc65 --- /dev/null +++ b/Popups/Main.css @@ -0,0 +1,39 @@ +html { + background: rgba(0, 0, 50, 0.8); + text-align: center; + color: white; + font-size: 13px; +} + +input, button { + border: 2px solid rgb(0, 0, 255); + background: rgb(0, 0, 127); + border-radius: 20px; + color: white; +} + +input { + width: 250px; +} + +button { + width: 125px; +} + +input:hover, button:hover { + background: rgb(0, 0, 180); +} + +input:active, button:active { + background: rgb(0, 0, 70); +} + +.Important { + font-weight: bold; +} + +.Results { + border: 4px dotted rgb(0, 0, 127); + background: rgba(0, 0, 255, 0.8); + color: rgb(255, 255, 255); +} diff --git a/Popups/Main.html b/Popups/Main.html new file mode 100644 index 0000000..82be8b2 --- /dev/null +++ b/Popups/Main.html @@ -0,0 +1,36 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="utf-8" /> + <link href="Main.css" rel="stylesheet" /> + </head> + <body> + <p>The extension does everything automatically.</p> + <p class="Important">Refresh the page in order for changes to take affect.</p> + <table> + <tr> + <th><input type="url" name="AddChannel" required></input></th> + <th><input type="url" name="RemoveChannel" required></input></th> + </tr> + <tr> + <td><button name="AddChannel">Add Channel</button></td> + <td><button name="RemoveChannel">Remove Channel</button></td> + </tr> + </table> + <p class="Results"></p> + <table> + <tr> + <th><input type="url" name="AddTopic" required></input></th> + <th><input type="url" name="RemoveTopic" required></input></th> + </tr> + <tr> + <td><button name="AddTopic">Add Topic</button></td> + <td><button name="RemoveTopic">Remove Topic</button></td> + </tr> + </table> + <p class="Results"></p> + <p>More stuff available in the options menu.</p> + + <script src="Main.js" type="text/javascript"></script> + </body> +</html> diff --git a/Popups/Main.js b/Popups/Main.js new file mode 100644 index 0000000..383c940 --- /dev/null +++ b/Popups/Main.js @@ -0,0 +1,103 @@ +// Removes at given index and then put last element at said index. +// Returns modified Array. +function RemoveAtIndex(arr, index) { + let Temp1 = arr[index]; + let Temp2 = arr[arr.length - 1]; + arr[index] = Temp2; + arr.pop(); + return arr; +} + +function AddChannel() { + browser.storage.local.get("ChannelList").then( + (List) => { + if (document.getElementsByName("AddChannel")[0].value == "") { + console.log("nothing in input, cancelling..."); + return; + } + // If there is no array, make new array. + if (Object.values(List).length == 0) { + browser.storage.local.set({ChannelList: [document.getElementsByName("AddChannel")[0].value]}); + } + // push a value to the existing array. + else { + let TempArray = Array.from(Object.values(List)[0]); + TempArray.push(document.getElementsByName("AddChannel")[0].value); + browser.storage.local.set({ChannelList: TempArray}); + } + } + ); +} + +function RemoveChannel() { + browser.storage.local.get("ChannelList").then( + (List) => { + if (Object.values(List).length != 0) { + let TempArray = Array.from(Object.values(List)[0]); + let index = TempArray.indexOf(document.getElementsByName("RemoveChannel")[0].value); + if (index != -1) { + TempArray = RemoveAtIndex(TempArray, index); + browser.storage.local.set({ChannelList: TempArray}); + } + } + } + ); +} + +function AddTopic() { + browser.storage.local.get("TopicList").then( + (List) => { + if (document.getElementsByName("AddTopic")[0].value == "") { + console.log("nothing in input, cancelling..."); + return; + } + // If there is no array, make new array. + if (Object.values(List).length == 0) { + browser.storage.local.set({TopicList: [document.getElementsByName("AddTopic")[0].value]}); + } + // push a value to the existing array. + else { + let TempArray = Array.from(Object.values(List)[0]); + TempArray.push(document.getElementsByName("AddTopic")[0].value); + browser.storage.local.set({TopicList: TempArray}); + } + } + ); +} + +function RemoveTopic() { + browser.storage.local.get("TopicList").then( + (List) => { + if (Object.values(List).length != 0) { + let TempArray = Array.from(Object.values(List)[0]); + let index = TempArray.indexOf(document.getElementsByName("RemoveTopic")[0].value); + if (index != -1) { + TempArray = RemoveAtIndex(TempArray, index); + browser.storage.local.set({TopicList: TempArray}); + } + } + } + ); +} + +// Now... load stuff! +window.onload = (event) => { + document.getElementsByName("AddChannel")[1].addEventListener("click", AddChannel); + document.getElementsByName("RemoveChannel")[1].addEventListener("click", RemoveChannel); + browser.storage.local.get("ChannelList").then( + (List) => { + for (let i of Object.values(List)[0]) { + document.getElementsByClassName("Results")[0].innerHTML += "<p> "+ i + " </p>"; + } + } + ); + document.getElementsByName("AddTopic")[1].addEventListener("click", AddTopic); + document.getElementsByName("RemoveTopic")[1].addEventListener("click", RemoveTopic); + browser.storage.local.get("TopicList").then( + (List) => { + for (let i of Object.values(List)[0]) { + document.getElementsByClassName("Results")[1].innerHTML += "<p> "+ i + " </p>"; + } + } + ); +}; diff --git a/README.md b/README.md new file mode 100644 index 0000000..23b9bf1 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# StudioModifier + +Customizes the YouTube Studio to remove all stats and competitiveness. This makes posting YouTube videos a lot more fun. diff --git a/manifest.json b/manifest.json new file mode 100644 index 0000000..db28b28 --- /dev/null +++ b/manifest.json @@ -0,0 +1,25 @@ +{ + "manifest_version": 2, + "name": "Studio Modifier", + "author": "CatAClock", + "version": "1.0.3", + "description": "Customizes the YouTube Studio to remove all stats and competitiveness. This makes posting YouTube videos a lot more fun.", + "icons": { + "64": "Icons/Icon.png" + }, + "browser_action": { + "default_icon": "Icons/Icon.png", + "default_title": "Studio Modifier", + "default_popup": "Popups/Main.html" + }, + "options_ui": { + "page": "Options/Main.html" + }, + "content_scripts": [ + { + "matches": ["*://studio.youtube.com/*"], + "js": ["ContentScripts/StudioModify.js"] + } + ], + "permissions": ["storage"] +}