diff --git a/src/interface/pages/settings/shortcuts.svelte b/src/interface/pages/settings/shortcuts.svelte index d507a7d8..0527be3d 100644 --- a/src/interface/pages/settings/shortcuts.svelte +++ b/src/interface/pages/settings/shortcuts.svelte @@ -23,13 +23,19 @@ }); }); - const switchChange = (shortcut: any) => { - const value = $settingsState.shortcuts.find(s => s.name === shortcut); - if (value) { - value.enabled = !value.enabled; - settingsState.shortcuts = settingsState.shortcuts; + const switchChange = (shortcut: any) => { + const idx = $settingsState.shortcuts.findIndex(s => s.name === shortcut); + if (idx !== -1) { + // Create a new array with the toggled value to ensure reactivity + const updated = settingsState.shortcuts.map(s => + s.name === shortcut ? { ...s, enabled: !s.enabled } : s + ); + settingsState.shortcuts = updated; } else { - settingsState.shortcuts = [...settingsState.shortcuts, { name: shortcut, enabled: true }]; + settingsState.shortcuts = [ + ...settingsState.shortcuts, + { name: shortcut, enabled: true } + ]; } } diff --git a/src/seqta/utils/Adders/AddShortcuts.ts b/src/seqta/utils/Adders/AddShortcuts.ts index ec233861..f3ae4146 100644 --- a/src/seqta/utils/Adders/AddShortcuts.ts +++ b/src/seqta/utils/Adders/AddShortcuts.ts @@ -26,6 +26,9 @@ export function addShortcuts(shortcuts: any) { function createNewShortcut(link: any, icon: any, viewBox: any, title: any) { // Creates the stucture and element information for each seperate shortcut + const container = document.getElementById("shortcuts"); + if (!container) return; + let shortcut = document.createElement("a"); shortcut.setAttribute("href", link); shortcut.setAttribute("target", "_blank"); @@ -42,5 +45,5 @@ function createNewShortcut(link: any, icon: any, viewBox: any, title: any) { shortcutdiv.append(text); shortcut.append(shortcutdiv); - document.getElementById("shortcuts")!.appendChild(shortcut); + container.appendChild(shortcut); } diff --git a/src/seqta/utils/CreateEnable/CreateCustomShortcutDiv.ts b/src/seqta/utils/CreateEnable/CreateCustomShortcutDiv.ts index ed986657..bca0557e 100644 --- a/src/seqta/utils/CreateEnable/CreateCustomShortcutDiv.ts +++ b/src/seqta/utils/CreateEnable/CreateCustomShortcutDiv.ts @@ -2,6 +2,9 @@ import stringToHTML from "../stringToHTML"; export function CreateCustomShortcutDiv(element: any) { // Creates the stucture and element information for each seperate shortcut + const container = document.getElementById("shortcuts"); + if (!container) return; + var shortcut = document.createElement("a"); shortcut.setAttribute("href", element.url); shortcut.setAttribute("target", "_blank"); @@ -45,5 +48,5 @@ export function CreateCustomShortcutDiv(element: any) { shortcutdiv.append(text); shortcut.append(shortcutdiv); - document.getElementById("shortcuts")!.append(shortcut); + container.append(shortcut); } diff --git a/src/seqta/utils/DisableRemove/RemoveShortcutDiv.ts b/src/seqta/utils/DisableRemove/RemoveShortcutDiv.ts deleted file mode 100644 index 5e76dc59..00000000 --- a/src/seqta/utils/DisableRemove/RemoveShortcutDiv.ts +++ /dev/null @@ -1,28 +0,0 @@ -import links from "@/seqta/content/links.json"; - -export function RemoveShortcutDiv(elements: any) { - if (elements.length === 0) return; - - elements.forEach((element: any) => { - const shortcuts = document.querySelectorAll(".shortcut"); - shortcuts.forEach((shortcut) => { - const anchorElement = shortcut.parentElement; // the element is the parent - const textElement = shortcut.querySelector("p"); //

is a direct child of .shortcut - const title = textElement ? textElement.textContent : ""; - - const elementName = links[element.name as keyof typeof links]?.DisplayName || element.name; - - let shouldRemove = title === elementName; - - // Check href only if element.url exists - if (element.url) { - shouldRemove = - shouldRemove && anchorElement!.getAttribute("href") === element.url; - } - - if (shouldRemove) { - anchorElement!.remove(); - } - }); - }); -} diff --git a/src/seqta/utils/Loaders/LoadHomePage.ts b/src/seqta/utils/Loaders/LoadHomePage.ts index 7a1eda0c..a31d70c1 100644 --- a/src/seqta/utils/Loaders/LoadHomePage.ts +++ b/src/seqta/utils/Loaders/LoadHomePage.ts @@ -4,12 +4,11 @@ import LogoLight from "@/resources/icons/betterseqta-light-icon.png"; import assessmentsicon from "@/seqta/icons/assessmentsIcon"; import coursesicon from "@/seqta/icons/coursesIcon"; import { GetThresholdOfColor } from "@/seqta/ui/colors/getThresholdColour"; -import { addShortcuts } from "../Adders/AddShortcuts"; import { convertTo12HourFormat } from "../convertTo12HourFormat"; import { delay } from "../delay"; import { settingsState } from "../listeners/SettingsState"; import stringToHTML from "../stringToHTML"; -import { CreateCustomShortcutDiv } from "@/seqta/utils/CreateEnable/CreateCustomShortcutDiv"; +import { renderShortcuts } from "@/seqta/utils/Render/renderShortcuts"; import { CreateElement } from "@/seqta/utils/CreateEnable/CreateElement"; import { FilterUpcomingAssessments } from "@/seqta/utils/FilterUpcomingAssessments"; import { getMockNotices } from "@/seqta/ui/dev/hideSensitiveContent"; @@ -100,12 +99,7 @@ export async function loadHomePage() { const cleanup = setupTimetableListeners(); - try { - addShortcuts(settingsState.shortcuts); - } catch (err: any) { - console.error("[BetterSEQTA+] Error adding shortcuts:", err.message || err); - } - AddCustomShortcutsToPage(); + renderShortcuts(); const date = new Date(); const TodayFormatted = formatDate(date); @@ -367,15 +361,6 @@ function comparedate(obj1: any, obj2: any) { return 0; } -async function AddCustomShortcutsToPage() { - let customshortcuts: any = settingsState.customshortcuts; - if (customshortcuts.length > 0) { - for (let i = 0; i < customshortcuts.length; i++) { - const element = customshortcuts[i]; - CreateCustomShortcutDiv(element); - } - } -} function processNotices(response: any, labelArray: string[]) { const NoticeContainer = document.getElementById("notice-container"); diff --git a/src/seqta/utils/Render/renderShortcuts.ts b/src/seqta/utils/Render/renderShortcuts.ts new file mode 100644 index 00000000..381ffc26 --- /dev/null +++ b/src/seqta/utils/Render/renderShortcuts.ts @@ -0,0 +1,26 @@ +import { settingsState } from "@/seqta/utils/listeners/SettingsState"; +import { addShortcuts } from "@/seqta/utils/Adders/AddShortcuts"; +import { CreateCustomShortcutDiv } from "@/seqta/utils/CreateEnable/CreateCustomShortcutDiv"; + +export function renderShortcuts() { + const container = document.getElementById("shortcuts"); + if (!container) return; + + container.innerHTML = ""; + + try { + addShortcuts(settingsState.shortcuts || []); + } catch (err: any) { + console.error("[BetterSEQTA+] Error adding built-in shortcuts:", err?.message || err); + } + + const custom = settingsState.customshortcuts || []; + for (const element of custom) { + try { + CreateCustomShortcutDiv(element); + } catch (err: any) { + console.error("[BetterSEQTA+] Error adding custom shortcut:", element?.name, err?.message || err); + } + } +} + diff --git a/src/seqta/utils/listeners/SettingsState.ts b/src/seqta/utils/listeners/SettingsState.ts index 28a73640..b749099d 100644 --- a/src/seqta/utils/listeners/SettingsState.ts +++ b/src/seqta/utils/listeners/SettingsState.ts @@ -29,19 +29,11 @@ class StorageManager { }, set: (target, prop: keyof SettingsState, value) => { const oldValue = target.data[prop]; - - // Only save if the value actually changed + + // Only save if the reference actually changed if (oldValue !== value) { Reflect.set(target.data, prop, value); target.saveToStorage(); - - // Notify listeners immediately for responsiveness - const listeners = target.listeners.get(prop as string); - if (listeners) { - for (const listener of listeners) { - listener(value, oldValue); - } - } } return true; }, diff --git a/src/seqta/utils/listeners/StorageChanges.ts b/src/seqta/utils/listeners/StorageChanges.ts index 3997420d..4edc5f83 100644 --- a/src/seqta/utils/listeners/StorageChanges.ts +++ b/src/seqta/utils/listeners/StorageChanges.ts @@ -1,10 +1,9 @@ import { settingsState } from "./SettingsState"; import { updateAllColors } from "@/seqta/ui/colors/Manager"; -import { addShortcuts } from "@/seqta/utils/Adders/AddShortcuts"; -import { CreateCustomShortcutDiv } from "@/seqta/utils/CreateEnable/CreateCustomShortcutDiv"; +// Shortcuts rendering +import { renderShortcuts } from "@/seqta/utils/Render/renderShortcuts"; import { FilterUpcomingAssessments } from "@/seqta/utils/FilterUpcomingAssessments"; -import { RemoveShortcutDiv } from "@/seqta/utils/DisableRemove/RemoveShortcutDiv"; import browser from "webextension-polyfill"; import type { CustomShortcut } from "@/types/storage"; @@ -47,21 +46,7 @@ export class StorageChangeHandler { oldValue: CustomShortcut[], ) { if (!newValue || !oldValue) return; - - if (newValue.length > oldValue.length) { - // New shortcut added - add the last one - CreateCustomShortcutDiv(newValue[oldValue.length]); - } else if (newValue.length < oldValue.length) { - // Shortcut removed - find which one was removed - const newSet = new Set(newValue.map(item => JSON.stringify(item))); - const removedElement = oldValue.find( - (oldItem) => !newSet.has(JSON.stringify(oldItem)) - ); - - if (removedElement) { - RemoveShortcutDiv([removedElement]); - } - } + renderShortcuts(); } private handleShortcutsChange( @@ -69,34 +54,7 @@ export class StorageChangeHandler { oldValue: { enabled: boolean; name: string }[], ) { if (!newValue || !oldValue) return; - - // Create map for faster lookup - const oldMap = new Map(oldValue.map(item => [item.name, item.enabled])); - - const addedShortcuts: { enabled: boolean; name: string }[] = []; - const removedShortcuts: { enabled: boolean; name: string }[] = []; - - // Check for changes in shortcuts - for (const newItem of newValue) { - const oldEnabled = oldMap.get(newItem.name); - - // Newly enabled shortcuts - if (newItem.enabled && (oldEnabled === undefined || !oldEnabled)) { - addedShortcuts.push(newItem); - } - - // Newly disabled shortcuts - if (!newItem.enabled && oldEnabled === true) { - removedShortcuts.push(newItem); - } - } - - if (addedShortcuts.length > 0) { - addShortcuts(addedShortcuts); - } - if (removedShortcuts.length > 0) { - RemoveShortcutDiv(removedShortcuts); - } + renderShortcuts(); } private handleTransparencyEffectsChange(newValue: boolean) {