schoolbox web extension :)
0
fork

Configure Feed

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

feat(plugins/modernIcons): hot reload

willow 1ca8ac9c 5f7ec27f

+83 -64
+83 -64
src/entrypoints/plugins/modernIcons/index.ts
··· 1 - import { injectInlineStyles, injectStylesheet, uninjectInlineStyles, uninjectStylesheet } from "@/utils"; 1 + import { 2 + dataAttr, 3 + injectInlineStyles, 4 + injectStylesheet, 5 + setDataAttr, 6 + uninjectInlineStyles, 7 + uninjectStylesheet, 8 + } from "@/utils"; 2 9 import { definePlugin } from "@/utils/plugin"; 3 10 import styleText from "./styles.css?inline"; 4 - import { logger } from "@/utils/logger"; 11 + 12 + const ID = "modernIcons"; 13 + const PLUGIN_ID = `plugin-${ID}`; 5 14 6 15 export default function init() { 7 16 definePlugin( 8 - "modernIcons", 17 + ID, 9 18 async (settings) => { 10 - // [className, iconName] (material icons) 11 - const icons = { 12 - "icon-teacher": "school", 13 - "icon-due-work": "inventory_2", 14 - "icon-task": "inventory", 15 - "icon-timetable": "schedule", 16 - "icon-calendar": "calendar_month", 17 - "icon-news": "newspaper", 18 - "icon-email": "email", 19 - "icon-wolfram-alpha": "web", 20 - "icon-comment": "translate", 21 - "icon-canvas-lms": "medical_services", 22 - "icon-video": "videocam", 23 - "icon-office-365": "dvr", 24 - "icon-google-drive": "drive_export", 25 - "icon-help": "help", 26 - "icon-podcast": "music_note", 27 - "icon-music": "music_note", 28 - "icon-staff-students": "account_circle", 29 - "icon-settings": "settings", 30 - "icon-logout": "logout", 31 - "icon-course": "class", 32 - "icon-reply": "reply", 33 - "icon-approve": "check_circle", 34 - "icon-forms": "check_box", 35 - "icon-group": "group", 36 - "icon-info": "info", 37 - "icon-resource-booking": "photo_camera", 38 - "icon-files": "description", 39 - "icon-schoolbox": "language", 40 - "icon-user": "person", 41 - "icon-cloudy": "cloud", 42 - "icon-eportfolio": "work", 43 - "icon-open": "door_open", 44 - }; 45 - 46 - function insertIcon(className: string, iconName: string, fill: boolean) { 47 - const selectors = [`nav.tab-bar .top-menu .${className}`, `#overflow-nav .${className}`]; 48 - selectors.forEach((selector) => { 49 - const icon = document.querySelector(selector); 50 - // Check if the icon already exists 51 - if (icon && !icon.querySelector(".material-symbols-rounded")) { 52 - // logger.info(`Inserting icon for ${className} at ${selector}`); 53 - const iconElement = document.createElement("i"); 54 - iconElement.innerHTML = iconName; 55 - iconElement.classList.add("material-symbols-rounded"); 56 - iconElement.style.fontVariationSettings = `"FILL" ${fill ? "1" : "0"}`; 57 - icon.insertBefore(iconElement, icon.firstChild); 58 - } 59 - }); 60 - } 61 - 62 19 const iconNames = [...new Set(Object.values(icons))].sort(); 63 20 const fontUrl = `https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:FILL@0..1&icon_names=${iconNames.join(",")}`; 64 - // logger.info(fontUrl); 65 21 66 22 // inject font face 67 - injectStylesheet(fontUrl, "plugin-modernIcons"); 23 + injectStylesheet(fontUrl, PLUGIN_ID); 68 24 69 25 // inject icon styling 70 - injectInlineStyles(styleText, "plugin-modernIcons"); 26 + injectInlineStyles(styleText, PLUGIN_ID); 71 27 72 - for (const [className, iconName] of Object.entries(icons)) { 73 - insertIcon(className, iconName, settings?.toggle.filled ?? false); 74 - } 28 + // inject icons 29 + const filled = settings?.toggle.filled ?? false; 30 + injectIcons(icons, filled); 75 31 }, 76 32 () => { 77 - uninjectStylesheet("plugin-modernIcons"); 78 - uninjectInlineStyles("plugin-modernIcons"); 79 - logger.warn("not implemented!"); 33 + uninjectStylesheet(PLUGIN_ID); 34 + uninjectInlineStyles(PLUGIN_ID); 35 + uninjectIcons(); 80 36 }, 81 37 ["nav.tab-bar .top-menu", "#overflow-nav"], 82 38 ); 83 39 } 40 + 41 + // [className, iconName] (material icons) 42 + const icons = { 43 + "icon-teacher": "school", 44 + "icon-due-work": "inventory_2", 45 + "icon-task": "inventory", 46 + "icon-timetable": "schedule", 47 + "icon-calendar": "calendar_month", 48 + "icon-news": "newspaper", 49 + "icon-email": "email", 50 + "icon-wolfram-alpha": "web", 51 + "icon-comment": "translate", 52 + "icon-canvas-lms": "medical_services", 53 + "icon-video": "videocam", 54 + "icon-office-365": "dvr", 55 + "icon-google-drive": "drive_export", 56 + "icon-help": "help", 57 + "icon-podcast": "music_note", 58 + "icon-music": "music_note", 59 + "icon-staff-students": "account_circle", 60 + "icon-settings": "settings", 61 + "icon-logout": "logout", 62 + "icon-course": "class", 63 + "icon-reply": "reply", 64 + "icon-approve": "check_circle", 65 + "icon-forms": "check_box", 66 + "icon-group": "group", 67 + "icon-info": "info", 68 + "icon-resource-booking": "photo_camera", 69 + "icon-files": "description", 70 + "icon-schoolbox": "language", 71 + "icon-user": "person", 72 + "icon-cloudy": "cloud", 73 + "icon-eportfolio": "work", 74 + "icon-open": "door_open", 75 + }; 76 + 77 + function injectIcons(icons: Record<string, string>, filled: boolean) { 78 + for (const [className, iconName] of Object.entries(icons)) { 79 + const selectors = [`nav.tab-bar .top-menu .${className}`, `#overflow-nav .${className}`]; 80 + 81 + for (const selector of selectors) { 82 + const icon = document.querySelector(selector); 83 + // check if the icon already exists 84 + if (icon && !icon.querySelector(".material-symbols-rounded")) { 85 + // logger.info(`inserting icon for ${className} at ${selector}`); 86 + const iconElement = document.createElement("i"); 87 + iconElement.innerHTML = iconName; 88 + iconElement.classList.add("material-symbols-rounded"); 89 + iconElement.style.fontVariationSettings = `"FILL" ${filled ? "1" : "0"}`; 90 + setDataAttr(iconElement, `${PLUGIN_ID}-icon`); 91 + icon.insertBefore(iconElement, icon.firstChild); 92 + } 93 + } 94 + } 95 + } 96 + 97 + function uninjectIcons() { 98 + const icons = document.querySelectorAll(dataAttr(`${PLUGIN_ID}-icon`)); 99 + for (const icon of icons) { 100 + icon.parentNode?.removeChild(icon); 101 + } 102 + }