schoolbox web extension :)
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

refactor: options page Title component

Willow 24f058a5 efeff983

+285 -39
+4 -1
src/options/Popup.svelte
··· 15 15 const storage = await browser.storage.local.get("themes"); 16 16 flavour = storage.themes.flavour; 17 17 // console.log("flavour", flavour); 18 + 18 19 browser.storage.onChanged.addListener((changes, areaName) => { 19 20 if (areaName === "local" && changes.themes) { 20 - flavour = changes.themes.newValue.flavour; 21 + try { 22 + flavour = changes.themes.newValue.flavour; 23 + } catch {} 21 24 } 22 25 }); 23 26 });
+4 -12
src/options/components/Footer.svelte
··· 6 6 let verNum; 7 7 onMount(async () => { 8 8 verNum = "v" + browser.runtime.getManifest().version; 9 - 10 - const resetButton = document.getElementById("reset"); 11 - if (resetButton) { 12 - resetButton.addEventListener("click", function () { 13 - if (confirm("Are you sure you want to reset all settings?")) { 14 - browser.runtime.sendMessage({ resetSettings: true }); 15 - location.reload(); 16 - } 17 - }); 18 - } 19 9 }); 20 10 21 11 function handleSupportClick() { ··· 23 13 } 24 14 25 15 function handleResetClick() { 26 - browser.runtime.sendMessage({ resetSettings: true }); 27 - location.reload(); 16 + if (confirm("Are you sure you want to reset all settings?")) { 17 + browser.runtime.sendMessage({ resetSettings: true }); 18 + location.reload(); 19 + } 28 20 } 29 21 30 22 function handleBugClick() {
+22
src/options/components/Title.svelte
··· 1 + <script> 2 + import browser from 'webextension-polyfill'; 3 + 4 + export let data = {}; 5 + export let title = ''; 6 + export let key = ''; 7 + 8 + function setStorage() { 9 + browser.storage.local.set({ [key]: data }); 10 + } 11 + </script> 12 + 13 + <label class="relative flex justify-between items-center group p-2 text-xl text-ctp-text"> 14 + <h2>{title}</h2> 15 + <input 16 + id="theme-toggle" 17 + type="checkbox" 18 + class="absolute left-1/2 -translate-x-1/2 w-full h-full peer appearance-none rounded-md" 19 + bind:checked={data.toggle} 20 + on:change={setStorage} /> 21 + <span class="slider big"></span> 22 + </label>
+3 -15
src/options/pages/Plugins.svelte
··· 1 1 <script> 2 2 import { onMount } from "svelte"; 3 3 import browser from "webextension-polyfill"; 4 + import Title from "../components/Title.svelte"; 4 5 5 6 let plugins = { 6 7 toggle: false, ··· 13 14 const response = await fetch("/plugins.json"); 14 15 const data = await response.json(); 15 16 const storage = await browser.storage.local.get(); 16 - console.log(storage.plugins.enabled); 17 + console.log("plugins", storage.plugins); 17 18 plugins = storage.plugins; 18 19 populatedPlugins = Object.entries(data).map(([pluginId, pluginData]) => { 19 20 return { ··· 33 34 } 34 35 await browser.storage.local.set({ plugins: plugins }); 35 36 } 36 - 37 - async function togglePlugins() { 38 - await browser.storage.local.set({ plugins: plugins }); 39 - } 40 37 </script> 41 38 42 39 <div id="card"> 43 - <label class="relative flex justify-between items-center group p-2 text-xl text-ctp-text"> 44 - <h2 class="from-blue to-teal">Plugins</h2> 45 - <input 46 - id="theme-toggle" 47 - type="checkbox" 48 - class="absolute left-1/2 -translate-x-1/2 w-full h-full peer appearance-none rounded-md" 49 - bind:checked={plugins.toggle} 50 - on:change={togglePlugins} /> 51 - <span class="slider big"></span> 52 - </label> 40 + <Title title="Plugins" data={plugins} key="plugins" /> 53 41 54 42 <div class="plugins-container"> 55 43 {#each populatedPlugins as plugin (plugin.id)}
+250 -1
src/options/pages/Snippets.svelte
··· 1 - snippets 1 + <script> 2 + import { onMount } from "svelte"; 3 + import browser from "webextension-polyfill"; 4 + import Title from "../components/Title.svelte" 5 + 6 + let snippets = { 7 + toggle: false, 8 + }; 9 + 10 + let populatedSnippets = []; 11 + 12 + onMount(async () => { 13 + const storage = await browser.storage.local.get(); 14 + snippets = storage.snippets; 15 + console.log("snippets", snippets); 16 + }); 17 + // // add snippet listener 18 + // document.getElementById("snippet-form").addEventListener("submit", function (event) { 19 + // event.preventDefault(); 20 + // let url = document.getElementById("snippet-input").value; 21 + // if (url) { 22 + // console.log(url); 23 + 24 + // // if is link, send request 25 + // if (url.startsWith("http") && url.includes("gist.github.com")) { 26 + // console.log("Downloading snippet..."); 27 + // // send request to get snippet 28 + // fetch(url + "/raw") 29 + // .then((response) => response.text()) 30 + // .then((cssSnippet) => { 31 + // console.log(cssSnippet); 32 + // let nameMatch = cssSnippet.match(/\/\*\s*name:\s*(.*?)\s*\*\//); 33 + // let descriptionMatch = cssSnippet.match(/\/\*\s*description:\s*(.*?)\s*\*\//); 34 + // let snippetName = nameMatch ? nameMatch[1] : null; 35 + // let snippetDescription = descriptionMatch ? descriptionMatch[1] : null; 36 + // let sections = url.split("/"); 37 + // let snippetAuthor = sections[3]; 38 + // let snippetID = sections[sections.length - 1].split(".")[0]; 39 + 40 + // // example URL: https://gist.githubusercontent.com/42Willow/98435ecb3d871ecf14659936cdf36105 41 + // console.log(`author: ${snippetAuthor}`); // Outputs: 42Willow 42 + // console.log(`id: ${snippetID}`); // Outputs: hide-iframes 43 + // console.log(`name: ${snippetName}`); // Outputs: Hide homepage iframe 44 + // console.log(`description: ${snippetDescription}`); // Outputs: Useful for use with dark mode themes 45 + 46 + // let snip = { 47 + // [snippetID]: { 48 + // name: snippetName, 49 + // author: snippetAuthor, 50 + // description: snippetDescription, 51 + // }, 52 + // }; 53 + 54 + // if (Object.values(snip[snippetID]).includes(null)) { 55 + // alert("This snippet is missing a name or description"); 56 + // return; 57 + // } 58 + // console.log(snip); 59 + 60 + // // modify the settings to add to list of userSnippets 61 + // chrome.storage.local.get(["settings"], function (settingsData) { 62 + // let settings = settingsData.settings; 63 + // // if not already installed 64 + // if (settings.userSnippets.some((e) => e[snippetID])) { 65 + // alert("This snippet is already installed."); 66 + // return; 67 + // } 68 + // settings.userSnippets.push(snip); 69 + // chrome.storage.local.set({ settings: settings }, function () { 70 + // console.log(`Installed snippet ${snip}`); 71 + // }); 72 + // addUserSnippets(); 73 + // }); 74 + // }); 75 + // } else if (url.startsWith("http") && url.includes("gist") && url.includes("raw")) { 76 + // alert("Please use the main URL of the Gist, not the raw URL."); 77 + // } else { 78 + // alert("Please enter a valid URL."); 79 + // } 80 + // } 81 + // }); 82 + 83 + // fetch("/snippets/snippets.json") 84 + // .then((response) => response.json()) 85 + // .then((data) => { 86 + // // console.log(data); 87 + 88 + // // add snippets from the json file 89 + // addSnippets(data); 90 + 91 + // // add user installed snippets 92 + // addUserSnippets(); 93 + // }); 94 + 95 + // // Add snippets to the page 96 + // function addSnippets(data) { 97 + // chrome.storage.local.get(["settings"], function (settingsData) { 98 + // let options = document.querySelector(".snippets-container"); 99 + // let snippets = Object.entries(data); 100 + // // console.log(snippets); 101 + // // console.log(settingsData); 102 + // snippets.forEach((snippet) => { 103 + // // console.log(snippet); 104 + // let snippetId = snippet[0]; 105 + // let snippetName = snippet[1].name; 106 + // let snippetDescription = snippet[1].description; 107 + // let snippetToggled = settingsData.settings.enabledSnippets.includes(snippetId); 108 + // let option = document.createElement("div"); 109 + // option.classList.add("my-4"); 110 + // option.classList.add("group"); 111 + // option.innerHTML = ` 112 + // <label class="relative flex justify-between items-center group py-2 text-xl text-ctp-text"> 113 + // <h4 class="text-ctp-text">${snippetName}</h4> 114 + // <input snippet-id="${snippetId}" ${snippetToggled ? "checked" : ""} type="checkbox" class="snippet-toggle absolute left-1/2 -translate-x-1/2 w-full h-full peer appearance-none rounded-md" /> 115 + // <span class="w-11 h-5 flex items-center flex-shrink-0 ml-4 p-1 bg-ctp-red rounded-lg duration-500 ease-in-out peer-checked:bg-ctp-green after:w-3 after:h-3 after:bg-ctp-base after:rounded-lg after:shadow-md after:duration-300 peer-checked:after:translate-x-6 group-hover:after:translate-x-1"></span> 116 + // </label> 117 + // <div class="text-subtext0 group-hover:text-subtext1">${snippetDescription}</div> 118 + // `; 119 + // options.appendChild(option); 120 + // }); 121 + // }); 122 + // } 123 + 124 + // function addUserSnippets() { 125 + // chrome.storage.local.get(["settings"], function (settingsData) { 126 + // let settings = settingsData.settings; 127 + // let snippets = settings.userSnippets; 128 + // let options = document.querySelector(".user-snippets-container"); 129 + // // clear the container 130 + // options.innerHTML = ""; 131 + // // console.log(snippets); 132 + // if (snippets.length > 0) { 133 + // snippets.forEach((snippet) => { 134 + // let snippetId = Object.keys(snippet)[0]; 135 + // let snippetName = snippet[snippetId].name; 136 + // let snippetDescription = snippet[snippetId].description; 137 + // let snippetURL = `https://gist.github.com/${snippet[snippetId].author}/${snippetId}`; 138 + // let option = document.createElement("div"); 139 + // let snippetToggled = settingsData.settings.enabledSnippets.includes(snippetId); 140 + // option.classList.add("my-4"); 141 + // option.classList.add("group"); 142 + // option.innerHTML = ` 143 + // <label class="relative flex justify-between items-center group py-2 text-xl text-ctp-text"> 144 + // <h4 class="text-ctp-text">${snippetName}</h4> 145 + // <input snippet-id="${snippetId}" ${snippetToggled ? "checked" : ""} type="checkbox" class="snippet-toggle absolute left-1/2 -translate-x-1/2 w-full h-full peer appearance-none rounded-md" /> 146 + // <span class="w-11 h-5 flex items-center flex-shrink-0 ml-4 p-1 bg-ctp-red rounded-lg duration-500 ease-in-out peer-checked:bg-ctp-green after:w-3 after:h-3 after:bg-ctp-base after:rounded-lg after:shadow-md after:duration-300 peer-checked:after:translate-x-6 group-hover:after:translate-x-1"></span> 147 + // </label> 148 + // <div class="text-subtext0 group-hover:text-subtext1 mb-2">${snippetDescription}</div> 149 + // <a href="${snippetURL}" target="_blank"><button class="text-xs rounded-md px-1 py-0.5 bg-ctp-base text-ctp-text hover:text-crust hover:bg-ctp-pink">Gist</button></a> 150 + // <button snippet-id="${snippetId}" class="remove-snippet text-xs rounded-md px-1 py-0.5 bg-ctp-base text-ctp-text hover:text-crust hover:bg-ctp-red">Remove</button> 151 + // `; 152 + // options.appendChild(option); 153 + // }); 154 + // } 155 + 156 + // // setup toggle listeners 157 + // let snippetToggles = document.querySelectorAll(".snippet-toggle"); 158 + 159 + // snippetToggles.forEach((toggle) => { 160 + // // console.log(toggle); 161 + // toggle.addEventListener("click", toggleClicked); 162 + // }); 163 + 164 + // // setup remove listeners 165 + // let removeButtons = document.querySelectorAll(".remove-snippet"); 166 + 167 + // removeButtons.forEach((button) => { 168 + // button.addEventListener("click", removeClicked); 169 + // }); 170 + // }); 171 + // } 172 + 173 + // function toggleClicked(event) { 174 + // // console.log(event.target); 175 + // let snippetId = event.target.getAttribute("snippet-id"); 176 + // if (event.target.checked) { 177 + // installSnippet(snippetId); 178 + // } else { 179 + // uninstallSnippet(snippetId); 180 + // } 181 + // } 182 + 183 + // function removeClicked(event) { 184 + // let snippetId = event.target.getAttribute("snippet-id"); 185 + // chrome.storage.local.get(["settings"], function (settingsData) { 186 + // let settings = settingsData.settings; 187 + // let index = settings.enabledSnippets.indexOf(snippetId); 188 + // if (index !== -1) { 189 + // settings.enabledSnippets.splice(index, 1); 190 + // } 191 + // settings.userSnippets.splice( 192 + // settings.userSnippets.findIndex((e) => e[snippetId]), 193 + // 1, 194 + // ); 195 + // chrome.storage.local.set({ settings: settings }, function () { 196 + // console.log(`Removed snippet ${snippetId}`); 197 + // }); 198 + // addUserSnippets(); 199 + // }); 200 + // } 201 + 202 + // function installSnippet(snippetId) { 203 + // chrome.storage.local.get(["settings"], function (settingsData) { 204 + // let settings = settingsData.settings; 205 + // settings.enabledSnippets.push(snippetId); 206 + // chrome.storage.local.set({ settings: settings }, function () { 207 + // console.log(`Installed snippet ${snippetId}`); 208 + // }); 209 + // }); 210 + // } 211 + // function uninstallSnippet(snippetId) { 212 + // chrome.storage.local.get(["settings"], function (settingsData) { 213 + // let settings = settingsData.settings; 214 + // settings.enabledSnippets.splice(settings.enabledSnippets.indexOf(snippetId), 1); 215 + // chrome.storage.local.set({ settings: settings }, function () { 216 + // console.log(`Uninstalled snippet ${snippetId}`); 217 + // }); 218 + // }); 219 + // } 220 + </script> 221 + 222 + <div id="card"> 223 + <Title title="Snippets" data={snippets} key="snippets" /> 224 + 225 + <div class="snippets-container w-full"></div> 226 + <div class="w-full"> 227 + <h3 class="text-ctp-text my-4">User Snippets</h3> 228 + <p class="text-ctp-overlay2 mb-4"> 229 + To learn how to make your own snippets, please read the 230 + <a 231 + class="text-ctp-blue hover:underline" 232 + href="https://github.com/42Willow/schooltape/wiki/Contributing#snippets" 233 + target="_blank">wiki</a 234 + >. 235 + </p> 236 + <!-- input box to make new snippet --> 237 + <form id="snippet-form" class="w-full"> 238 + <div class="flex justify-center items-center w-full"> 239 + <input 240 + id="snippet-input" 241 + class="w-full p-2 rounded-l-xl bg-ctp-surface0 text-ctp-text" 242 + type="text" 243 + placeholder="Gist URL" /> 244 + <button id="add-snippet" class="p-2 rounded-r-xl bg-ctp-pink text-ctp-crust" type="submit">Add</button> 245 + </div> 246 + </form> 247 + </div> 248 + 249 + <div class="user-snippets-container w-full"></div> 250 + </div>
+2 -10
src/options/pages/Themes.svelte
··· 1 1 <script> 2 2 import { onMount } from "svelte"; 3 3 import browser from "webextension-polyfill"; 4 + import Title from "../components/Title.svelte"; 4 5 5 6 const flavours = ["latte", "frappe", "macchiato", "mocha"]; 6 7 const accents = [ ··· 45 46 </script> 46 47 47 48 <div id="card"> 48 - <label class="relative flex justify-between items-center group p-2 text-xl text-ctp-text"> 49 - <h2 class="from-blue to-teal">Themes</h2> 50 - <input 51 - id="theme-toggle" 52 - type="checkbox" 53 - class="absolute left-1/2 -translate-x-1/2 w-full h-full peer appearance-none rounded-md" 54 - bind:checked={themes.toggle} 55 - on:change={toggleTheme} /> 56 - <span class="slider big"></span> 57 - </label> 49 + <Title title="Themes" data={themes} key="themes" /> 58 50 59 51 <div id="flavours" class="flex my-6 py-2 rounded-xl text-ctp-text"> 60 52 {#each flavours as flavour}