From e449edf887ced9ec1e7dda2bceb8efffc1b55819 Mon Sep 17 00:00:00 2001 From: CatAClock Date: Tue, 15 Apr 2025 11:59:49 -0700 Subject: [PATCH] codeberg copy --- ContentScripts/StudioModify.js | 406 +++++++++++++++++++++++++++++++++ Icons/Icon.png | Bin 0 -> 2599 bytes Icons/Icon.svg | 49 ++++ LICENSE.md | 131 +++++++++++ Options/Main.html | 16 ++ Popups/Main.css | 39 ++++ Popups/Main.html | 36 +++ Popups/Main.js | 103 +++++++++ README.md | 3 + manifest.json | 25 ++ 10 files changed, 808 insertions(+) create mode 100644 ContentScripts/StudioModify.js create mode 100644 Icons/Icon.png create mode 100644 Icons/Icon.svg create mode 100644 LICENSE.md create mode 100644 Options/Main.html create mode 100644 Popups/Main.css create mode 100644 Popups/Main.html create mode 100644 Popups/Main.js create mode 100644 README.md create mode 100644 manifest.json 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 0000000000000000000000000000000000000000..25613f0ec9254642a7a96263569c11c717e3563d GIT binary patch literal 2599 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 S1!MfCl^61xOWOXBu{8isv+XX9k@q z9E?AvV85qXui-6VS5uCu|K81)pV>_?7QmfYgE@W>)DG}hhXS~;!+N192Y=lPs~W)& z>;P^`O1Zog`?~Z1zz>97L;}Zyy;<0ng53uRyNx+MTD=&8l-6w4umM;DYy>u3m6Q!1 zYwov7sW5O^s=)03?M1%OK&55i)egXzlz{OAA!Pb{15a+p&1)Rs0Z;QQDP^`4@^FOT z<=gSp5|zGu7?E$DdXVVujDNKE?2a^U)1gFd4R34B`Xb49&OvD2(bQh71W&^g%8rW`?DBcG3W?zgy3CI^Cm@- z#baB?xwa>vlrn$|011o&9+Xl(f2{3wnNE3{mGw5Yd$Vly{2tvv(RDR!P9|mVRW1($ zDWwOzQarkiQu4_k0ykZql)0YxV1GlGL*RHvzpf7V1x|PY{tvV-49uEXk?{Zk002ov JPDHLkV1fz8-^Ty| literal 0 HcmV?d00001 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 @@ + + + + + + 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 + + + +## 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 @@ + + + + + + +

The extension does everything automatically.

+ +

FAQ

+

The extension does not work when loading into YouTube Studio!

+

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.

+

Solution 2: Try bookmarking "https://studio.youtube.com/channel/" instead of your personal link to give it more time to load and respond.

+

Where are the items in the extension popup located?

+

In the dashboard and analytics respectively.

+ + 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 @@ + + + + + + + +

The extension does everything automatically.

+

Refresh the page in order for changes to take affect.

+ + + + + + + + + +
+

+ + + + + + + + + +
+

+

More stuff available in the options menu.

+ + + + 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 += "

"+ i + "

"; + } + } + ); + 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 += "

"+ i + "

"; + } + } + ); +}; 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"] +}