From c1f095a503e0f9482ee37d9c85da6a2002c4c0da Mon Sep 17 00:00:00 2001 From: SethBurkart123 Date: Wed, 24 Jan 2024 08:47:54 +1100 Subject: [PATCH] bug: major bug fixes and smoothing --- chrome/manifest.json | 42 ++++++ firefox/manifest.json | 37 +++++ package.json | 6 +- src/SEQTA.ts | 127 ++++++++++++------ src/seqta/ui/ImageBackgrounds.ts | 4 +- .../seqta/ui/background}/background.html | 2 +- .../seqta/ui/background/background.ts | 46 ++++--- 7 files changed, 198 insertions(+), 66 deletions(-) create mode 100644 chrome/manifest.json create mode 100644 firefox/manifest.json rename {public/backgrounds => src/seqta/ui/background}/background.html (91%) rename public/backgrounds/background.js => src/seqta/ui/background/background.ts (68%) diff --git a/chrome/manifest.json b/chrome/manifest.json new file mode 100644 index 00000000..530f15e2 --- /dev/null +++ b/chrome/manifest.json @@ -0,0 +1,42 @@ +{ + "manifest_version": 3, + "name": "BetterSEQTA+", + "version": "3.2.2", + "description": "Make SEQTA usable and beautiful! A fork of BetterSEQTA to continue development and add WAY more features!!!", + "icons": { + "32": "src/resources/icons/icon-32.png", + "48": "src/resources/icons/icon-48.png", + "64": "src/resources/icons/icon-64.png" + }, + "action": { + "browser_style": true, + "default_popup": "src/interface/index.html#settings", + "default_icon": { + "32": "src/resources/icons/icon-32.png", + "48": "src/resources/icons/icon-48.png", + "64": "src/resources/icons/icon-64.png" + } + }, + "permissions": ["tabs", "notifications", "storage"], + "host_permissions": ["https://newsapi.org/", "*://*/*"], + "background": { + "service_worker": "src/background.ts", + "type": "module" + }, + "content_scripts": [ + { + "matches": ["*://*/*"], + "js": ["src/SEQTA.ts"], + "run_at": "document_start" + } + ], + "web_accessible_resources": [ + { + "resources": [ + "public/*", + "src/*" + ], + "matches": ["*://*/*"] + } + ] +} \ No newline at end of file diff --git a/firefox/manifest.json b/firefox/manifest.json new file mode 100644 index 00000000..e9633ce1 --- /dev/null +++ b/firefox/manifest.json @@ -0,0 +1,37 @@ +{ + "manifest_version": 2, + "name": "BetterSEQTA+", + "version": "3.2.2", + "description": "Make SEQTA usable and beautiful! A fork of BetterSEQTA to continue development and add WAY more features!!!", + "icons": { + "32": "../src/resources/icons/icon-32.png", + "48": "../src/resources/icons/icon-48.png", + "64": "../src/resources/icons/icon-64.png" + }, + "browser_action": { + "browser_style": true, + "default_popup": "../src/interface/index.html#settings", + "default_icon": { + "32": "../src/resources/icons/icon-32.png", + "48": "../src/resources/icons/icon-48.png", + "64": "../src/resources/icons/icon-64.png" + } + }, + "permissions": ["tabs", "notifications", "storage", "https://newsapi.org/"], + "background": { + "scripts": [ + "../src/background.ts" + ] + }, + "content_scripts": [ + { + "matches": ["*://*/*"], + "js": ["../src/SEQTA.ts"], + "run_at": "document_start" + } + ], + "web_accessible_resources": [ + "../src/*", + "../public/*" + ] +} \ No newline at end of file diff --git a/package.json b/package.json index a1f67ebf..931f561f 100644 --- a/package.json +++ b/package.json @@ -13,8 +13,8 @@ "license": "MIT", "devDependencies": { "@parcel/config-webextension": "^2.10.3", - "@parcel/optimizer-data-url": "2.10.3", - "@parcel/transformer-inline-string": "2.10.3", + "@parcel/optimizer-data-url": "^2.11.0", + "@parcel/transformer-inline-string": "^2.11.0", "@parcel/transformer-sass": "2.10.3", "assert": "^2.0.0", "browserify-zlib": "^0.2.0", @@ -26,7 +26,7 @@ "os-browserify": "^0.3.0", "parcel": "^2.10.3", "path-browserify": "^1.0.0", - "prettier": "3.0.2", + "prettier": "^3.2.2", "process": "^0.11.10", "querystring-es3": "^0.2.1", "sass": "^1.69.5", diff --git a/src/SEQTA.ts b/src/SEQTA.ts index ae9ecca6..b0fab448 100644 --- a/src/SEQTA.ts +++ b/src/SEQTA.ts @@ -1,6 +1,6 @@ import * as Sentry from "@sentry/browser" -import { animate, spring, stagger } from 'motion' +import { animate, spring, /* stagger */ } from 'motion' import loading, { AppendLoadingSymbol } from './seqta/ui/Loading' import updateVideo from 'url:./resources/update-video.mp4' @@ -370,24 +370,37 @@ export function RemoveBackground() { bk3[0].remove() } -export function waitForElm(selector: any) { +export function waitForElm(selector: string) { return new Promise((resolve) => { - if (document.querySelector(selector)) { - return resolve(document.querySelector(selector)) + const querySelector = () => document.querySelector(selector); + + if (querySelector()) { + return resolve(querySelector()); } const observer = new MutationObserver(() => { - if (document.querySelector(selector)) { - resolve(document.querySelector(selector)) - observer.disconnect() + if (querySelector()) { + resolve(querySelector()); + observer.disconnect(); } - }) + }); - observer.observe(document.body, { - childList: true, - subtree: true, - }) - }) + // 🛡️ Safety check: Ensure document.body is available + if (document.body) { + observer.observe(document.body, { + childList: true, + subtree: true, + }); + } else { + // 🚨 Fallback: Wait for the document to be ready + document.addEventListener('DOMContentLoaded', () => { + observer.observe(document.body, { + childList: true, + subtree: true, + }); + }); + } + }); } export function GetCSSElement(file: string) { @@ -440,7 +453,19 @@ async function updateIframesWithDarkMode(): Promise { } }) - observer.observe(document.body, { subtree: true, childList: true }) + if (document.body) { + observer.observe(document.body, { + childList: true, + subtree: true, + }); + } else { + document.addEventListener('DOMContentLoaded', () => { + observer.observe(document.body, { + childList: true, + subtree: true, + }); + }); + } } function applyDarkModeToIframe(iframe: HTMLIFrameElement, cssLink: HTMLStyleElement): void { @@ -806,8 +831,8 @@ export function closeSettings() { } function addExtensionSettings() { - const link = GetCSSElement('src/interface/popup.css') - document.querySelector('html')!.appendChild(link) + /* const link = GetCSSElement('src/interface/popup.css') + document.querySelector('html')!.appendChild(link) */ const extensionPopup = document.createElement('div') extensionPopup.classList.add('outside-container', 'hide') @@ -1189,14 +1214,16 @@ async function AddBetterSEQTAElements(toggle: any) { let houseelement1 = document.getElementsByClassName('userInfohouse')[0] const houseelement = houseelement1 as HTMLElement if (students[index]?.house) { - (houseelement as HTMLElement).style.background = students[index].house_colour - try { - let colorresult = GetThresholdOfColor(students[index]?.house_colour) - - houseelement.style.color = colorresult && colorresult > 300 ? 'black' : 'white' - houseelement.innerText = students[index].year + students[index].house - } catch (error) { - houseelement.innerText = students[index].house + if (students[index]?.house_colour) { + houseelement.style.background = students[index].house_colour + try { + let colorresult = GetThresholdOfColor(students[index]?.house_colour) + + houseelement.style.color = colorresult && colorresult > 300 ? 'black' : 'white' + houseelement.innerText = students[index].year + students[index].house + } catch (error) { + houseelement.innerText = students[index].house + } } } else { houseelement.innerText = students[index].year @@ -1626,19 +1653,20 @@ function callHomeTimetable(date: string, change?: any) { } } else { if (DayContainer == null) { - - } else (!DayContainer.innerHTML || change); { - DayContainer.innerHTML = '' - var dummyDay = document.createElement('div') - dummyDay.classList.add('day-empty') - let img = document.createElement('img') - img.src = LogoLight - let text = document.createElement('p') - text.innerText = 'No lessons available.' - dummyDay.append(img) - dummyDay.append(text) - DayContainer.append(dummyDay) + console.log('DayContainer is null') + //DayContainer = document.getElementById('day-container')! } + console.log(DayContainer); + DayContainer.innerHTML = '' + var dummyDay = document.createElement('div') + dummyDay.classList.add('day-empty') + let img = document.createElement('img') + img.src = LogoLight + let text = document.createElement('p') + text.innerText = 'No lessons available.' + dummyDay.append(img) + dummyDay.append(text) + DayContainer.append(dummyDay) } } } @@ -2160,14 +2188,20 @@ async function loadHomePage() { // Sends the html data for the home page console.log('[BetterSEQTA] Started Loading Home Page') document.title = 'Home ― SEQTA Learn' - var element = document.querySelector('[data-key=home]') + const element = document.querySelector('[data-key=home]') // Apply the active class to indicate clicked on home button element!.classList.add('active') // Remove all current elements in the main div to add new elements - var main = document.getElementById('main') - main!.innerHTML = ''; + const main = document.getElementById('main') + + if (!main) { + console.error('Main element not found.') + return + } + + //main.innerHTML = ''; const icon = document.querySelector('link[rel*="icon"]')! as HTMLLinkElement icon.href = icon48 @@ -2198,7 +2232,12 @@ async function loadHomePage() { const Timetable = stringToHTML('

Today\'s Lessons

') // Appends the timetable container into the home container document.getElementById('home-container')!.append(Timetable.firstChild!) - callHomeTimetable(TodayFormatted, true) + if (document.getElementById('home-container')) { + callHomeTimetable(TodayFormatted, true) + } else { + console.error("HELP! THERE IS NO HOME CONTAINER") + } + const timetablearrowback = document.getElementById('home-timetable-back') const timetablearrowforward = document.getElementById('home-timetable-forward') @@ -2507,7 +2546,11 @@ async function loadHomePage() { activeClassList = classes[i] } } - let activeSubjects = activeClassList.subjects + + let activeSubjects = [] + if (activeClassList?.subjects) { + activeSubjects = activeClassList.subjects + } let activeSubjectCodes = [] @@ -2683,7 +2726,7 @@ function SendNewsPage() { async function CheckForMenuList() { if (!MenuItemMutation) { try { - if (document.getElementById('menu')!.firstChild) { + if (document.getElementById('menu')?.firstChild) { ObserveMenuItemPosition() MenuItemMutation = true } diff --git a/src/seqta/ui/ImageBackgrounds.ts b/src/seqta/ui/ImageBackgrounds.ts index 15782c9a..645e44d2 100644 --- a/src/seqta/ui/ImageBackgrounds.ts +++ b/src/seqta/ui/ImageBackgrounds.ts @@ -1,4 +1,4 @@ -import browser from 'webextension-polyfill' +import backgroundPage from 'url:./background/background.html' export async function appendBackgroundToUI() { console.log('Starting appendBackgroundToUI...'); @@ -10,6 +10,6 @@ export async function appendBackgroundToUI() { background.id = 'background'; background.classList.add('imageBackground'); background.setAttribute('excludeDarkCheck', 'true'); - background.src = browser.runtime.getURL('backgrounds/background.html'); + background.src = backgroundPage; parent!.appendChild(background); } diff --git a/public/backgrounds/background.html b/src/seqta/ui/background/background.html similarity index 91% rename from public/backgrounds/background.html rename to src/seqta/ui/background/background.html index cbf1a004..eeb2bc55 100644 --- a/public/backgrounds/background.html +++ b/src/seqta/ui/background/background.html @@ -24,6 +24,6 @@
- + diff --git a/public/backgrounds/background.js b/src/seqta/ui/background/background.ts similarity index 68% rename from public/backgrounds/background.js rename to src/seqta/ui/background/background.ts index c5cdcf7b..71ac3f97 100644 --- a/public/backgrounds/background.js +++ b/src/seqta/ui/background/background.ts @@ -1,20 +1,31 @@ -// Open the database -const openDB = () => { +interface Data { + blob: Blob; + type: 'image' | 'video'; +} + +interface DatabaseEventTarget extends EventTarget { + result: IDBDatabase; +} + +interface DatabaseEvent extends Event { + target: DatabaseEventTarget; +} + +const openDB = (): Promise => { return new Promise((resolve, reject) => { const request = indexedDB.open('MyDatabase', 1); request.onerror = () => reject(request.error); request.onsuccess = () => resolve(request.result); - request.onupgradeneeded = (event) => { - const db = event.target.result; - db.createObjectStore('backgrounds', { keyPath: 'id' }); + request.onupgradeneeded = (event: IDBVersionChangeEvent) => { + // @ts-expect-error + event?.target?.result.createObjectStore('backgrounds', { keyPath: 'id' }); }; }); }; -// Modified Read Data from IndexedDB -const readData = async () => { +const readData = async (): Promise => { const selectedBackground = localStorage.getItem('selectedBackground'); if (!selectedBackground) { return null; @@ -25,20 +36,20 @@ const readData = async () => { const store = tx.objectStore('backgrounds'); const request = store.get(selectedBackground); - return await new Promise((resolve, reject) => { - request.onsuccess = () => resolve(request.result); + return new Promise((resolve, reject) => { + request.onsuccess = () => resolve(request.result as Data); request.onerror = () => reject(request.error); }); }; -const updateBackground = async () => { +const updateBackground = async (): Promise => { try { const data = await readData(); if (!data) { console.log('No data found in IndexedDB.'); const container = document.getElementById('media-container'); - const currentMedia = container.querySelector('.current-media'); + const currentMedia = container?.querySelector('.current-media'); if (currentMedia) { currentMedia.remove(); } @@ -63,19 +74,19 @@ const updateBackground = async () => { } // Mark the old element for removal - const oldElement = container.querySelector('.current-media'); + const oldElement = container?.querySelector('.current-media'); if (oldElement) { oldElement.classList.remove('current-media'); oldElement.classList.add('old-media'); } // Add the new element and mark it as current - newElement.classList.add('current-media'); - container.appendChild(newElement); + newElement?.classList.add('current-media'); + container?.appendChild(newElement as Node); // Delay removal of old element setTimeout(() => { - const oldMedia = container.querySelector('.old-media'); + const oldMedia = container?.querySelector('.old-media'); if (oldMedia) { oldMedia.remove(); } @@ -86,13 +97,12 @@ const updateBackground = async () => { }; // Main function to run on page load -const main = async () => { - await updateBackground(); // Initial background update +const main = async (): Promise => { + await updateBackground(); // Listen for changes to local storage window.addEventListener('storage', async (event) => { if (event.key === 'selectedBackground') { - await updateBackground(); // Update background if 'selectedBackground' changes } }); };