schoolbox web extension :)
0
fork

Configure Feed

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

Merge branch 'main' into feat/plugins/change-logo

willow 6bfbbb37 ce36a69a

+48 -32
+7
CHANGELOG.md
··· 1 1 # Changelog 2 2 3 + ## [4.3.4](https://github.com/schooltape/schooltape/compare/v4.3.3...v4.3.4) (2025-12-15) 4 + 5 + 6 + ### Bug Fixes 7 + 8 + * **plugins/homepageSwitcher:** closing tabs ([3db3c02](https://github.com/schooltape/schooltape/commit/3db3c021a51f8e2401c2c6f0f838b3065a723876)) 9 + 3 10 ## [4.3.3](https://github.com/schooltape/schooltape/compare/v4.3.2...v4.3.3) (2025-12-12) 4 11 5 12
+1 -1
package.json
··· 1 1 { 2 2 "name": "schooltape", 3 - "version": "4.3.3", 3 + "version": "4.3.4", 4 4 "author": "42willow", 5 5 "devDependencies": { 6 6 "@catppuccin/palette": "^1.7.1",
+20 -23
src/entrypoints/background.ts
··· 1 1 import type { Browser } from "#imports"; 2 2 import { browser, defineBackground, storage } from "#imports"; 3 3 import { logger } from "@/utils/logger"; 4 + import type { BackgroundMessage } from "@/utils/storage"; 4 5 import { globalSettings, updated } from "@/utils/storage"; 5 6 import semver from "semver"; 6 7 ··· 48 49 // update icon when toggle or update is changed 49 50 globalSettings.watch(updateIcon); 50 51 51 - // listen for messages 52 - interface Message { 53 - resetSettings?: boolean; 54 - inject?: string; 55 - toTab?: string; 56 - updateIcon?: boolean; 57 - } 52 + browser.runtime.onMessage.addListener(async (msg: BackgroundMessage, sender: Browser.runtime.MessageSender) => { 53 + logger.child({ message: msg, sender }).info("[background] received message"); 58 54 59 - // eslint-disable-next-line @typescript-eslint/no-explicit-any 60 - browser.runtime.onMessage.addListener(async (msg: any, sender: any) => { 61 - const message = msg as Message; 62 - logger.child({ message, sender }).info("[background] Received message"); 63 - 64 - if (message.resetSettings) { 65 - resetSettings(); 66 - } else if (message.toTab) { 67 - const tabs = await browser.tabs.query({ url: message.toTab }); 68 - if (tabs.length > 0) { 69 - browser.tabs.update(tabs[0].id, { active: true }); 70 - } else if (sender.tab?.id) { 71 - browser.tabs.update(sender.tab.id, { url: message.toTab }); 72 - } 73 - } else if (message.updateIcon) { 74 - updateIcon(); 55 + switch (msg.type) { 56 + case "resetSettings": 57 + resetSettings(); 58 + break; 59 + case "updateIcon": 60 + updateIcon(); 61 + break; 62 + case "closeTab": 63 + if (!sender.tab?.id) break; 64 + browser.tabs.remove(sender.tab.id); 65 + break; 66 + case "updateTabUrl": 67 + if (!sender.tab?.id) break; 68 + browser.tabs.update(sender.tab.id, { url: msg.url }); 69 + break; 70 + default: 71 + logger.error(`[background] unknown message received: ${msg}`); 75 72 } 76 73 77 74 return true; // return success
+4 -4
src/entrypoints/plugins/homepageSwitcher/index.ts
··· 1 - import { browser } from "#imports"; 1 + import { sendMessage } from "@/utils"; 2 2 import { Plugin } from "@/utils/plugin"; 3 3 import type { Toggle } from "@/utils/storage"; 4 4 import type { StorageState } from "@/utils/storage/state.svelte"; ··· 40 40 e.preventDefault(); 41 41 42 42 if (logos) { 43 - const tab = logos[0].href; 44 - if (closeCurrentTab.toggle) window.close(); // TODO: Scripts may only close windows that were opened by a script. 45 - browser.runtime.sendMessage({ toTab: tab }); 43 + const tabUrl = logos[0].href; 44 + if (closeCurrentTab.toggle) sendMessage({ type: "closeTab" }); 45 + sendMessage({ type: "updateTabUrl", url: tabUrl }); 46 46 } 47 47 }, 48 48 {
+3 -2
src/entrypoints/popup/App.svelte
··· 1 1 <script lang="ts"> 2 2 import { flavors } from "@catppuccin/palette"; 3 3 import { globalSettings, updated } from "@/utils/storage"; 4 - import { browser, onMount } from "#imports"; 4 + import { onMount } from "#imports"; 5 5 6 6 import Router from "svelte-spa-router"; 7 7 import active from "svelte-spa-router/active"; ··· 9 9 import Plugins from "./routes/Plugins.svelte"; 10 10 import Themes from "./routes/Themes.svelte"; 11 11 import Snippets from "./routes/Snippets.svelte"; 12 + import { sendMessage } from "@/utils"; 12 13 13 14 const routes = { 14 15 "/": Home, ··· 27 28 28 29 onMount(() => { 29 30 updated.update({ icon: false }); 30 - browser.runtime.sendMessage({ updateIcon: true }); 31 + sendMessage({ type: "updateIcon" }); 31 32 }); 32 33 </script> 33 34
+2 -1
src/entrypoints/popup/components/Footer.svelte
··· 4 4 import { updated } from "@/utils/storage"; 5 5 import Button from "./inputs/Button.svelte"; 6 6 import { RotateCcw, Globe, GitBranch } from "@lucide/svelte"; 7 + import { sendMessage } from "@/utils"; 7 8 8 9 let version = $state(); 9 10 ··· 63 64 classList="text-ctp-text hover:text-ctp-base hover:bg-ctp-red" 64 65 onclick={() => { 65 66 if (confirm("Are you sure you want to reset all settings?")) { 66 - browser.runtime.sendMessage({ resetSettings: true }); 67 + sendMessage({ type: "resetSettings" }); 67 68 location.reload(); 68 69 } 69 70 }}><RotateCcw size={22} /></Button>
+2 -1
src/entrypoints/start.content.ts
··· 5 5 injectStylesheet, 6 6 injectUserSnippet, 7 7 onSchoolboxPage, 8 + sendMessage, 8 9 uninjectCatppuccin, 9 10 uninjectStylesheet, 10 11 uninjectUserSnippet, ··· 89 90 } 90 91 91 92 // update icon 92 - browser.runtime.sendMessage({ updateIcon: true }); 93 + sendMessage({ type: "updateIcon" }); 93 94 } 94 95 }, 95 96 });
+3
src/utils/index.ts
··· 1 1 import { flavorEntries } from "@catppuccin/palette"; 2 2 import { logger } from "./logger"; 3 + import type { BackgroundMessage } from "./storage"; 3 4 import { globalSettings, schoolboxUrls } from "./storage"; 4 5 5 6 export const dataAttr = (id: string) => `[data-schooltape="${id}"]`; ··· 10 11 export async function onSchoolboxPage(): Promise<boolean> { 11 12 return (await schoolboxUrls.get()).urls.includes(window.location.origin); 12 13 } 14 + 15 + export const sendMessage = (msg: BackgroundMessage) => browser.runtime.sendMessage(msg); 13 16 14 17 export function injectInlineStyles(styleText: string, id: string) { 15 18 logger.info(`injecting styles with id ${id}`);
+6
src/utils/storage/types.ts
··· 1 + export type BackgroundMessage = 2 + | { type: "resetSettings" } 3 + | { type: "updateIcon" } 4 + | { type: "closeTab" } 5 + | { type: "updateTabUrl"; url: string }; 6 + 1 7 // global 2 8 export interface SettingsV1 { 3 9 global: boolean;