From 32c5c8392be7934089560b7915e29952c4270fad Mon Sep 17 00:00:00 2001 From: Jones8683 Date: Thu, 29 Jan 2026 19:40:28 +1030 Subject: [PATCH 01/21] fix: tutorials show room as N/A even if room is specified on timetable --- src/seqta/utils/Loaders/LoadHomePage.ts | 50 +++++++++++-------------- 1 file changed, 22 insertions(+), 28 deletions(-) diff --git a/src/seqta/utils/Loaders/LoadHomePage.ts b/src/seqta/utils/Loaders/LoadHomePage.ts index 9f4e576c..1392adcd 100644 --- a/src/seqta/utils/Loaders/LoadHomePage.ts +++ b/src/seqta/utils/Loaders/LoadHomePage.ts @@ -43,7 +43,7 @@ export async function loadHomePage() { const homeContainer = document.getElementById("home-root"); if (!homeContainer) return; - const skeletonStructure = stringToHTML(/* html */` + const skeletonStructure = stringToHTML(/* html */ `
@@ -299,7 +299,6 @@ function comparedate(obj1: any, obj2: any) { return 0; } - function processNotices(response: any, labelArray: string[]) { const NoticeContainer = document.getElementById("notice-container"); if (!NoticeContainer) return; @@ -343,14 +342,14 @@ function processNoticeColor(colour: string): string | undefined { } function createNoticeElement(notice: any, colour: string | undefined): Node { - const textPreview = notice.contents - .replace(/<[^>]*>/g, "") - .replace(/\[\[[\w]+[:][\w]+[\]\]]+/g, "") - .replace(/\s+/g, " ") - .trim() - .substring(0, 150) - + (notice.contents.length > 150 ? "..." : ""); - + const textPreview = + notice.contents + .replace(/<[^>]*>/g, "") + .replace(/\[\[[\w]+[:][\w]+[\]\]]+/g, "") + .replace(/\s+/g, " ") + .trim() + .substring(0, 150) + (notice.contents.length > 150 ? "..." : ""); + const noticeId = `notice-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`; const htmlContent = ` @@ -680,8 +679,10 @@ function callHomeTimetable(date: string, change?: any) { GetLessonColours().then((colours) => { let subjects = colours; for (let i = 0; i < lessonArray.length; i++) { - - let subjectname = ((lessonArray[i].type == "tutorial") ? `timetable.tutor.${lessonArray[i].tutorID}` : `timetable.subject.colour.${lessonArray[i].code}`); + let subjectname = + lessonArray[i].type == "tutorial" + ? `timetable.tutor.${lessonArray[i].tutorID}` + : `timetable.subject.colour.${lessonArray[i].code}`; let subject = subjects.find( (element: any) => element.name === subjectname, @@ -869,14 +870,14 @@ function makeLessonDiv(lesson: any, num: number) { programmeID, metaID, assessments, - type + type, } = lesson; let lessonString = `
-

${(type == "class") ? description : (type == "tutorial") ? "Tutorial" : "Unknown"}

+

${type == "class" ? description : type == "tutorial" ? "Tutorial" : "Unknown"}

${staff || "Unknown"}

-

${(type == "class") ? room : (type == "tutorial") ? "N/A" : "Unknown"}

+

${room || "N/A"}

${from || "Unknown"} - ${until || "Unknown"}

${attendanceTitle || "Unknown"}
`; @@ -987,22 +988,16 @@ async function CreateUpcomingSection(assessments: any, activeSubjects: any) { CreateFilters(activeSubjects); - let type; - let class_; - for (let i = 0; i < assessments.length; i++) { const element: any = assessments[i]; if (!upcomingDates[element.due as keyof typeof upcomingDates]) { - let dateObj: any = new Object(); - dateObj.div = CreateElement( - (type = "div"), - (class_ = "upcoming-date-container"), - ); + const dateObj: any = {}; + dateObj.div = CreateElement("div", "upcoming-date-container"); dateObj.assessments = []; (upcomingDates[element.due as keyof typeof upcomingDates] as any) = dateObj; } - let assessmentDateDiv = + const assessmentDateDiv = upcomingDates[element.due as keyof typeof upcomingDates]; if (assessmentDateDiv) { @@ -1012,9 +1007,8 @@ async function CreateUpcomingSection(assessments: any, activeSubjects: any) { for (var date in upcomingDates) { let assessmentdue = new Date( - ( - upcomingDates[date as keyof typeof upcomingDates] as any - ).assessments[0].due, + (upcomingDates[date as keyof typeof upcomingDates] as any).assessments[0] + .due, ); let specialcase = CheckSpecialDay(Today, assessmentdue); let assessmentDate; @@ -1044,7 +1038,7 @@ async function CreateUpcomingSection(assessments: any, activeSubjects: any) { } } FilterUpcomingAssessments(settingsState.subjectfilters); - + if (assessments.length === 0) { upcomingitemcontainer!.innerHTML = `
From d9fe70f4427c750234ccef25bc1cf2c85fddcec9 Mon Sep 17 00:00:00 2001 From: Jones8683 Date: Thu, 29 Jan 2026 20:07:13 +1030 Subject: [PATCH 02/21] fix: remove duplicate css block --- src/css/injected.scss | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/css/injected.scss b/src/css/injected.scss index 19990054..c6fb4c93 100644 --- a/src/css/injected.scss +++ b/src/css/injected.scss @@ -3177,17 +3177,6 @@ div.day-empty { display: flex; align-content: space-between; } -.upcoming-filters { - display: flex; - height: 26px; - width: 65%; - align-self: center; - align-items: center; - color: var(--text-color); - padding: 5px; - overflow-x: scroll; - overflow-y: hidden; -} .upcoming-checkbox-container { position: relative; padding: none !important; From bba96d51594b7b570318306e64c757ee5c232490 Mon Sep 17 00:00:00 2001 From: Jones8683 Date: Thu, 29 Jan 2026 20:21:30 +1030 Subject: [PATCH 03/21] format: remove some duplicate selectors --- src/css/injected.scss | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/src/css/injected.scss b/src/css/injected.scss index c6fb4c93..88acc864 100644 --- a/src/css/injected.scss +++ b/src/css/injected.scss @@ -1407,9 +1407,6 @@ html.transparencyEffects .waitWindow { background: var(--better-main); } -.modaliser { - background: var(--better-main); -} .alert-container { height: 35em; width: 22em; @@ -1862,12 +1859,6 @@ ul { } } -.connectedNotificationsWrapper > div > button { - color: var(--text-primary) !important; - height: 45px; - width: 45px; -} - .programmeNavigator { width: 400px; background: var(--background-primary); @@ -2294,8 +2285,8 @@ div.bar.flat { .cke_toolbox { padding: 0 !important; padding-left: 8px !important; - background: unset !important; gap: 0 8px; + background: var(--better-main); } .cke_toolbar:has(.cke_toolgroup) { .cke_combo { @@ -2443,11 +2434,9 @@ body { .hidden { display: none; } -.cke_toolbox { - background: var(--better-main); -} .modaliser { display: none; + background: var(--better-main); } [class*="MessageList__unread___"] { From 0a33ca7f6e633a121cd0087046315aad77cb6a46 Mon Sep 17 00:00:00 2001 From: Jones8683 Date: Thu, 29 Jan 2026 20:25:22 +1030 Subject: [PATCH 04/21] trigger codefactor for fork From 9820595a707742c23412a0ca8730db6b682f8c6e Mon Sep 17 00:00:00 2001 From: codefactor-io Date: Thu, 29 Jan 2026 09:56:34 +0000 Subject: [PATCH 05/21] [CodeFactor] Apply fixes --- src/plugins/built-in/assessmentsOverview/index.ts | 2 +- src/plugins/built-in/assessmentsOverview/styles.css | 3 +-- src/plugins/built-in/backgroundMusic/index.ts | 2 +- src/plugins/built-in/globalSearch/src/core/index.ts | 2 +- src/plugins/built-in/globalSearch/src/indexing/indexer.ts | 2 +- .../built-in/globalSearch/src/indexing/jobs/forums.ts | 2 +- .../built-in/globalSearch/src/indexing/jobs/messages.ts | 2 +- .../globalSearch/src/indexing/jobs/notifications.ts | 2 +- src/plugins/built-in/profilePicture/index.ts | 2 +- src/plugins/core/manager.ts | 6 +++--- src/plugins/core/settingsHelpers.ts | 6 +++--- 11 files changed, 15 insertions(+), 16 deletions(-) diff --git a/src/plugins/built-in/assessmentsOverview/index.ts b/src/plugins/built-in/assessmentsOverview/index.ts index 24ac48e1..03fe4340 100644 --- a/src/plugins/built-in/assessmentsOverview/index.ts +++ b/src/plugins/built-in/assessmentsOverview/index.ts @@ -1,7 +1,7 @@ import type { Plugin } from "../../core/types"; import { waitForElm } from "@/seqta/utils/waitForElm"; import { getAssessmentsData } from "./api"; -import { renderSkeletonLoader, renderErrorState } from "./ui"; +import { renderErrorState, renderSkeletonLoader } from "./ui"; import styles from "./styles.css?inline"; import { delay } from "@/seqta/utils/delay"; diff --git a/src/plugins/built-in/assessmentsOverview/styles.css b/src/plugins/built-in/assessmentsOverview/styles.css index 2b47624c..a1374145 100644 --- a/src/plugins/built-in/assessmentsOverview/styles.css +++ b/src/plugins/built-in/assessmentsOverview/styles.css @@ -106,7 +106,6 @@ max-height: 100%; background: #f8fafc; border-radius: 12px; - box-shadow: 0 0 0 2px #e2e8f0; display: flex; flex-direction: column; min-height: 0; @@ -340,7 +339,7 @@ font-size: 0.875rem; font-weight: 600; color: #1a1a1a; - margin: 0 0 0.75rem 0; + margin: 0 0 0.75rem; line-height: 1.4; padding-right: 2rem; /* Make room for menu button */ } diff --git a/src/plugins/built-in/backgroundMusic/index.ts b/src/plugins/built-in/backgroundMusic/index.ts index 50712066..7ed2fe3d 100644 --- a/src/plugins/built-in/backgroundMusic/index.ts +++ b/src/plugins/built-in/backgroundMusic/index.ts @@ -1,5 +1,5 @@ import type { Plugin } from "@/plugins/core/types"; -import { componentSetting, defineSettings, numberSetting, booleanSetting } from "@/plugins/core/settingsHelpers"; +import { booleanSetting, componentSetting, defineSettings, numberSetting } from "@/plugins/core/settingsHelpers"; import styles from "./styles.css?inline"; import BackgroundMusicSetting from "./BackgroundMusicSetting.svelte"; import localforage from "localforage"; diff --git a/src/plugins/built-in/globalSearch/src/core/index.ts b/src/plugins/built-in/globalSearch/src/core/index.ts index cf6889ce..f7859808 100644 --- a/src/plugins/built-in/globalSearch/src/core/index.ts +++ b/src/plugins/built-in/globalSearch/src/core/index.ts @@ -4,8 +4,8 @@ import { booleanSetting, buttonSetting, defineSettings, - Setting, hotkeySetting, + Setting, } from "@/plugins/core/settingsHelpers"; import styles from "./styles.css?inline"; import { waitForElm } from "@/seqta/utils/waitForElm"; diff --git a/src/plugins/built-in/globalSearch/src/indexing/indexer.ts b/src/plugins/built-in/globalSearch/src/indexing/indexer.ts index de00fff7..04e09b2a 100644 --- a/src/plugins/built-in/globalSearch/src/indexing/indexer.ts +++ b/src/plugins/built-in/globalSearch/src/indexing/indexer.ts @@ -1,4 +1,4 @@ -import { clear, getAll, get, put, remove } from "./db"; +import { clear, get, getAll, put, remove } from "./db"; import { jobs } from "./jobs"; import { renderComponentMap } from "./renderComponents"; import type { IndexItem, Job, JobContext } from "./types"; diff --git a/src/plugins/built-in/globalSearch/src/indexing/jobs/forums.ts b/src/plugins/built-in/globalSearch/src/indexing/jobs/forums.ts index 24541831..48fa8c53 100644 --- a/src/plugins/built-in/globalSearch/src/indexing/jobs/forums.ts +++ b/src/plugins/built-in/globalSearch/src/indexing/jobs/forums.ts @@ -1,4 +1,4 @@ -import type { Job, IndexItem } from "../types"; +import type { IndexItem, Job } from "../types"; const fetchForums = async () => { const res = await fetch(`${location.origin}/seqta/student/load/forums`, { diff --git a/src/plugins/built-in/globalSearch/src/indexing/jobs/messages.ts b/src/plugins/built-in/globalSearch/src/indexing/jobs/messages.ts index f3faf700..c0072d98 100644 --- a/src/plugins/built-in/globalSearch/src/indexing/jobs/messages.ts +++ b/src/plugins/built-in/globalSearch/src/indexing/jobs/messages.ts @@ -1,4 +1,4 @@ -import type { Job, IndexItem } from "../types"; +import type { IndexItem, Job } from "../types"; import { htmlToPlainText } from "../utils"; import { delay } from "@/seqta/utils/delay"; import { VectorWorkerManager } from "../worker/vectorWorkerManager"; diff --git a/src/plugins/built-in/globalSearch/src/indexing/jobs/notifications.ts b/src/plugins/built-in/globalSearch/src/indexing/jobs/notifications.ts index ecae38f8..26f46180 100644 --- a/src/plugins/built-in/globalSearch/src/indexing/jobs/notifications.ts +++ b/src/plugins/built-in/globalSearch/src/indexing/jobs/notifications.ts @@ -1,4 +1,4 @@ -import type { Job, IndexItem } from "../types"; +import type { IndexItem, Job } from "../types"; import { htmlToPlainText } from "../utils"; import { fetchMessageContent } from "./messages"; import { delay } from "@/seqta/utils/delay"; diff --git a/src/plugins/built-in/profilePicture/index.ts b/src/plugins/built-in/profilePicture/index.ts index 89f42cac..666065a4 100644 --- a/src/plugins/built-in/profilePicture/index.ts +++ b/src/plugins/built-in/profilePicture/index.ts @@ -1,5 +1,5 @@ import type { Plugin } from "@/plugins/core/types"; -import { defineSettings, componentSetting } from "@/plugins/core/settingsHelpers"; +import { componentSetting, defineSettings } from "@/plugins/core/settingsHelpers"; import ProfilePictureSetting from "./ProfilePictureSetting.svelte"; import { waitForElm } from "@/seqta/utils/waitForElm"; import styles from "./styles.css?inline"; diff --git a/src/plugins/core/manager.ts b/src/plugins/core/manager.ts index b98cfd73..78a4d0dc 100644 --- a/src/plugins/core/manager.ts +++ b/src/plugins/core/manager.ts @@ -1,13 +1,13 @@ import type { BooleanSetting, + ButtonSetting, + ComponentSetting, + HotkeySetting, NumberSetting, Plugin, PluginSettings, SelectSetting, StringSetting, - ButtonSetting, - HotkeySetting, - ComponentSetting, } from "./types"; import { createPluginAPI } from "./createAPI"; import browser from "webextension-polyfill"; diff --git a/src/plugins/core/settingsHelpers.ts b/src/plugins/core/settingsHelpers.ts index 40651138..6b1949b1 100644 --- a/src/plugins/core/settingsHelpers.ts +++ b/src/plugins/core/settingsHelpers.ts @@ -1,12 +1,12 @@ import type { BooleanSetting, ButtonSetting, + ComponentSetting, + HotkeySetting, NumberSetting, + PluginSettings, SelectSetting, StringSetting, - HotkeySetting, - PluginSettings, - ComponentSetting, } from "./types"; /** From eed8bac45ad7dec8deb655b3adb8a810196317bd Mon Sep 17 00:00:00 2001 From: Jones8683 Date: Thu, 29 Jan 2026 20:53:12 +1030 Subject: [PATCH 06/21] fix: clean up more duplicate selectors --- src/css/injected.scss | 58 ++++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 31 deletions(-) diff --git a/src/css/injected.scss b/src/css/injected.scss index 88acc864..c0583b6d 100644 --- a/src/css/injected.scss +++ b/src/css/injected.scss @@ -434,6 +434,11 @@ ul.magicDelete > li.deleting { [class*="notifications__items___"] { -ms-overflow-style: none !important; scrollbar-width: none !important; + border-bottom: none; + height: 540px; + display: flex; + flex-direction: column; + &::-webkit-scrollbar { display: none !important; } @@ -728,13 +733,7 @@ td.colourBar { #container #content .uiButton { border-radius: 16px; } -.dark { - #toolbar button.toggled, - #toolbar button.depressed { - background: #333333; - color: white; - } -} + #toolbar button.toggled, #toolbar button.depressed { background: #f3f3f3; @@ -1510,12 +1509,6 @@ html.transparencyEffects border: 1px solid white; } } -[class*="notifications__items___"] { - border-bottom: none; - height: 540px; - display: flex; - flex-direction: column; -} [class*="notifications__details___"] { max-width: 80%; overflow: clip; @@ -1708,6 +1701,9 @@ iframe.userHTML { box-shadow: 0 0 40px 0px rgba(0, 0, 0, 0.05); overflow-y: scroll; height: 100%; + width: 400px; + background: var(--background-primary); + position: relative; .navigator { padding: 6px !important; @@ -1849,21 +1845,6 @@ ul { scrollbar-color: #babac0 #fff !important; } -.dark { - body, - div, - ol, - ul { - scrollbar-width: thin; - scrollbar-color: #333 #111 !important; - } -} - -.programmeNavigator { - width: 400px; - background: var(--background-primary); - position: relative; -} #userActions > .details > .code { text-transform: initial; } @@ -2002,14 +1983,13 @@ div:has(> [class*="AssessmentDetails__AssessmentDetails___"]) { } div.entry.class { border-radius: 4px; -} - -div.entry.class { width: 100% !important; } + div.entry.class[style*="left: 46.5%"] { left: 50% !important; } + div.entry.class[style*="width: 46.5%"] { width: 50% !important; } @@ -2091,6 +2071,22 @@ a.uiFile:not(.rows) { } } +.dark { + body, + div, + ol, + ul { + scrollbar-width: thin; + scrollbar-color: #333 #111 !important; + } + + #toolbar button.toggled, + #toolbar button.depressed { + background: #333333; + color: white; + } +} + .dark .title a.uiFile { color: #06b4fc !important; } From 8b6bda6dff24e629aa0fb45272a969be083679b7 Mon Sep 17 00:00:00 2001 From: Jones8683 Date: Fri, 30 Jan 2026 08:37:38 +1030 Subject: [PATCH 07/21] more cleanup --- src/css/injected.scss | 80 ++++++------------------------------------- 1 file changed, 10 insertions(+), 70 deletions(-) diff --git a/src/css/injected.scss b/src/css/injected.scss index c0583b6d..de4ad1ed 100644 --- a/src/css/injected.scss +++ b/src/css/injected.scss @@ -39,7 +39,6 @@ html { font-family: Rubik, sans-serif !important; } -/* Ensure native select dropdowns are readable on Windows */ select option { background-color: #ffffff !important; color: #111827 !important; @@ -49,7 +48,6 @@ select option { color: #ffffff !important; } -/* Consistent rounded corners for selects */ select { border-radius: 8px !important; } @@ -158,8 +156,7 @@ select { #main { color: var(--text-primary); position: relative; -} -#main { + > .timetablepage { > .quickbar { .gutter { @@ -276,10 +273,8 @@ select { grid-template-columns: repeat(autofit, minmax(200px, 400px)) !important; background: unset; - // TODO: Make this only opacity 0 when the animation will be played to stop a flash of the original > section { border-radius: 16px !important; - //opacity: 0; button { border-radius: 16px; @@ -319,7 +314,6 @@ select { > .dashlet { background: var(--background-primary); border-radius: 16px; - //opacity: 0; &[data-ident="timetable"] { grid-row: span 2 / auto !important; @@ -339,9 +333,6 @@ select { .dashlet-summary-homework > .summary > .subject > .item { color: var(--text-primary) !important; } -.dashlet-summary-homework > .summary > .subject > .item { - color: var(--text-primary) !important; -} .dashlet-notes > ul { background: var(--background-primary); } @@ -406,7 +397,6 @@ ul.magicDelete > li.deleting { white-space: nowrap; } -/* Allow long course/assessment names in the sidebar to wrap and break safely */ #menu li > label, #menu section > label { white-space: normal; @@ -500,7 +490,6 @@ ul.magicDelete > li.deleting { html { background: var(--better-main) !important; } -/* Messages */ .menuShown .content .anyoneSelect .listWrapper .list:has(.item) { width: 100% !important; } @@ -519,7 +508,6 @@ ol:has([class*="MessageList__avatar___"] svg) { transition-duration: 150ms !important; transition-delay: 0ms !important; } -/* Direct Message Menu */ .wrapper .cke_contents iframe { box-sizing: border-box; -moz-box-sizing: border-box; @@ -528,7 +516,6 @@ ol:has([class*="MessageList__avatar___"] svg) { } .wrapper .cke_contents::-webkit-scrollbar-thumb { background-color: #969696 !important; - /* color of the scroll thumb */ } .content .footer { margin-top: 5px; @@ -1364,7 +1351,6 @@ html.transparencyEffects font-size: 20px !important; font-weight: 500; min-height: 46px; - /* Let the title expand naturally but clamp to 2 lines to avoid overlap */ height: auto; line-height: 1.2; display: -webkit-box; @@ -1438,8 +1424,6 @@ html.transparencyEffects background: white; z-index: 21 !important; color: var(--better-sub); -} -[class*="notifications__notifications___"] > button { padding: 8px; } .legacy-root button > svg, @@ -1540,7 +1524,6 @@ html.transparencyEffects display: none !important; } [class*="MessageList__MessageList___"] ol [class*="Button__Button___"]::before { - // plus icon content: ""; font-size: 12px; margin-right: 4px; @@ -1831,7 +1814,6 @@ iframe.userHTML { color: var(--text-primary); } -/* set button(top and bottom of the scrollbar) */ body::-webkit-scrollbar-button { display: none !important; } @@ -1845,9 +1827,6 @@ ul { scrollbar-color: #babac0 #fff !important; } -#userActions > .details > .code { - text-transform: initial; -} div:has(> [class*="AssessmentDetails__AssessmentDetails___"]) { padding: 4px; } @@ -2355,7 +2334,6 @@ ul.buttonChecklist, ul.buttonMenu, ul.colourButtonOptions, ul.uiSplitButtonList, -ul.buttonMenu, .contactFormPanel { background: var(--background-primary) !important; border: solid 4px var(--background-primary); @@ -2427,9 +2405,6 @@ body { .days { width: 100%; } -.hidden { - display: none; -} .modaliser { display: none; background: var(--better-main); @@ -2775,6 +2750,7 @@ body { bottom: 20px; } #userActions > .details > .code { + text-transform: initial; overflow: visible !important; } .code { @@ -2896,8 +2872,6 @@ div.day-empty { height: 6em; padding: 0px; border-radius: 10px; -} -.upcoming-assessment { display: flex; } .upcoming-date-container { @@ -2966,7 +2940,6 @@ div.day-empty { align-items: center; display: flex; } -/* Hide the browser's default checkbox */ .upcoming-checkbox-container input { position: absolute; opacity: 0; @@ -2975,7 +2948,6 @@ div.day-empty { width: 0; padding: 0; } -/* Create a custom checkbox */ .upcoming-checkmark { position: absolute; top: 0; @@ -3001,11 +2973,9 @@ div.day-empty { display: none; } -/* Show the checkmark when checked */ .upcoming-checkbox-container input:checked ~ .upcoming-checkmark:after { display: block; } -/* Style the checkmark/indicator */ .upcoming-checkbox-container .upcoming-checkmark:after { left: 3.5px; top: 0px; @@ -3077,9 +3047,6 @@ div.day-empty { inset 0px 6px 0 var(--item-colour, transparent), inset 0px 40px 50px -40px rgba(0, 0, 0, 0.9); } -.clickable { - cursor: pointer; -} .day:hover { background: var(--background-secondary); transition: 200ms; @@ -3177,7 +3144,6 @@ div.day-empty { align-items: center; display: flex; } -/* Hide the browser's default checkbox */ .upcoming-checkbox-container input { position: absolute; opacity: 0; @@ -3186,7 +3152,6 @@ div.day-empty { width: 0; padding: 0; } -/* Create a custom checkbox */ .upcoming-checkmark { position: absolute; top: 0; @@ -3197,25 +3162,20 @@ div.day-empty { border-radius: 5px; color: var(--text-color); } -/* On mouse-over, add a grey background color */ .upcoming-checkbox-container:hover input ~ .upcoming-checkmark { filter: brightness(0.8); } -/* When the checkbox is checked, add a blue background */ .upcoming-checkbox-container input:checked ~ .upcoming-checkmark { background: var(--item-colour); } -/* Create the checkmark/indicator (hidden when not checked) */ .upcoming-checkmark:after { content: ""; position: absolute; display: none; } -/* Show the checkmark when checked */ .upcoming-checkbox-container input:checked ~ .upcoming-checkmark:after { display: block; } -/* Style the checkmark/indicator */ .upcoming-checkbox-container .upcoming-checkmark:after { left: 3.5px; top: 0px; @@ -3523,7 +3483,6 @@ div.day-empty { overflow: visible; } -// Auto collapsing alignment toolbar .cke_toolbar:has(.cke_button__seqta-align-left) { overflow: visible !important; @@ -3564,13 +3523,11 @@ div.day-empty { } } - // Button icons .cke_button_icon { margin: 0 !important; } } - // menu background &:before { content: ""; position: absolute; @@ -3588,7 +3545,6 @@ div.day-empty { transition: all 0.2s ease-out; } - // Dropdown behavior on hover &:hover { &:hover:before { transform: scale(1); @@ -3599,7 +3555,6 @@ div.day-empty { visibility: visible; transition-delay: 0s; - // Stack buttons in dropdown with spacing &:first-child { transform: translateY(0); border-top-left-radius: 12px !important; @@ -3627,7 +3582,6 @@ div.day-empty { } } - // Add subtle animation when closing dropdown &:not(:hover) .cke_button:not(.cke_button_on):not( .cke_button__seqta-align-left:first-child @@ -3659,7 +3613,6 @@ div.day-empty { border: none !important; } -// Notice card hover effects for main page cards .notice-unified-content.notice-card-state:not([data-transitioning]) { cursor: pointer; @@ -3700,7 +3653,6 @@ div.day-empty { text-overflow: ellipsis; } -// Modal styles .notice-modal-overlay { position: fixed; top: 0; @@ -3719,7 +3671,7 @@ div.day-empty { .notice-modal-transition { position: fixed; z-index: 10001; - transition: none; // Controlled by motion animations + transition: none; } .notice-modal-content { @@ -3753,13 +3705,7 @@ div.day-empty { padding: 16px; border: 1px solid rgba(255, 255, 255, 0.1); box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); -} -.dark .notice-unified-content { - color: white; -} - -.notice-unified-content { h1, h2, h3, @@ -3783,7 +3729,7 @@ div.day-empty { } .notice-content-title { - font-size: 20px !important; // Nice middle ground - not too big, not too small + font-size: 20px !important; font-weight: 600 !important; color: var(--text-primary) !important; margin: 0 0 12px !important; @@ -3798,17 +3744,14 @@ div.day-empty { margin: 0 !important; flex: 1; display: block; - // Force stable layout dimensions - content renders at full size always - min-width: 600px; // Ensure tables have consistent width for layout + min-width: 600px; width: 100%; } - // The ONLY difference between states is clipping! &.notice-card-state { .notice-content-body { - // Clip to show only 2 lines but keep full layout overflow: hidden; - max-height: 3em; // ~2 lines worth of height + max-height: 3em; } } @@ -3818,10 +3761,8 @@ div.day-empty { } .notice-content-body { - // Show full content with scrolling overflow-y: auto; - // Custom scrollbar for long content &::-webkit-scrollbar { width: 6px; } @@ -3839,7 +3780,6 @@ div.day-empty { background: rgba(255, 255, 255, 0.3); } - // Style content elements nicely p { margin-bottom: 12px; @@ -3870,6 +3810,10 @@ div.day-empty { } } +.dark .notice-unified-content { + color: white; +} + .notice-header { display: flex; justify-content: space-between; @@ -3968,7 +3912,6 @@ button.notice-close-btn { flex: 1; overflow-y: auto; - // Custom scrollbar &::-webkit-scrollbar { width: 6px; } @@ -3986,7 +3929,6 @@ button.notice-close-btn { background: rgba(255, 255, 255, 0.3); } - // Style content elements p { margin-bottom: 12px; @@ -4015,7 +3957,6 @@ button.notice-close-btn { } } -// Dark mode adjustments .dark { .notice-card { border-color: rgba(255, 255, 255, 0.05); @@ -4030,7 +3971,6 @@ button.notice-close-btn { } } -// Mobile responsiveness @media (max-width: 768px) { .notice-modal-overlay { padding: 10px; From b40222147713949ebaf313931c63b58b50b0cf97 Mon Sep 17 00:00:00 2001 From: Jones8683 Date: Fri, 30 Jan 2026 14:58:24 +1030 Subject: [PATCH 08/21] fix build --- src/css/iframe.scss | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/src/css/iframe.scss b/src/css/iframe.scss index 5fafec68..4eb65908 100644 --- a/src/css/iframe.scss +++ b/src/css/iframe.scss @@ -1,20 +1,3 @@ -/* - * This file is part of EvenBetterSEQTA. - * - * EvenBetterSEQTA is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * EvenBetterSEQTA is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with EvenBetterSEQTA. If not, see . - */ - body { background: transparent; } @@ -116,8 +99,7 @@ body { } .cke_panel_listItem > a { - &:hover { background: #3d3d3e !important; } -} \ No newline at end of file +} From 9da8e104a886f2746db402bb3f1a6c8f13241c86 Mon Sep 17 00:00:00 2001 From: Jones Jankovic Date: Fri, 30 Jan 2026 16:37:52 +1030 Subject: [PATCH 09/21] Update src/seqta/utils/Loaders/LoadHomePage.ts Co-authored-by: Aden Lindsay <140392385+AdenMGB@users.noreply.github.com> --- src/seqta/utils/Loaders/LoadHomePage.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/seqta/utils/Loaders/LoadHomePage.ts b/src/seqta/utils/Loaders/LoadHomePage.ts index 1392adcd..8500bb2a 100644 --- a/src/seqta/utils/Loaders/LoadHomePage.ts +++ b/src/seqta/utils/Loaders/LoadHomePage.ts @@ -43,7 +43,7 @@ export async function loadHomePage() { const homeContainer = document.getElementById("home-root"); if (!homeContainer) return; - const skeletonStructure = stringToHTML(/* html */ ` + const skeletonStructure = stringToHTML(/* html */`
From 401947031b6cc2dfa7f96b090769d175d15af1f7 Mon Sep 17 00:00:00 2001 From: Jones Jankovic Date: Fri, 30 Jan 2026 16:41:39 +1030 Subject: [PATCH 10/21] Add back GPL license header to iframe.scss --- src/css/iframe.scss | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/css/iframe.scss b/src/css/iframe.scss index 4eb65908..f070b817 100644 --- a/src/css/iframe.scss +++ b/src/css/iframe.scss @@ -1,3 +1,20 @@ +/* + * This file is part of EvenBetterSEQTA. + * + * EvenBetterSEQTA is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * EvenBetterSEQTA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with EvenBetterSEQTA. If not, see . + */ + body { background: transparent; } From e0009ad8dccb4dad56a8d05414240f547ea0fbdb Mon Sep 17 00:00:00 2001 From: Jones8683 Date: Fri, 30 Jan 2026 19:16:01 +1030 Subject: [PATCH 11/21] resolve codefactor warnings about animation shorthand --- src/css/injected.scss | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/css/injected.scss b/src/css/injected.scss index de4ad1ed..2a89f9a9 100644 --- a/src/css/injected.scss +++ b/src/css/injected.scss @@ -1645,7 +1645,7 @@ iframe.userHTML { } [class*="Thermoscore__Thermoscore___"] { background-image: unset; - background: var(--auto-background); + background-color: var(--auto-background); border-radius: 8px; } .dark [class*="Thermoscore__Thermoscore___"] { @@ -2666,16 +2666,16 @@ body { } .big-circle { margin: -88px; - animation-timing-function: ease; - animation: spin 3s linear infinite; - -moz-animation: spin 3s linear infinite; + animation: spin 3s ease infinite; + -moz-animation: spin 3s ease infinite; } + .small-circle { margin: -66px; - animation-timing-function: ease; - animation: spin 3s linear infinite; - -moz-animation: spin 3s linear infinite; + animation: spin 3s ease infinite; + -moz-animation: spin 3s ease infinite; } + .dark [class*="LabelList__name___"] { text-shadow: 0 0 5px black; } @@ -2717,10 +2717,10 @@ body { } .outer-circle { margin: -108px; - animation-direction: alternate-reverse; - animation: spinback 1s linear infinite; - -moz-animation: spinback 1s linear infinite; + animation: spinback 1s linear infinite alternate-reverse; + -moz-animation: spinback 1s linear infinite alternate-reverse; } + @-moz-keyframes spin { 100% { -moz-transform: rotate(360deg); @@ -3710,7 +3710,7 @@ div.day-empty { h2, h3, h4, - h5, + z h5, h6 { margin: 0 !important; padding: 0 !important; From 1d215d8c75b322be29f1746ac0b6a2d837cab720 Mon Sep 17 00:00:00 2001 From: Jones8683 Date: Fri, 30 Jan 2026 19:17:50 +1030 Subject: [PATCH 12/21] Revert "Add back GPL license header to iframe.scss" This reverts commit 401947031b6cc2dfa7f96b090769d175d15af1f7. --- src/css/iframe.scss | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/src/css/iframe.scss b/src/css/iframe.scss index f070b817..4eb65908 100644 --- a/src/css/iframe.scss +++ b/src/css/iframe.scss @@ -1,20 +1,3 @@ -/* - * This file is part of EvenBetterSEQTA. - * - * EvenBetterSEQTA is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * EvenBetterSEQTA is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with EvenBetterSEQTA. If not, see . - */ - body { background: transparent; } From 3746b05af2beb997b07634f496e844c683094394 Mon Sep 17 00:00:00 2001 From: Jones8683 Date: Fri, 30 Jan 2026 19:19:07 +1030 Subject: [PATCH 13/21] Reapply "Add back GPL license header to iframe.scss" This reverts commit 1d215d8c75b322be29f1746ac0b6a2d837cab720. --- src/css/iframe.scss | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/css/iframe.scss b/src/css/iframe.scss index 4eb65908..f070b817 100644 --- a/src/css/iframe.scss +++ b/src/css/iframe.scss @@ -1,3 +1,20 @@ +/* + * This file is part of EvenBetterSEQTA. + * + * EvenBetterSEQTA is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * EvenBetterSEQTA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with EvenBetterSEQTA. If not, see . + */ + body { background: transparent; } From 14a2e93b3a70fa5a5ee61c1351ac0a58c7af8fdc Mon Sep 17 00:00:00 2001 From: Jones8683 Date: Fri, 30 Jan 2026 19:25:47 +1030 Subject: [PATCH 14/21] styff --- src/css/injected.scss | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/css/injected.scss b/src/css/injected.scss index 2a89f9a9..f15675c8 100644 --- a/src/css/injected.scss +++ b/src/css/injected.scss @@ -3187,9 +3187,6 @@ div.day-empty { -ms-transform: rotate(45deg); transform: rotate(45deg); } -.upcoming-hiddenassessment { - color: #797979; -} .titlebar { align-items: center; transition: 200ms; From 445aa9d071ff62dbcba864d830440e099a5eb579 Mon Sep 17 00:00:00 2001 From: Jones8683 Date: Fri, 30 Jan 2026 19:26:38 +1030 Subject: [PATCH 15/21] Revert "resolve codefactor warnings about animation shorthand" This reverts commit e0009ad8dccb4dad56a8d05414240f547ea0fbdb. --- src/css/injected.scss | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/css/injected.scss b/src/css/injected.scss index f15675c8..00980f50 100644 --- a/src/css/injected.scss +++ b/src/css/injected.scss @@ -1645,7 +1645,7 @@ iframe.userHTML { } [class*="Thermoscore__Thermoscore___"] { background-image: unset; - background-color: var(--auto-background); + background: var(--auto-background); border-radius: 8px; } .dark [class*="Thermoscore__Thermoscore___"] { @@ -2666,16 +2666,16 @@ body { } .big-circle { margin: -88px; - animation: spin 3s ease infinite; - -moz-animation: spin 3s ease infinite; + animation-timing-function: ease; + animation: spin 3s linear infinite; + -moz-animation: spin 3s linear infinite; } - .small-circle { margin: -66px; - animation: spin 3s ease infinite; - -moz-animation: spin 3s ease infinite; + animation-timing-function: ease; + animation: spin 3s linear infinite; + -moz-animation: spin 3s linear infinite; } - .dark [class*="LabelList__name___"] { text-shadow: 0 0 5px black; } @@ -2717,10 +2717,10 @@ body { } .outer-circle { margin: -108px; - animation: spinback 1s linear infinite alternate-reverse; - -moz-animation: spinback 1s linear infinite alternate-reverse; + animation-direction: alternate-reverse; + animation: spinback 1s linear infinite; + -moz-animation: spinback 1s linear infinite; } - @-moz-keyframes spin { 100% { -moz-transform: rotate(360deg); @@ -3707,7 +3707,7 @@ div.day-empty { h2, h3, h4, - z h5, + h5, h6 { margin: 0 !important; padding: 0 !important; From c9443bad278d7b6ac122cc27fd48bb70fd007062 Mon Sep 17 00:00:00 2001 From: Jones8683 Date: Fri, 30 Jan 2026 19:29:14 +1030 Subject: [PATCH 16/21] git please work --- src/css/injected.scss | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/src/css/injected.scss b/src/css/injected.scss index 00980f50..8689dd20 100644 --- a/src/css/injected.scss +++ b/src/css/injected.scss @@ -3129,21 +3129,6 @@ div.day-empty { display: flex; align-content: space-between; } -.upcoming-checkbox-container { - position: relative; - padding: none !important; - padding-left: 25px !important; - padding-right: 10px !important; - cursor: pointer; - font-size: 12px; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - height: 20px; - align-items: center; - display: flex; -} .upcoming-checkbox-container input { position: absolute; opacity: 0; From 011c1eddb4d0e15c2480d8ad67e123824f791bdb Mon Sep 17 00:00:00 2001 From: Jones8683 Date: Fri, 30 Jan 2026 19:45:44 +1030 Subject: [PATCH 17/21] remove more duplicates and slight css touch ups --- src/css/injected.scss | 53 ++----------------------------------------- 1 file changed, 2 insertions(+), 51 deletions(-) diff --git a/src/css/injected.scss b/src/css/injected.scss index 8689dd20..fa1a619a 100644 --- a/src/css/injected.scss +++ b/src/css/injected.scss @@ -2940,56 +2940,11 @@ div.day-empty { align-items: center; display: flex; } -.upcoming-checkbox-container input { - position: absolute; - opacity: 0; - cursor: pointer; - height: 0; - width: 0; - padding: 0; -} -.upcoming-checkmark { - position: absolute; - top: 0; - left: 0; - height: 15px; - width: 15px; - border: 3px solid var(--item-colour); - border-radius: 5px; - color: var(--text-color); -} -.upcoming-checkbox-container:hover input ~ .upcoming-checkmark { - filter: brightness(0.8); -} - -.upcoming-checkbox-container input:checked ~ .upcoming-checkmark { - background: var(--item-colour); -} - -.upcoming-checkmark:after { - content: ""; - position: absolute; - display: none; -} - -.upcoming-checkbox-container input:checked ~ .upcoming-checkmark:after { - display: block; -} -.upcoming-checkbox-container .upcoming-checkmark:after { - left: 3.5px; - top: 0px; - width: 5px; - height: 10px; - border: solid white; - border-width: 0 3px 3px 0; - -webkit-transform: rotate(45deg); - -ms-transform: rotate(45deg); - transform: rotate(45deg); -} .upcoming-hiddenassessment { color: #797979; } + .calendarEventEditor > .tabset > .item { border-radius: 0 !important; } @@ -3587,10 +3542,6 @@ div.day-empty { scrollbar-width: none !important; } -.notice-modal-content { - border: none !important; -} - .notice-unified-content.notice-modal-state { border: none !important; } @@ -3743,7 +3694,7 @@ div.day-empty { } .notice-content-body { - overflow-y: auto; + overflow-y: hidden; &::-webkit-scrollbar { width: 6px; From de75468f2be7997e7887ae8c61808dc3a054de04 Mon Sep 17 00:00:00 2001 From: Jones8683 Date: Fri, 30 Jan 2026 20:00:30 +1030 Subject: [PATCH 18/21] most of the rest of the dups --- src/css/injected.scss | 59 +++++++------------------------------------ 1 file changed, 9 insertions(+), 50 deletions(-) diff --git a/src/css/injected.scss b/src/css/injected.scss index fa1a619a..212191b2 100644 --- a/src/css/injected.scss +++ b/src/css/injected.scss @@ -955,6 +955,14 @@ html.transparencyEffects color: white !important; } .notices-container { + width: 100%; + max-height: 60em; + background: var(--better-main); + display: flex; + flex-direction: column; + -webkit-box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px; + box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px; + input { border: none; color: var(--text-color) !important; @@ -970,6 +978,7 @@ html.transparencyEffects } } } + #main > .notices > .notice > .label, #main > .notices > .notice > .staff, #main > .notices > .notice > h2 { @@ -1182,15 +1191,6 @@ html.transparencyEffects } } } -.notices-container { - width: 100%; - max-height: 60em; - background: var(--better-main); - display: flex; - flex-direction: column; - -webkit-box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px; - box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px; -} .notice-container { background: var(--better-main); width: 100%; @@ -1339,10 +1339,6 @@ html.transparencyEffects .clickable { cursor: pointer; } -.day:hover { - background: var(--background); - transition: 200ms; -} .day h2 { margin: 0; @@ -1444,10 +1440,6 @@ html.transparencyEffects .legacy-root button::after { background: black !important; } - -.legacy-root button::after { - background: var(--better-main); -} .legacy-root button:not([disabled]):focus { border-color: var(--better-sub); } @@ -2862,10 +2854,6 @@ div.day-empty { border-radius: 5px 0px 0px 5px; background: var(--item-colour); } -.upcoming-assessment-title { - color: var(--text-primary); - font-size: 10px; -} .upcoming-assessment { border: 2px solid var(--item-colour); margin: 5px 50px; @@ -2874,25 +2862,14 @@ div.day-empty { border-radius: 10px; display: flex; } -.upcoming-date-container { - margin-bottom: 20px; -} .upcoming-date-title { padding: 12px; font-size: 20px; } -.upcoming-details h5 { - text-transform: uppercase; - color: #aaaaaa; - padding: 0px 4px; -} .upcoming-details p:hover { cursor: pointer; text-decoration: underline; } -.upcoming-special-day { - font-size: 20px; -} .upcoming-blank { display: flex; border-bottom: 2px solid #bebebe; @@ -2900,17 +2877,9 @@ div.day-empty { height: 2em; padding: 0px; } -.upcoming-blank p { - padding: 0; - margin: 0; -} .upcoming-tick { align-self: center; } -.upcoming-title { - display: flex; - align-content: space-between; -} .upcoming-title h2 { width: 100%; } @@ -3032,16 +3001,6 @@ div.day-empty { font-size: 10px; margin: 0; } -.upcoming-assessment { - border: 3px solid var(--item-colour); - margin: 5px 50px; - height: 6em; - padding: 0px; - border-radius: 10px; -} -.upcoming-assessment { - display: flex; -} .upcoming-date-container { margin-bottom: 20px; } From ce6a5cfdc4dd517d17c1fafcc65ca9ba55e348c1 Mon Sep 17 00:00:00 2001 From: Jones8683 Date: Fri, 30 Jan 2026 20:11:09 +1030 Subject: [PATCH 19/21] fix: background shorthand warning --- src/css/injected.scss | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/css/injected.scss b/src/css/injected.scss index 212191b2..47995861 100644 --- a/src/css/injected.scss +++ b/src/css/injected.scss @@ -2658,16 +2658,16 @@ body { } .big-circle { margin: -88px; - animation-timing-function: ease; - animation: spin 3s linear infinite; - -moz-animation: spin 3s linear infinite; + animation: spin 3s ease infinite; + -moz-animation: spin 3s ease infinite; } + .small-circle { margin: -66px; - animation-timing-function: ease; - animation: spin 3s linear infinite; - -moz-animation: spin 3s linear infinite; + animation: spin 3s ease infinite; + -moz-animation: spin 3s ease infinite; } + .dark [class*="LabelList__name___"] { text-shadow: 0 0 5px black; } @@ -2709,9 +2709,8 @@ body { } .outer-circle { margin: -108px; - animation-direction: alternate-reverse; - animation: spinback 1s linear infinite; - -moz-animation: spinback 1s linear infinite; + animation: spinback 1s linear infinite alternate-reverse; + -moz-animation: spinback 1s linear infinite alternate-reverse; } @-moz-keyframes spin { 100% { From a381de7c9b1c69ab0e3c9220827bbbd83b7c6b32 Mon Sep 17 00:00:00 2001 From: Jones8683 Date: Fri, 30 Jan 2026 20:27:59 +1030 Subject: [PATCH 20/21] final shorthand fix --- src/css/injected.scss | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/css/injected.scss b/src/css/injected.scss index 47995861..f0c00395 100644 --- a/src/css/injected.scss +++ b/src/css/injected.scss @@ -1637,8 +1637,7 @@ iframe.userHTML { } [class*="Thermoscore__Thermoscore___"] { background-image: unset; - background: var(--auto-background); - border-radius: 8px; + background-color: var(--auto-background); } .dark [class*="Thermoscore__Thermoscore___"] { border: 2px solid rgba(255, 255, 255, 0.3); From b9c3c2b5c53e96d9761a51503bf18f3769bd6967 Mon Sep 17 00:00:00 2001 From: Jones8683 Date: Sun, 1 Feb 2026 09:51:11 +1030 Subject: [PATCH 21/21] Reset LoadHomePage.ts to upstream version --- src/seqta/utils/Loaders/LoadHomePage.ts | 483 ++++++++++-------------- 1 file changed, 190 insertions(+), 293 deletions(-) diff --git a/src/seqta/utils/Loaders/LoadHomePage.ts b/src/seqta/utils/Loaders/LoadHomePage.ts index 8500bb2a..967caeb2 100644 --- a/src/seqta/utils/Loaders/LoadHomePage.ts +++ b/src/seqta/utils/Loaders/LoadHomePage.ts @@ -30,20 +30,17 @@ export async function loadHomePage() { element?.classList.add("active"); const main = document.getElementById("main"); - if (!main) { - console.error("[BetterSEQTA+] Main element not found."); - return; - } - - const homeRoot = stringToHTML(`
`); + if (!main) return; main.innerHTML = ""; - main.appendChild(homeRoot?.firstChild!); + main.appendChild( + stringToHTML(`
`).firstChild!, + ); const homeContainer = document.getElementById("home-root"); if (!homeContainer) return; - const skeletonStructure = stringToHTML(/* html */` + const skeletonStructure = stringToHTML(/* html */ `
@@ -101,25 +98,16 @@ export async function loadHomePage() { renderShortcuts(); - const date = new Date(); - const TodayFormatted = formatDate(date); + const TodayFormatted = formatDate(new Date()); - const [assessmentsPromise, classesPromise, prefsPromise] = [ + const [assessments, classes, prefs] = await Promise.all([ GetUpcomingAssessments(), - GetActiveClasses(), - fetch(`${location.origin}/seqta/student/load/prefs?`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ asArray: true, request: "userPrefs" }), }).then((res) => res.json()), - ]; - - const [assessments, classes, prefs] = await Promise.all([ - assessmentsPromise, - classesPromise, - prefsPromise, ]); callHomeTimetable(TodayFormatted, true); @@ -159,20 +147,20 @@ export async function loadHomePage() { } async function GetUpcomingAssessments() { - let func = fetch( - `${location.origin}/seqta/student/assessment/list/upcoming?`, - { + try { + return fetch(`${location.origin}/seqta/student/assessment/list/upcoming?`, { method: "POST", headers: { "Content-Type": "application/json; charset=utf-8", }, body: JSON.stringify({ student: 69 }), - }, - ); - - return func - .then((result) => result.json()) - .then((response) => response.payload); + }) + .then((result) => result.json()) + .then((response) => response.payload); + } catch (error) { + console.error("[BetterSEQTA+] Failed to get upcoming assessments:", error); + return []; + } } function setupTimetableListeners() { @@ -230,15 +218,10 @@ async function GetActiveClasses() { body: JSON.stringify({}), }, ); - - if (!response.ok) { - throw new Error(`HTTP error! Status: ${response.status}`); - } - - const data = await response.json(); - return data.payload; + return (await response.json()).payload; } catch (error) { - console.error("Oops! There was a problem fetching active classes:", error); + console.error("[BetterSEQTA+] Failed to get active classes:", error); + return []; } } @@ -248,28 +231,25 @@ function setupNotices(labelArray: string[], date: string) { ) as HTMLInputElement; const fetchNotices = async (date: string) => { - let data; + try { + const data = settingsState.mockNotices + ? getMockNotices() + : await ( + await fetch(`${location.origin}/seqta/student/load/notices?`, { + method: "POST", + headers: { "Content-Type": "application/json; charset=utf-8" }, + body: JSON.stringify({ date }), + }) + ).json(); - if (settingsState.mockNotices) { - data = getMockNotices(); - } else { - const response = await fetch( - `${location.origin}/seqta/student/load/notices?`, - { - method: "POST", - headers: { "Content-Type": "application/json; charset=utf-8" }, - body: JSON.stringify({ date }), - }, - ); - data = await response.json(); + processNotices(data, labelArray); + } catch (error) { + console.error("[BetterSEQTA+] Failed to fetch notices:", error); } - - processNotices(data, labelArray); }; const debouncedInputChange = debounce((e: Event) => { - const target = e.target as HTMLInputElement; - fetchNotices(target.value); + fetchNotices((e.target as HTMLInputElement).value); }, 250); dateControl?.addEventListener("input", debouncedInputChange); @@ -290,15 +270,8 @@ function debounce any>( } function comparedate(obj1: any, obj2: any) { - if (obj1.date < obj2.date) { - return -1; - } - if (obj1.date > obj2.date) { - return 1; - } - return 0; + return obj1.date < obj2.date ? -1 : obj1.date > obj2.date ? 1 : 0; } - function processNotices(response: any, labelArray: string[]) { const NoticeContainer = document.getElementById("notice-container"); if (!NoticeContainer) return; @@ -368,12 +341,10 @@ function createNoticeElement(notice: any, colour: string | undefined): Node {
`; const element = stringToHTML(htmlContent).firstChild as HTMLElement; - if (element) { - element.addEventListener("click", () => - openNoticeModal(notice, colour, element), - ); - } - return element!; + element.addEventListener("click", () => + openNoticeModal(notice, colour, element), + ); + return element; } function openNoticeModal( @@ -385,15 +356,11 @@ function openNoticeModal( .replace(/\[\[[\w]+[:][\w]+[\]\]]+/g, "") .replace(/ +/, " "); - const existingModal = document.getElementById("notice-modal"); - if (existingModal) { - existingModal.remove(); - } + document.getElementById("notice-modal")?.remove(); const sourceRect = sourceElement.getBoundingClientRect(); let scrollY = Math.round(window.scrollY); let scrollX = Math.round(window.scrollX); - let sourceLeft = sourceRect.left; let sourceTop = sourceRect.top; let sourceWidth = sourceRect.width; @@ -475,7 +442,6 @@ function openNoticeModal( let targetHeight = Math.round( Math.min(Math.max(measuredHeight, 200), viewportHeight * 0.85), ); - let targetLeft = Math.round((viewportWidth - targetWidth) / 2); let targetTop = Math.round((viewportHeight - targetHeight) / 2) + scrollY; @@ -584,13 +550,10 @@ function openNoticeModal( const newTargetWidth = Math.round( Math.min(Math.max(newSourceWidth, 800), newViewportWidth - 40), ); - - // Just measure the existing modal content const currentHeight = unifiedContent.getBoundingClientRect().height; const newTargetHeight = Math.round( Math.min(Math.max(currentHeight, 200), newViewportHeight * 0.85), ); - const newTargetLeft = Math.round((newViewportWidth - newTargetWidth) / 2); const newTargetTop = Math.round((newViewportHeight - newTargetHeight) / 2) + newScrollY; @@ -655,118 +618,92 @@ function callHomeTimetable(date: string, change?: any) { xhr.setRequestHeader("Content-Type", "application/json; charset=utf-8"); xhr.onreadystatechange = function () { - if (xhr.readyState === 4) { - if (loadingTimeout) { - clearTimeout(loadingTimeout); - loadingTimeout = null; - } + if (xhr.readyState !== 4) return; - const DayContainer = document.getElementById("day-container")!; + if (loadingTimeout) { + clearTimeout(loadingTimeout); + loadingTimeout = null; + } - try { - var serverResponse = JSON.parse(xhr.response); - let lessonArray: Array = []; + const DayContainer = document.getElementById("day-container")!; - if (serverResponse.payload.items.length > 0) { - if (DayContainer.innerText || change) { - for (let i = 0; i < serverResponse.payload.items.length; i++) { - lessonArray.push(serverResponse.payload.items[i]); + var serverResponse = JSON.parse(xhr.response); + let lessonArray: Array = []; + + if (serverResponse.payload.items.length > 0) { + if (DayContainer.innerText || change) { + for (let i = 0; i < serverResponse.payload.items.length; i++) { + lessonArray.push(serverResponse.payload.items[i]); + } + lessonArray.sort(function (a, b) { + return a.from.localeCompare(b.from); + }); + + GetLessonColours().then((colours) => { + for (let i = 0; i < lessonArray.length; i++) { + let subjectname = + lessonArray[i].type == "tutorial" + ? `timetable.tutor.${lessonArray[i].tutorID}` + : `timetable.subject.colour.${lessonArray[i].code}`; + let subject = colours.find( + (element: any) => element.name === subjectname, + ); + + if (!subject) { + lessonArray[i].colour = "--item-colour: #8e8e8e;"; + } else { + lessonArray[i].colour = `--item-colour: ${subject.value};`; + if (GetThresholdOfColor(subject.value) > 300) { + lessonArray[i].invert = true; + } } - lessonArray.sort(function (a, b) { - return a.from.localeCompare(b.from); - }); - GetLessonColours().then((colours) => { - let subjects = colours; - for (let i = 0; i < lessonArray.length; i++) { - let subjectname = - lessonArray[i].type == "tutorial" - ? `timetable.tutor.${lessonArray[i].tutorID}` - : `timetable.subject.colour.${lessonArray[i].code}`; + lessonArray[i].from = lessonArray[i].from.substring(0, 5); + lessonArray[i].until = lessonArray[i].until.substring(0, 5); - let subject = subjects.find( - (element: any) => element.name === subjectname, - ); - if (!subject) { - lessonArray[i].colour = "--item-colour: #8e8e8e;"; - } else { - lessonArray[i].colour = `--item-colour: ${subject.value};`; - let result = GetThresholdOfColor(subject.value); + if (settingsState.timeFormat === "12") { + lessonArray[i].from = convertTo12HourFormat(lessonArray[i].from); + lessonArray[i].until = convertTo12HourFormat( + lessonArray[i].until, + ); + } - if (result > 300) { - lessonArray[i].invert = true; - } - } - - lessonArray[i].from = lessonArray[i].from.substring(0, 5); - lessonArray[i].until = lessonArray[i].until.substring(0, 5); - - if (settingsState.timeFormat === "12") { - lessonArray[i].from = convertTo12HourFormat( - lessonArray[i].from, - ); - lessonArray[i].until = convertTo12HourFormat( - lessonArray[i].until, - ); - } - - lessonArray[i].attendanceTitle = CheckUnmarkedAttendance( - lessonArray[i].attendance, - ); - } - - DayContainer.innerText = ""; - for (let i = 0; i < lessonArray.length; i++) { - var div = makeLessonDiv(lessonArray[i], i + 1); - - if (lessonArray[i].invert) { - const div1 = div.firstChild! as HTMLElement; - div1.classList.add("day-inverted"); - } - - DayContainer.append(div.firstChild as HTMLElement); - } - - DayContainer.classList.remove("loading"); - - const today = new Date(); - if (currentSelectedDate.getDate() == today.getDate()) { - for (let i = 0; i < lessonArray.length; i++) { - CheckCurrentLesson(lessonArray[i], i + 1); - } - - CheckCurrentLessonAll(lessonArray); - } - }); + lessonArray[i].attendanceTitle = CheckUnmarkedAttendance( + lessonArray[i].attendance, + ); + } + + DayContainer.innerText = ""; + for (let i = 0; i < lessonArray.length; i++) { + const div = makeLessonDiv(lessonArray[i], i + 1); + if (lessonArray[i].invert) { + (div.firstChild! as HTMLElement).classList.add("day-inverted"); + } + DayContainer.append(div.firstChild as HTMLElement); } - } else { - DayContainer.innerHTML = ""; - var dummyDay = document.createElement("div"); - dummyDay.classList.add("day-empty"); - let img = document.createElement("img"); - img.src = browser.runtime.getURL(LogoLight); - let text = document.createElement("p"); - text.innerText = "No lessons available."; - dummyDay.append(img); - dummyDay.append(text); - DayContainer.append(dummyDay); DayContainer.classList.remove("loading"); - } - } catch (error) { - console.error("Error loading timetable data:", error); - DayContainer.classList.remove("loading"); - - DayContainer.innerHTML = ""; - const errorDiv = document.createElement("div"); - errorDiv.classList.add("day-empty"); - errorDiv.innerHTML = ` - -

Error loading lessons. Please try again.

- `; - DayContainer.append(errorDiv); + const today = new Date(); + if (currentSelectedDate.getDate() == today.getDate()) { + for (let i = 0; i < lessonArray.length; i++) { + CheckCurrentLesson(lessonArray[i], i + 1); + } + CheckCurrentLessonAll(lessonArray); + } + }); } + } else { + DayContainer.innerHTML = ""; + const dummyDay = document.createElement("div"); + dummyDay.classList.add("day-empty"); + const img = document.createElement("img"); + img.src = browser.runtime.getURL(LogoLight); + const text = document.createElement("p"); + text.innerText = "No lessons available."; + dummyDay.append(img, text); + DayContainer.append(dummyDay); + DayContainer.classList.remove("loading"); } }; xhr.send( @@ -856,8 +793,6 @@ async function CheckCurrentLesson(lesson: any, num: number) { } function makeLessonDiv(lesson: any, num: number) { - if (!lesson) throw new Error("No lesson provided."); - const { code, colour, @@ -877,7 +812,7 @@ function makeLessonDiv(lesson: any, num: number) {

${type == "class" ? description : type == "tutorial" ? "Tutorial" : "Unknown"}

${staff || "Unknown"}

-

${room || "N/A"}

+

${type == "class" ? room : type == "tutorial" ? "N/A" : "Unknown"}

${from || "Unknown"} - ${until || "Unknown"}

${attendanceTitle || "Unknown"}
`; @@ -923,64 +858,48 @@ function buildAssessmentURL(programmeID: any, metaID: any, itemID = "") { } function CheckUnmarkedAttendance(lessonattendance: any) { - if (lessonattendance) { - var lesson = lessonattendance.label; - } else { - lesson = " "; - } - return lesson; + return lessonattendance ? lessonattendance.label : " "; } async function CreateUpcomingSection(assessments: any, activeSubjects: any) { - let upcomingitemcontainer = document.querySelector("#upcoming-items"); - let overdueDates = []; - let upcomingDates = {}; - - var Today = new Date(); + const upcomingitemcontainer = document.querySelector("#upcoming-items"); + const overdueDates = []; + const upcomingDates = {}; + const Today = new Date(); for (let i = 0; i < assessments.length; i++) { - const assessment = assessments[i]; - let assessmentdue = new Date(assessment.due); - - CheckSpecialDay(Today, assessmentdue); - if (assessmentdue < Today) { - if (!CheckSpecialDay(Today, assessmentdue)) { - overdueDates.push(assessment); - assessments.splice(i, 1); - i--; - } + const assessmentdue = new Date(assessments[i].due); + if (assessmentdue < Today && !CheckSpecialDay(Today, assessmentdue)) { + overdueDates.push(assessments[i]); + assessments.splice(i, 1); + i--; } } - var TomorrowDate = new Date(); - TomorrowDate.setDate(TomorrowDate.getDate() + 1); - const colours = await GetLessonColours(); - let subjects = colours; for (let i = 0; i < assessments.length; i++) { - let subjectname = `timetable.subject.colour.${assessments[i].code}`; - - let subject = subjects.find((element: any) => element.name === subjectname); - + const subject = colours.find( + (element: any) => + element.name === `timetable.subject.colour.${assessments[i].code}`, + ); if (!subject) { assessments[i].colour = "--item-colour: #8e8e8e;"; } else { assessments[i].colour = `--item-colour: ${subject.value};`; - GetThresholdOfColor(subject.value); } } for (let i = 0; i < activeSubjects.length; i++) { const element = activeSubjects[i]; - let subjectname = `timetable.subject.colour.${element.code}`; - let colour = colours.find((element: any) => element.name === subjectname); + const colour = colours.find( + (c: any) => c.name === `timetable.subject.colour.${element.code}`, + ); if (!colour) { element.colour = "--item-colour: #8e8e8e;"; } else { element.colour = `--item-colour: ${colour.value};`; - let result = GetThresholdOfColor(colour.value); - if (result > 300) { + if (GetThresholdOfColor(colour.value) > 300) { element.invert = true; } } @@ -991,42 +910,32 @@ async function CreateUpcomingSection(assessments: any, activeSubjects: any) { for (let i = 0; i < assessments.length; i++) { const element: any = assessments[i]; if (!upcomingDates[element.due as keyof typeof upcomingDates]) { - const dateObj: any = {}; - dateObj.div = CreateElement("div", "upcoming-date-container"); - dateObj.assessments = []; + const dateObj: any = { + div: CreateElement("div", "upcoming-date-container"), + assessments: [], + }; (upcomingDates[element.due as keyof typeof upcomingDates] as any) = dateObj; } const assessmentDateDiv = upcomingDates[element.due as keyof typeof upcomingDates]; - if (assessmentDateDiv) { (assessmentDateDiv as any).assessments.push(element); } } for (var date in upcomingDates) { - let assessmentdue = new Date( - (upcomingDates[date as keyof typeof upcomingDates] as any).assessments[0] - .due, + const assessmentdue = new Date( + ( + upcomingDates[date as keyof typeof upcomingDates] as any + ).assessments[0].due, + ); + const specialcase = CheckSpecialDay(Today, assessmentdue); + const assessmentDate = createAssessmentDateDiv( + date, + upcomingDates[date as keyof typeof upcomingDates], + specialcase, ); - let specialcase = CheckSpecialDay(Today, assessmentdue); - let assessmentDate; - - if (specialcase) { - let datecase: string = specialcase!; - assessmentDate = createAssessmentDateDiv( - date, - upcomingDates[date as keyof typeof upcomingDates], - - datecase, - ); - } else { - assessmentDate = createAssessmentDateDiv( - date, - upcomingDates[date as keyof typeof upcomingDates], - ); - } if (specialcase === "Yesterday") { upcomingitemcontainer!.insertBefore( @@ -1049,77 +958,68 @@ async function CreateUpcomingSection(assessments: any, activeSubjects: any) { } function createAssessmentDateDiv(date: string, value: any, datecase?: any) { - var options = { + const options = { weekday: "long" as "long", month: "long" as "long", day: "numeric" as "numeric", }; const FormattedDate = new Date(date); - const assessments = value.assessments; const container = value.div; - let DateTitleDiv = document.createElement("div"); + const DateTitleDiv = document.createElement("div"); DateTitleDiv.classList.add("upcoming-date-title"); if (datecase) { - let datetitle = document.createElement("h5"); + const datetitle = document.createElement("h5"); datetitle.classList.add("upcoming-special-day"); datetitle.innerText = datecase; DateTitleDiv.append(datetitle); container.setAttribute("data-day", datecase); } - let DateTitle = document.createElement("h5"); + const DateTitle = document.createElement("h5"); DateTitle.innerText = FormattedDate.toLocaleDateString("en-AU", options); DateTitleDiv.append(DateTitle); - container.append(DateTitleDiv); - let assessmentContainer = document.createElement("div"); + const assessmentContainer = document.createElement("div"); assessmentContainer.classList.add("upcoming-date-assessments"); for (let i = 0; i < assessments.length; i++) { const element = assessments[i]; - let item = document.createElement("div"); + const item = document.createElement("div"); item.classList.add("upcoming-assessment"); item.setAttribute("data-subject", element.code); item.id = `assessment${element.id}`; - item.style.cssText = element.colour; - let titlediv = document.createElement("div"); + const titlediv = document.createElement("div"); titlediv.classList.add("upcoming-subject-title"); - - let titlesvg = + titlediv.append( stringToHTML(` - `).firstChild; - titlediv.append(titlesvg!); + `).firstChild!, + ); - let detailsdiv = document.createElement("div"); + const detailsdiv = document.createElement("div"); detailsdiv.classList.add("upcoming-details"); - let detailstitle = document.createElement("h5"); + const detailstitle = document.createElement("h5"); detailstitle.innerText = `${element.subject} assessment`; - let subject = document.createElement("p"); + const subject = document.createElement("p"); subject.innerText = element.title; subject.classList.add("upcoming-assessment-title"); subject.onclick = function () { document.querySelector("#menu ul")!.classList.add("noscroll"); location.href = `../#?page=/assessments/${element.programmeID}:${element.metaclassID}&item=${element.id}`; }; - detailsdiv.append(detailstitle); - detailsdiv.append(subject); - - item.append(titlediv); - item.append(detailsdiv); + detailsdiv.append(detailstitle, subject); + item.append(titlediv, detailsdiv); assessmentContainer.append(item); fetch(`${location.origin}/seqta/student/assessment/submissions/get`, { method: "POST", - headers: { - "Content-Type": "application/json; charset=utf-8", - }, + headers: { "Content-Type": "application/json; charset=utf-8" }, body: JSON.stringify({ assessment: element.id, metaclass: element.metaclassID, @@ -1130,8 +1030,7 @@ function createAssessmentDateDiv(date: string, value: any, datecase?: any) { .then((response) => { if (response.payload.length > 0) { const assessment = document.querySelector(`#assessment${element.id}`); - - let submittedtext = document.createElement("div"); + const submittedtext = document.createElement("div"); submittedtext.classList.add("upcoming-submittedtext"); submittedtext.innerText = "Submitted"; assessment!.append(submittedtext); @@ -1169,36 +1068,37 @@ function CheckSpecialDay(date1: Date, date2: Date) { } async function GetLessonColours() { - let func = fetch(`${location.origin}/seqta/student/load/prefs?`, { - method: "POST", - headers: { - "Content-Type": "application/json; charset=utf-8", - }, - body: JSON.stringify({ request: "userPrefs", asArray: true, user: 69 }), - }); - return func - .then((result) => result.json()) - .then((response) => response.payload); + try { + return fetch(`${location.origin}/seqta/student/load/prefs?`, { + method: "POST", + headers: { "Content-Type": "application/json; charset=utf-8" }, + body: JSON.stringify({ request: "userPrefs", asArray: true, user: 69 }), + }) + .then((result) => result.json()) + .then((response) => response.payload); + } catch (error) { + console.error("[BetterSEQTA+] Failed to get lesson colours:", error); + return []; + } } function CreateFilters(subjects: any) { - let filteroptions = settingsState.subjectfilters; + const filteroptions = settingsState.subjectfilters; + const filterdiv = document.querySelector("#upcoming-filters"); - let filterdiv = document.querySelector("#upcoming-filters"); for (let i = 0; i < subjects.length; i++) { const element = subjects[i]; - if (!Object.prototype.hasOwnProperty.call(filteroptions, element.code)) { filteroptions[element.code] = true; settingsState.subjectfilters = filteroptions; } - let elementdiv = CreateSubjectFilter( - element.code, - element.colour, - filteroptions[element.code], + filterdiv!.append( + CreateSubjectFilter( + element.code, + element.colour, + filteroptions[element.code], + ), ); - - filterdiv!.append(elementdiv); } } @@ -1207,23 +1107,20 @@ function CreateSubjectFilter( itemcolour: string, checked: any, ) { - let label = CreateElement("label", "upcoming-checkbox-container"); + const label = CreateElement("label", "upcoming-checkbox-container"); label.innerText = subjectcode; - let input1 = CreateElement("input"); - const input = input1 as HTMLInputElement; + const input = CreateElement("input") as HTMLInputElement; input.type = "checkbox"; input.checked = checked; input.id = `filter-${subjectcode}`; label.style.cssText = itemcolour; - let span = CreateElement("span", "upcoming-checkmark"); - label.append(input); - label.append(span); + const span = CreateElement("span", "upcoming-checkmark"); + label.append(input, span); input.addEventListener("change", function (change) { - let filters = settingsState.subjectfilters; - let id = (change.target as HTMLInputElement)!.id.split("-")[1]; - filters[id] = (change.target as HTMLInputElement)!.checked; - + const filters = settingsState.subjectfilters; + const id = (change.target as HTMLInputElement).id.split("-")[1]; + filters[id] = (change.target as HTMLInputElement).checked; settingsState.subjectfilters = filters; });