From b5327f045d5e89c64291e0071c45010c2da9cc1e Mon Sep 17 00:00:00 2001 From: sethburkart123 Date: Sun, 9 Jun 2024 14:47:02 +1000 Subject: [PATCH] refactor: separate AddBetterSEQTA elements into smaller functions --- src/SEQTA.ts | 285 ++----------------- src/seqta/ui/AddBetterSEQTAElements.ts | 290 ++++++++++++++++++++ src/seqta/ui/colors/Manager.ts | 6 +- src/seqta/utils/listeners/StorageChanges.ts | 17 +- 4 files changed, 317 insertions(+), 281 deletions(-) create mode 100644 src/seqta/ui/AddBetterSEQTAElements.ts diff --git a/src/SEQTA.ts b/src/SEQTA.ts index e5cdba23..32d3f176 100644 --- a/src/SEQTA.ts +++ b/src/SEQTA.ts @@ -12,8 +12,6 @@ import { MessageHandler } from './seqta/utils/listeners/MessageListener' import { SettingsState } from "./types/storage" import ShortcutLinks from './seqta/content/links.json' import Sortable from 'sortablejs' -//import StorageListener from './seqta/utils/listeners/StorageChanges' -import { appendBackgroundToUI } from './seqta/ui/ImageBackgrounds' import assessmentsicon from './seqta/icons/assessmentsIcon' import browser from 'webextension-polyfill' import coursesicon from './seqta/icons/coursesIcon' @@ -23,13 +21,13 @@ import iframeCSS from "./css/iframe.scss?raw" import { onError } from './seqta/utils/onError' import stringToHTML from './seqta/utils/stringToHTML' import { updateAllColors } from './seqta/ui/colors/Manager' -import { updateBgDurations } from './seqta/ui/Animation' import { SettingsResizer } from "./seqta/ui/SettingsResizer"; import documentLoadCSS from './css/documentload.scss?inline' import injectedCSS from './css/injected.scss?inline' import { injectYouTubeVideo } from './seqta/ui/VideoLoader' import { settingsState } from './seqta/utils/listeners/SettingsState' import { StorageChangeHandler } from './seqta/utils/listeners/StorageChanges' +import { AddBetterSEQTAElements } from './seqta/ui/AddBetterSEQTAElements' declare global { interface Window { @@ -40,10 +38,8 @@ declare global { export let isChrome = window.chrome let SettingsClicked = false export let MenuOptionsOpen = false -let UserInitalCode = '' let currentSelectedDate = new Date() let LessonInterval: any -export let DarkMode: boolean var MenuItemMutation = false var NonSEQTAPage = false @@ -90,7 +86,7 @@ function SetDisplayNone(ElementName: string) { return `li[data-key=${ElementName}]{display:var(--menuHidden) !important; transition: 1s;}` } -function animbkEnable(item: any) { +export function enableAnimatedBackground(item: any) { if (item.animatedbk) { CreateBackground() } else { @@ -640,21 +636,16 @@ function CheckNoticeTextColour(notice: any) { mutations_list.forEach(function (mutation) { mutation.addedNodes.forEach(function (added_node) { const node = added_node as HTMLElement - const result = browser.storage.local.get(['DarkMode']) - function open (result: any) { - DarkMode = result.DarkMode - if (node.classList.contains('notice')) { - var hex = node.style.cssText.split(' ')[1] - if (hex) { + if (node.classList.contains('notice')) { + var hex = node.style.cssText.split(' ')[1] + if (hex) { const hex1 = hex.slice(0,-1) var threshold = GetThresholdOfColor(hex1) - if (DarkMode && threshold < 100) { + if (settingsState.DarkMode && threshold < 100) { node.style.cssText = '--color: undefined;' } } - } } - result.then(open, onError) }) }) }) @@ -785,14 +776,14 @@ function main(storedSetting: SettingsState) { if (storedSetting.onoff) { console.log('[BetterSEQTA+] Enabled') - if (DarkMode) document.documentElement.classList.add('dark') + if (settingsState.DarkMode) document.documentElement.classList.add('dark') document.querySelector('.legacy-root')?.classList.add('hidden') new StorageChangeHandler(); new MessageHandler() - updateAllColors(storedSetting) + updateAllColors() loading() InjectCustomIcons() HideMenuItems() @@ -874,7 +865,7 @@ export function closeSettings() { ExtensionSettings!.classList.add('hide') } -function addExtensionSettings() { +export function addExtensionSettings() { const extensionPopup = document.createElement('div') extensionPopup.classList.add('outside-container', 'hide') extensionPopup.id = 'ExtensionPopup' @@ -1155,254 +1146,22 @@ function ReplaceMenuSVG(element: HTMLElement, svg: string) { item.insertBefore((newsvg as Node), item.firstChild) } -async function AddBetterSEQTAElements(toggle: any) { - if (toggle) { - // Creates Home menu button and appends it as the first child of the list - - const result = await browser.storage.local.get() - - animbkEnable(result) - updateBgDurations(result) - - DarkMode = result.DarkMode - if (DarkMode) { - document.documentElement.classList.add('dark') - } - - const container = document.getElementById('content')! - const div = document.createElement('div') - div.classList.add('titlebar') - container.append(div) - const NewButton = stringToHTML('
  • ') - - const menu = document.getElementById('menu')! - const List = menu.firstChild! as HTMLElement - - if (NewButton.firstChild) { - List.insertBefore(NewButton.firstChild, List.firstChild) - } - - try { - // Fetch the response and wait for it - const response = await fetch(`${location.origin}/seqta/student/login`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json; charset=utf-8', - }, - body: JSON.stringify({ - mode: 'normal', - query: null, - redirect_url: location.origin, - }), - }) - - // Parse the JSON response and wait for it - const responseData = await response.json() - let info = responseData.payload - - // Manipulate the DOM as needed - const titlebar = document.getElementsByClassName('titlebar')[0] - const userInfo = stringToHTML( - /* html */` -
    - -
    -
    - ` - ).firstChild - titlebar.append(userInfo!) - - const userinfo = stringToHTML(/* html */ - `
    -
    -
    -

    -

    ${info.userDesc}

    -
    -

    ${UserInitalCode}

    -
    -
    `).firstChild - titlebar.append(userinfo!) - - var logoutbutton = document.getElementsByClassName('logout')[0] - var userInfosvgdiv = document.getElementById('logouttooltip')! - userInfosvgdiv.appendChild(logoutbutton) - - // Await the fetch response - const peopleResponse = await fetch(`${location.origin}/seqta/student/load/message/people`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json; charset=utf-8', - }, - body: JSON.stringify({ mode: 'student' }), - }) - - // Await the JSON parsing of the response - const peopleResponseData = await peopleResponse.json() - let students = peopleResponseData.payload - - // Process the students data - var index = students.findIndex(function (person: any) { - return ( - person.firstname == info.userDesc.split(' ')[0] && - person.surname == info.userDesc.split(' ')[1] - ) - }) - - let houseelement1 = document.getElementsByClassName('userInfohouse')[0] - const houseelement = houseelement1 as HTMLElement - if (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 - } - - } catch (error) { - console.error('Error fetching and processing student data:', error) - } - - const NewsButtonStr = '
  • ' - const NewsButton = stringToHTML(NewsButtonStr) - List!.appendChild(NewsButton.firstChild!) - - let a = document.createElement('div') - a.classList.add('icon-cover') - a.id = 'icon-cover' - menu!.appendChild(a) - - const menuCover = document.querySelector('#icon-cover') - menuCover!.addEventListener('click', function () { - location.href = '../#?page=/home' - loadHomePage(); - (document! - .getElementById('menu')! - .firstChild! as HTMLElement).classList.remove('noscroll') - }) - // Creates the home container when the menu button is pressed - const homebutton = document.getElementById('homebutton') - homebutton!.addEventListener('click', function () { - if (!MenuOptionsOpen) { - loadHomePage() - } - }) - - // Creates the news container when the menu button is pressed - const newsbutton = document.getElementById('newsbutton') - newsbutton!.addEventListener('click', function () { - if (!MenuOptionsOpen) { - SendNewsPage() - } - }) - } - - appendBackgroundToUI() - addExtensionSettings() - - // If betterSEQTA+ is enabled, run the code - if (toggle) { - // Creates settings and dashboard buttons next to alerts - let SettingsButton = stringToHTML( - '', - ) - let ContentDiv = document.getElementById('content') - ContentDiv!.append(SettingsButton.firstChild!) - - const result: any = await new Promise(resolve => { - const result = browser.storage.local.get() - result.then(resolve, onError) - }) - - const DarkMode = result!.DarkMode - const tooltipString = GetLightDarkModeString(DarkMode) - const svgContent = DarkMode ? '' : - '' - - const LightDarkModeButton = stringToHTML(` - - `) - - ContentDiv!.append(LightDarkModeButton.firstChild!) - - updateAllColors(DarkMode, result.selectedColor) - - document.getElementById('LightDarkModeButton')!.addEventListener('click', async () => { - const result: any = await new Promise(resolve => { - const result = browser.storage.local.get() - result.then(resolve, onError) - }) - - console.log(!settingsState.DarkMode) - settingsState.DarkMode = !settingsState.DarkMode; - - updateAllColors(!settingsState.DarkMode, result.selectedColor) - - const darklightText = document.getElementById('darklighttooliptext') - darklightText!.innerText = GetLightDarkModeString(!settingsState.DarkMode) - }) - - // Locate the menuToggle element - const menuToggle = document.getElementById('menuToggle') - menuToggle!.innerHTML = '' - - // Create three divs to act as lines of the hamburger icon - for (let i = 0; i < 3; i++) { - const line = document.createElement('div') - line.className = 'hamburger-line' - menuToggle!.appendChild(line) - } - } else { - // Creates settings and dashboard buttons next to alerts - let SettingsButton = stringToHTML( - '', - ) - let ContentDiv = document.getElementById('content') - ContentDiv!.append(SettingsButton.firstChild!) - } - - var AddedSettings = document.getElementById('AddedSettings') - var extensionPopup = document.getElementById('ExtensionPopup') +export function setupSettingsButton() { + var AddedSettings = document.getElementById('AddedSettings'); + var extensionPopup = document.getElementById('ExtensionPopup'); AddedSettings!.addEventListener('click', function () { if (SettingsClicked) { - extensionPopup!.classList.add('hide') - animate( - '#ExtensionPopup', - { opacity: [1, 0], scale: [1, 0] }, - { easing: spring({ stiffness: 220, damping: 18 }) } - ); - (document.getElementById('ExtensionIframe')! as HTMLIFrameElement).contentWindow!.postMessage('popupClosed', '*') - SettingsClicked = false; + extensionPopup!.classList.add('hide'); + animate('#ExtensionPopup', { opacity: [1, 0], scale: [1, 0] }, { easing: spring({ stiffness: 220, damping: 18 }) }); + (document.getElementById('ExtensionIframe')! as HTMLIFrameElement).contentWindow!.postMessage('popupClosed', '*'); + SettingsClicked = false; } else { - extensionPopup!.classList.remove('hide') - animate( - '#ExtensionPopup', - { opacity: [0, 1], scale: [0, 1] }, - { easing: spring({ stiffness: 260, damping: 24 }) } - ) - SettingsClicked = true + extensionPopup!.classList.remove('hide'); + animate('#ExtensionPopup', { opacity: [0, 1], scale: [0, 1] }, { easing: spring({ stiffness: 260, damping: 24 }) }); + SettingsClicked = true; } - }) -} - -function GetLightDarkModeString(darkMode: boolean) { - if (darkMode) { - return 'Switch to light theme' - } else { - return 'Switch to dark theme' - } + }); } async function CheckCurrentLesson(lesson: any, num: number) { @@ -2165,7 +1924,7 @@ async function AddCustomShortcutsToPage() { } } -async function loadHomePage() { +export async function loadHomePage() { // Sends the html data for the home page console.log('[BetterSEQTA+] Started Loading Home Page') @@ -2638,7 +2397,7 @@ function createNewShortcut(link: any, icon: any, viewBox: any, title: any) { document.getElementById('shortcuts')!.appendChild(shortcut) } -function SendNewsPage() { +export function SendNewsPage() { setTimeout(function () { // Sends the html data for the home page console.log('[BetterSEQTA+] Started Loading News Page') diff --git a/src/seqta/ui/AddBetterSEQTAElements.ts b/src/seqta/ui/AddBetterSEQTAElements.ts new file mode 100644 index 00000000..7e8fc15a --- /dev/null +++ b/src/seqta/ui/AddBetterSEQTAElements.ts @@ -0,0 +1,290 @@ +import browser from "webextension-polyfill"; +import { GetThresholdOfColor, SendNewsPage, addExtensionSettings, enableAnimatedBackground, loadHomePage, setupSettingsButton } from "../../SEQTA"; +import { updateBgDurations } from "./Animation"; +import { appendBackgroundToUI } from "./ImageBackgrounds"; +import stringToHTML from "../utils/stringToHTML"; +import { settingsState } from "../utils/listeners/SettingsState"; +import { updateAllColors } from "./colors/Manager"; + +export async function AddBetterSEQTAElements(toggle: any) { + if (toggle) { + const result = await browser.storage.local.get(); + + initializeSettings(result); + addDarkMode(result.DarkMode); + createHomeButton(); + await handleUserInfo(); + handleStudentData(); + createNewsButton(); + setupEventListeners(); + } + + appendBackgroundToUI(); + addExtensionSettings(); + if (toggle) { + await createSettingsButton(); + await addDarkLightToggle(); + customizeMenuToggle(); + } else { + await createSettingsButton(); + } + + setupSettingsButton(); +} + +function initializeSettings(result: any) { + enableAnimatedBackground(result); + updateBgDurations(result); +} + +function addDarkMode(DarkMode: boolean) { + if (DarkMode) { + document.documentElement.classList.add('dark'); + } +} + +function createHomeButton() { + const container = document.getElementById('content')!; + const div = document.createElement('div'); + div.classList.add('titlebar'); + container.append(div); + + const NewButton = stringToHTML('
  • '); + const menu = document.getElementById('menu')!; + const List = menu.firstChild! as HTMLElement; + + if (NewButton.firstChild) { + List.insertBefore(NewButton.firstChild, List.firstChild); + } +} + +async function handleUserInfo() { + try { + const response = await fetch(`${location.origin}/seqta/student/login`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json; charset=utf-8', + }, + body: JSON.stringify({ + mode: 'normal', + query: null, + redirect_url: location.origin, + }), + }); + + const responseData = await response.json(); + let info = responseData.payload; + updateUserInfo(info); + } catch (error) { + console.error('Error fetching and processing student data:', error); + } +} + +function updateUserInfo(info: { + basic: boolean; + clientIP: string[] | null; + email: string | null; + id: number | null; + lastAccessedTime: number | null; + meta: { + code: string | null; + governmentID: string | null; + }; + personUUID: string | null; + status: number | null; + synergeticCommunityUrl: string | null; + type: string | null; + userCode: string | null; + userDesc: string | null; + userName: string | null; +}) { + const titlebar = document.getElementsByClassName('titlebar')[0]; + + const userInfo = stringToHTML(/* html */` +
    + +
    +
    + `).firstChild; + titlebar.append(userInfo!); + + const userinfo = stringToHTML(/* html */` +
    +
    +
    +

    +

    ${info.userDesc}

    +
    +

    ${info.meta.code} // ${info.meta.governmentID}

    +
    +
    + `).firstChild; + titlebar.append(userinfo!); + + var logoutbutton = document.getElementsByClassName('logout')[0]; + var userInfosvgdiv = document.getElementById('logouttooltip')!; + userInfosvgdiv.appendChild(logoutbutton); +} + +async function handleStudentData() { + try { + const response = await fetch(`${location.origin}/seqta/student/load/message/people`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json; charset=utf-8', + }, + body: JSON.stringify({ mode: 'student' }), + }); + + const responseData = await response.json(); + let students = responseData.payload; + await updateStudentInfo(students); + } catch (error) { + console.error('Error fetching and processing student data:', error); + } +} + +async function getUserInfo() { + try { + const response = await fetch(`${location.origin}/seqta/student/login`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json; charset=utf-8', + }, + body: JSON.stringify({ + mode: 'normal', + query: null, + redirect_url: location.origin, + }), + }); + + const responseData = await response.json(); + return responseData.payload; + } catch (error) { + console.error('Error fetching user info:', error); + throw error; // Rethrow the error after logging it + } +} + +async function updateStudentInfo(students: any) { + const info = await getUserInfo(); // You would need to implement this to fetch or pass the user info + var index = students.findIndex(function (person: any) { + return ( + person.firstname == info.userDesc.split(' ')[0] && + person.surname == info.userDesc.split(' ')[1] + ); + }); + + let houseelement1 = document.getElementsByClassName('userInfohouse')[0]; + const houseelement = houseelement1 as HTMLElement; + + if (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; + } +} + +function createNewsButton() { + const NewsButtonStr = '
  • '; + const NewsButton = stringToHTML(NewsButtonStr); + const menu = document.getElementById('menu')!; + const List = menu.firstChild! as HTMLElement; + + List!.appendChild(NewsButton.firstChild!); + + let a = document.createElement('div'); + a.classList.add('icon-cover'); + a.id = 'icon-cover'; + menu!.appendChild(a); +} + +function setupEventListeners() { + const menuCover = document.querySelector('#icon-cover'); + menuCover!.addEventListener('click', function () { + location.href = '../#?page=/home'; + loadHomePage(); + (document!.getElementById('menu')!.firstChild! as HTMLElement).classList.remove('noscroll'); + }); + + const homebutton = document.getElementById('homebutton'); + homebutton!.addEventListener('click', function () { + if (!homebutton?.classList.contains('draggable') && !homebutton?.classList.contains('active')) { + loadHomePage(); + } + }); + + const newsbutton = document.getElementById('newsbutton'); + newsbutton!.addEventListener('click', function () { + if (!newsbutton?.classList.contains('draggable') && !newsbutton?.classList.contains('active')) { + SendNewsPage(); + } + }); +} + +async function createSettingsButton() { + let SettingsButton = stringToHTML( + '' + ); + let ContentDiv = document.getElementById('content'); + ContentDiv!.append(SettingsButton.firstChild!); +} + +function GetLightDarkModeString(darkMode: boolean) { + if (darkMode) { + return 'Switch to light theme' + } else { + return 'Switch to dark theme' + } +} + +async function addDarkLightToggle() { + const tooltipString = GetLightDarkModeString(settingsState.DarkMode); + const svgContent = settingsState.DarkMode ? + '' : + ''; + + const LightDarkModeButton = stringToHTML(` + + `); + + let ContentDiv = document.getElementById('content'); + ContentDiv!.append(LightDarkModeButton.firstChild!); + + updateAllColors(); + + document.getElementById('LightDarkModeButton')!.addEventListener('click', async () => { + settingsState.DarkMode = !settingsState.DarkMode; + + updateAllColors(); + + const darklightText = document.getElementById('darklighttooliptext'); + darklightText!.innerText = GetLightDarkModeString(!settingsState.DarkMode); + }); +} + +function customizeMenuToggle() { + const menuToggle = document.getElementById('menuToggle'); + if (menuToggle) { + menuToggle.innerHTML = ''; + } + + const line = document.createElement('div'); + line.className = 'hamburger-line'; + + for (let i = 0; i < 3; i++) { + menuToggle!.appendChild(line); + } +} \ No newline at end of file diff --git a/src/seqta/ui/colors/Manager.ts b/src/seqta/ui/colors/Manager.ts index c070b83f..039b55c0 100644 --- a/src/seqta/ui/colors/Manager.ts +++ b/src/seqta/ui/colors/Manager.ts @@ -15,11 +15,11 @@ const getChromeURL = (path: any) => browser.runtime.getURL(path); const applyProperties = (props: any) => Object.entries(props).forEach(([key, value]) => setCSSVar(key, value)); -export function updateAllColors(storedSetting: any, newColor = null) { +export function updateAllColors() { // Determine the color to use - const selectedColor = newColor || (storedSetting.selectedColor !== '' ? storedSetting.selectedColor : '#007bff'); + const selectedColor = settingsState.selectedColor !== '' ? settingsState.selectedColor : '#007bff'; - if (storedSetting.transparencyEffects) { + if (settingsState.transparencyEffects) { document.documentElement.classList.add('transparencyEffects'); } diff --git a/src/seqta/utils/listeners/StorageChanges.ts b/src/seqta/utils/listeners/StorageChanges.ts index 0b01499f..4b448ec7 100644 --- a/src/seqta/utils/listeners/StorageChanges.ts +++ b/src/seqta/utils/listeners/StorageChanges.ts @@ -19,9 +19,8 @@ export class StorageChangeHandler { } private registerHandlers() { - console.log(settingsState.onoff); - settingsState.register('selectedColor', this.handleSelectedColorChange.bind(this)); - settingsState.register('DarkMode', this.handleDarkModeChange.bind(this)); + settingsState.register('selectedColor', updateAllColors.bind(this)); + settingsState.register('DarkMode', updateAllColors.bind(this)); settingsState.register('onoff', this.handleOnOffChange.bind(this)); settingsState.register('shortcuts', this.handleShortcutsChange.bind(this)); settingsState.register('customshortcuts', this.handleCustomShortcutsChange.bind(this)); @@ -31,18 +30,6 @@ export class StorageChangeHandler { settingsState.register('transparencyEffects', this.handleTransparencyEffectsChange.bind(this)); } - private handleDarkModeChange() { - updateAllColors(settingsState.selectedColor); - } - - private handleSelectedColorChange(newColor: any) { - try { - updateAllColors(newColor); - } catch (err) { - console.error(err); - } - } - private handleOnOffChange() { browser.runtime.sendMessage({ type: 'reloadTabs' }); }