/*global chrome*/ import ShortcutLinks from "./seqta/content/links.json"; import MenuitemSVGKey from "./seqta/content/MenuItemSVGKey.json"; import stringToHTML from "./seqta/utils/stringToHTML.js"; import loading, { AppendLoadingSymbol } from "./seqta/ui/Loading.js"; // Icons import assessmentsicon from "./seqta/icons/assessmentsIcon.js"; import coursesicon from "./seqta/icons/coursesIcon.js"; let isChrome = window.chrome; let SettingsClicked = false; let MenuOptionsOpen = false; let UserInitalCode = ""; let currentSelectedDate = new Date(); let WhatsNewOpen = false; let LessonInterval; let DarkMode; function delay(ms) { return new Promise((resolve) => setTimeout(resolve, ms)); } function SetDisplayNone(ElementName) { return `li[data-key=${ElementName}]{display:var(--menuHidden) !important; transition: 1s;}`; } function ApplyCSSToHiddenMenuItems() { var stylesheetInnerText = ""; chrome.storage.local.get(null, function (result) { for (let i = 0; i < Object.keys(result.menuitems).length; i++) { if (!Object.values(result.menuitems)[i].toggle) { stylesheetInnerText += SetDisplayNone(Object.keys(result.menuitems)[i]); console.log( `[BetterSEQTA+] Hiding ${ Object.keys(result.menuitems)[i] } menu item`, ); } } let MenuItemStyle = document.createElement("style"); MenuItemStyle.innerText = stylesheetInnerText; document.head.appendChild(MenuItemStyle); }); } function OpenWhatsNewPopup() { const background = document.createElement("div"); background.id = "whatsnewbk"; background.classList.add("whatsnewBackground"); const container = document.createElement("div"); container.classList.add("whatsnewContainer"); var header = stringToHTML(`

What's New

BetterSEQTA+ V${chrome.runtime.getManifest().version}

`).firstChild; let imagecont = document.createElement("div"); imagecont.classList.add("whatsnewImgContainer"); var image = document.createElement("img"); image.src = chrome.runtime.getURL("icons/betterseqta-dark-icon.png"); image.classList.add("whatsnewImg"); imagecont.append(image); let textcontainer = document.createElement("div"); textcontainer.classList.add("whatsnewTextContainer"); let textheader = stringToHTML( "

DESIGN OVERHAUL

", ).firstChild; textcontainer.append(textheader); let text = stringToHTML( String.raw`

3.0.0 - BetterSEQTA+ *Complete Overhaul*

  • Redesigned appearance
  • Upgraded to manifest V3 (longer support)
  • Fixed transitional glitches
  • Under the hood improvements
  • Fixed News Feed
  • 2.0.7 - Added support to other domains + Minor bug fixes

  • Fixed BetterSEQTA+ not loading on some pages
  • Fixed text colour of notices being unreadable
  • Fixed pages not reloading when saving changes
  • 2.0.2 - Minor bug fixes

  • Fixed indicator for current lesson
  • Fixed text colour for DM messages list in Light mode
  • Fixed user info text colour
  • Sleek New Layout

  • Updated with a new font and presentation, BetterSEQTA+ has never looked better.
  • New Updated Sidebar

  • Condensed appearance with new updated icons.
  • Independent Light Mode and Dark Mode

  • Dark mode and Light mode are now available to pick alongside your chosen Theme Colour. Your Theme Colour will now become an accent colour for the page. Light/Dark mode can be toggled with the new button, found in the top-right of the menu bar.
  • Create Custom Shortcuts

  • Found in the BetterSEQTA+ Settings menu, custom shortcuts can now be created with a name and URL of your choice.
  • `, ).firstChild; let footer = stringToHTML( String.raw`
    Report bugs and feedback:
    `).firstChild; let exitbutton = document.createElement("div"); exitbutton.innerText = "x"; exitbutton.id = "whatsnewclosebutton"; container.append(header); container.append(imagecont); container.append(textcontainer); container.append(text); container.append(footer); container.append(exitbutton); document.getElementById("container").append(background); document.getElementById("container").append(container); chrome.storage.local.remove(["justupdated"]); var bkelement = document.getElementById("whatsnewbk"); bkelement.addEventListener("click", function () { DeleteWhatsNew(); WhatsNewOpen = false; }); var closeelement = document.getElementById("whatsnewclosebutton"); closeelement.addEventListener("click", function () { DeleteWhatsNew(); WhatsNewOpen = false; }); } async function finishLoad() { try { var loadingbk = document.getElementById("loading"); loadingbk.style.opacity = "0"; await delay(501); loadingbk.remove(); } catch (err) { console.log(err); } chrome.storage.local.get(["justupdated"], function (result) { if (result.justupdated) { WhatsNewOpen = true; OpenWhatsNewPopup(); } }); } async function DeleteWhatsNew() { var bkelement = document.getElementById("whatsnewbk"); var popup = document.getElementsByClassName("whatsnewContainer")[0]; bkelement.classList.add("whatsnewfadeout"); popup.classList.add("whatsnewzoomout"); await delay(500); bkelement.remove(); popup.remove(); } function CreateBackground() { // Creating and inserting 3 divs containing the background applied to the pages var bklocation = document.getElementById("container"); var menu = document.getElementById("menu"); var bk = document.createElement("div"); bk.classList.add("bg"); bklocation.insertBefore(bk, menu); var bk2 = document.createElement("div"); bk2.classList.add("bg"); bk2.classList.add("bg2"); bklocation.insertBefore(bk2, menu); var bk3 = document.createElement("div"); bk3.classList.add("bg"); bk3.classList.add("bg3"); bklocation.insertBefore(bk3, menu); } function waitForElm(selector) { return new Promise((resolve) => { if (document.querySelector(selector)) { return resolve(document.querySelector(selector)); } const observer = new MutationObserver(() => { if (document.querySelector(selector)) { resolve(document.querySelector(selector)); observer.disconnect(); } }); observer.observe(document.body, { childList: true, subtree: true, }); }); } async function RunColourCheck(element) { if ( typeof element.contentDocument.documentElement.childNodes[1] == "undefined" ) { await delay(1000); RunColourCheck(element); } else { element.contentDocument.documentElement.childNodes[1].style.color = "white"; } } function GetiFrameCSSElement() { var cssFile = chrome.runtime.getURL("inject/iframe.css"); var fileref = document.createElement("link"); fileref.setAttribute("rel", "stylesheet"); fileref.setAttribute("type", "text/css"); fileref.setAttribute("href", cssFile); return fileref; } function CheckiFrameItems() { // Injecting CSS File to the webpage to overwrite iFrame default CSS let fileref = GetiFrameCSSElement(); const observer = new MutationObserver(function (mutations_list) { mutations_list.forEach(function (mutation) { mutation.addedNodes.forEach(function (added_node) { if (added_node.tagName == "IFRAME") { chrome.storage.local.get(["DarkMode"], function (result) { DarkMode = result.DarkMode; if (DarkMode) { RunColourCheck(added_node); if ( added_node.contentDocument.documentElement.childNodes[1].style .color != "white" ) { added_node.contentDocument.documentElement.childNodes[1].style.color = "white"; } if ( !added_node.contentDocument.documentElement.firstChild.innerHTML.includes( "iframe.css", ) ) { added_node.contentDocument.documentElement.firstChild.appendChild( fileref, ); } added_node.addEventListener("load", function () { if ( added_node.contentDocument.documentElement.childNodes[1].style .color != "white" ) { added_node.contentDocument.documentElement.childNodes[1].style.color = "white"; } if ( !added_node.contentDocument.documentElement.firstChild.innerHTML.includes( "iframe.css", ) ) { added_node.contentDocument.documentElement.firstChild.appendChild( fileref, ); } }); } }); } }); }); }); observer.observe(document.body, { subtree: true, childList: true, }); } function SortMessagePageItems(messagesParentElement) { let filterbutton = document.createElement("div"); filterbutton.classList.add("messages-filterbutton"); filterbutton.innerText = "Filter"; let header = document.getElementsByClassName( "MessageList__MessageList___3DxoC", )[0].firstChild; header.append(filterbutton); const observer = new MutationObserver(function (mutations_list) { mutations_list.forEach(function (mutation) { mutation.addedNodes.forEach(function (added_node) { if (added_node.dataset.message) { // Check if added_node.firstChild.title is in block list } }); }); }); observer.observe(messagesParentElement, { subtree: true, childList: true, }); } function LoadPageElements() { AddBetterSEQTAElements(true); var sublink = window.location.href.split("/")[4]; switch (sublink) { case "news": console.log("[BetterSEQTA+] Started Init"); chrome.storage.local.get(null, function (result) { if (result.onoff) { SendNewsPage(); // Sends similar HTTP Post Request for the notices chrome.storage.local.get(null, function (result) { if (result.notificationcollector) { var xhr3 = new XMLHttpRequest(); xhr3.open( "POST", `${location.origin}/seqta/student/heartbeat?`, true, ); xhr3.setRequestHeader( "Content-Type", "application/json; charset=utf-8", ); xhr3.onreadystatechange = function () { if (xhr3.readyState === 4) { var Notifications = JSON.parse(xhr3.response); var alertdiv = document.getElementsByClassName( "notifications__bubble___1EkSQ", )[0]; if (typeof alertdiv == "undefined") { console.log( "[BetterSEQTA+] No notifications currently", ); } else { alertdiv.textContent = Notifications.payload.notifications.length; } } }; xhr3.send( JSON.stringify({ timestamp: "1970-01-01 00:00:00.0", hash: "#?page=/home", }), ); } }); finishLoad(); } }); break; case "home": window.location.replace(`${location.origin}/#?page=/home`); LoadInit(); break; case undefined: window.location.replace(`${location.origin}/#?page=/home`); LoadInit(); break; default: finishLoad(); // Sends similar HTTP Post Request for the notices chrome.storage.local.get(null, function (result) { if (result.notificationcollector) { var xhr3 = new XMLHttpRequest(); xhr3.open( "POST", `${location.origin}/seqta/student/heartbeat?`, true, ); xhr3.setRequestHeader( "Content-Type", "application/json; charset=utf-8", ); xhr3.onreadystatechange = function () { if (xhr3.readyState === 4) { var Notifications = JSON.parse(xhr3.response); var alertdiv = document.getElementsByClassName( "notifications__bubble___1EkSQ", )[0]; if (typeof alertdiv == "undefined") { console.log("[BetterSEQTA+] No notifications currently"); } else { alertdiv.textContent = Notifications.payload.notifications.length; } } }; xhr3.send( JSON.stringify({ timestamp: "1970-01-01 00:00:00.0", hash: "#?page=/home", }), ); } }); break; } const observer = new MutationObserver(function (mutations_list) { mutations_list.forEach(function (mutation) { mutation.addedNodes.forEach(function (added_node) { if (added_node.classList.contains("messages")) { let element = document.getElementById("title").firstChild; element.innerText = "Direct Messages"; document.title = "Direct Messages ― SEQTA Learn"; SortMessagePageItems(added_node); } else if (added_node.classList.contains("notices")) { CheckNoticeTextColour(added_node); } }); }); }); observer.observe(document.querySelector("#main"), { subtree: false, childList: true, }); } function CheckNoticeTextColour(notice) { const observer = new MutationObserver(function (mutations_list) { mutations_list.forEach(function (mutation) { mutation.addedNodes.forEach(function (added_node) { chrome.storage.local.get(["DarkMode"], function (result) { DarkMode = result.DarkMode; if (added_node.classList.contains("notice")) { var hex = added_node.style.cssText.split(" ")[1]; var threshold = GetThresholdofHex(hex); if (DarkMode && threshold < 100) { added_node.style.cssText = "--color: undefined;"; } } }); }); }); }); observer.observe(notice, { subtree: true, childList: true, }); } function tryLoad() { waitForElm(".login").then(() => { finishLoad(); }); waitForElm(".day-container").then(() => { finishLoad(); }); waitForElm("[data-key=welcome]").then((elm) => { elm.classList.remove("active"); }); waitForElm(".code").then((elm) => { if (!elm.innerText.includes("BetterSEQTA")) LoadPageElements(); }); // Waits for page to call on load, run scripts document.addEventListener( "load", function () { CheckiFrameItems(); }, true, ); } function ChangeMenuItemPositions(storage) { let menuorder = storage; var menuList = document.querySelector("#menu").firstChild.childNodes; let listorder = []; for (let i = 0; i < menuList.length; i++) { let a = menuorder.indexOf(menuList[i].dataset.key); listorder.push(a); } var newArr = []; for (var i = 0; i < listorder.length; i++) { newArr[listorder[i]] = menuList[i]; } let listItemsDOM = document.getElementById("menu").firstChild; for (let i = 0; i < newArr.length; i++) { const element = newArr[i]; if (element) { element.setAttribute("data-checked", "true"); listItemsDOM.appendChild(element); } } } async function ObserveMenuItemPosition() { chrome.storage.local.get(null, function (result) { let menuorder = result.menuorder; if (menuorder && result.onoff) { const observer = new MutationObserver(function (mutations_list) { mutations_list.forEach(function (mutation) { mutation.addedNodes.forEach(function (added_node) { if (!added_node?.dataset?.checked && !MenuOptionsOpen) { if (MenuitemSVGKey[added_node?.dataset?.key]) { ReplaceMenuSVG( added_node, MenuitemSVGKey[added_node.dataset.key], ); } ChangeMenuItemPositions(menuorder); } }); }); }); observer.observe(document.querySelector("#menu").firstChild, { subtree: true, childList: true, }); } }); } function AppendElementsToDisabledPage() { AddBetterSEQTAElements(false); let settingsStyle = document.createElement("style"); settingsStyle.innerText = ` .addedButton { position: absolute !important; right: 50px; width: 35px; height: 35px; padding: 6px !important; overflow: unset !important; border-radius: 50%; margin: 7px !important; cursor: pointer; color: white !important; } .addedButton svg { margin: 6px; } .outside-container { top: 48px !important; } `; document.head.append(settingsStyle); } function lightenAndPaleColor( hexColor, lightenFactor = 0.75, paleFactor = 0.55, ) { // Convert a RGB value to HSL function rgbToHsl(r, g, b) { (r /= 255), (g /= 255), (b /= 255); let max = Math.max(r, g, b), min = Math.min(r, g, b); let h, s, l = (max + min) / 2; if (max === min) { h = s = 0; } else { let d = max - min; s = l > 0.5 ? d / (2 - max - min) : d / (max + min); switch (max) { case r: h = (g - b) / d + (g < b ? 6 : 0); break; case g: h = (b - r) / d + 2; break; case b: h = (r - g) / d + 4; break; } h /= 6; } return [h, s, l]; } // Convert an HSL value to RGB function hslToRgb(h, s, l) { function hue2rgb(p, q, t) { if (t < 0) t += 1; if (t > 1) t -= 1; if (t < 1 / 6) return p + (q - p) * 6 * t; if (t < 1 / 2) return q; if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6; return p; } let r, g, b; if (s === 0) { r = g = b = l; } else { let q = l < 0.5 ? l * (1 + s) : l + s - l * s; let p = 2 * l - q; r = hue2rgb(p, q, h + 1 / 3); g = hue2rgb(p, q, h); b = hue2rgb(p, q, h - 1 / 3); } return [r * 255, g * 255, b * 255]; } // Extract the red, green, and blue components from hex let r = parseInt(hexColor.substr(1, 2), 16); let g = parseInt(hexColor.substr(3, 2), 16); let b = parseInt(hexColor.substr(5, 2), 16); // Convert RGB to HSL let [h, s, l] = rgbToHsl(r, g, b); // Adjust saturation and lightness s -= s * paleFactor; l += (1 - l) * lightenFactor; // Convert HSL back to RGB [r, g, b] = hslToRgb(h, s, l); // Convert RGB to hex r = Math.round(r).toString(16).padStart(2, "0"); g = Math.round(g).toString(16).padStart(2, "0"); b = Math.round(b).toString(16).padStart(2, "0"); return "#" + r + g + b; } function ColorLuminance(hex, lum) { // validate hex string hex = String(hex).replace(/[^0-9a-f]/gi, ""); if (hex.length < 6) { hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2]; } lum = lum || 0; // convert to decimal and change luminosity var rgb = "#", c, i; for (i = 0; i < 3; i++) { c = parseInt(hex.substr(i * 2, 2), 16); c = Math.round(Math.min(Math.max(0, c + c * lum), 255)).toString(16); rgb += ("00" + c).substring(c.length); } return rgb; } chrome.storage.onChanged.addListener(function (changes) { if (changes.selectedColor) { try { chrome.storage.local.get(["DarkMode"], function (result) { if (!result.DarkMode) { document.documentElement.style.setProperty( "--better-pale", lightenAndPaleColor(changes.selectedColor.newValue), ); } }); } catch (err) { console.log(err); } let rbg = GetThresholdofHex(changes.selectedColor.newValue); if (rbg > 210) { document.documentElement.style.setProperty("--text-color", "black"); document.documentElement.style.setProperty( "--betterseqta-logo", `url(${chrome.runtime.getURL("icons/betterseqta-dark-full.png")})`, ); } else { document.documentElement.style.setProperty("--text-color", "white"); document.documentElement.style.setProperty( "--betterseqta-logo", `url(${chrome.runtime.getURL("icons/betterseqta-light-full.png")})`, ); } document.documentElement.style.setProperty( "--better-main", changes.selectedColor.newValue, ); // document.documentElement.style.setProperty('--better-sub', ColorLuminance(changes.selectedColor.newValue, -0.15)); if (changes.selectedColor.newValue == "#ffffff") { document.documentElement.style.setProperty("--better-light", "#b7b7b7"); } else { document.documentElement.style.setProperty( "--better-light", ColorLuminance(changes.selectedColor.newValue, 0.99), ); } } if (changes?.customshortcuts?.newValue) { if (changes.customshortcuts.oldValue.length > 0) { CreateCustomShortcutDiv( changes.customshortcuts.newValue[ changes.customshortcuts.oldValue.length ], ); } else { CreateCustomShortcutDiv(changes.customshortcuts.newValue[0]); } } }); var PageLoaded = false; async function CheckLoadOnPeriods() { if (!PageLoaded) { await delay(1000); var code = document.getElementsByClassName("code")[0]; if (code && !UserInitalCode) { LoadPageElements(); finishLoad(); PageLoaded = true; } if (!code) { CheckLoadOnPeriods(); } } } function RunFunctionOnTrue(storedSetting) { DarkMode = storedSetting.DarkMode; // If the option is 'on', open BetterSEQTA if (typeof storedSetting.onoff == "undefined") { chrome.runtime.sendMessage({ type: "setDefaultStorage" }); } if (storedSetting.onoff) { console.log("[BetterSEQTA+] Enabled"); // Injecting CSS File to the webpage to overwrite SEQTA's default CSS var cssFile = chrome.runtime.getURL("inject/injected.css"); var fileref = document.createElement("link"); fileref.setAttribute("rel", "stylesheet"); fileref.setAttribute("type", "text/css"); fileref.setAttribute("href", cssFile); document.head.appendChild(fileref); document.getElementsByTagName("html")[0].appendChild(fileref); // Injecting custom icons font file const fontURL = chrome.runtime.getURL("fonts/IconFamily.woff"); const style = document.createElement("style"); style.setAttribute("type", "text/css"); style.innerHTML = ` @font-face { font-family: 'IconFamily'; src: url('${fontURL}') format('woff'); font-weight: normal; font-style: normal; }`; document.head.appendChild(style); document.documentElement.style.setProperty("--better-sub", "#161616"); document.documentElement.style.setProperty( "--better-alert-highlight", "#c61851", ); if (storedSetting.DarkMode) { document.documentElement.style.setProperty( "--background-primary", "#232323", ); document.documentElement.style.setProperty( "--background-secondary", "#1a1a1a", ); document.documentElement.style.setProperty("--text-primary", "white"); } else { try { document.documentElement.style.setProperty( "--better-pale", lightenAndPaleColor(storedSetting.selectedColor), ); } catch (err) { console.log(err); } document.documentElement.style.setProperty( "--background-primary", "#ffffff", ); document.documentElement.style.setProperty( "--background-secondary", "#e5e7eb", ); document.documentElement.style.setProperty("--text-primary", "black"); } document.querySelector("link[rel*=\"icon\"]").href = chrome.runtime.getURL("icons/icon-48.png"); let rbg = GetThresholdofHex(storedSetting.selectedColor); if (rbg > 210) { document.documentElement.style.setProperty("--text-color", "black"); document.documentElement.style.setProperty( "--betterseqta-logo", `url(${chrome.runtime.getURL("icons/betterseqta-dark-full.png")})`, ); } else { document.documentElement.style.setProperty("--text-color", "white"); document.documentElement.style.setProperty( "--betterseqta-logo", `url(${chrome.runtime.getURL("icons/betterseqta-light-full.png")})`, ); } document.documentElement.style.setProperty( "--better-main", storedSetting.selectedColor, ); // document.documentElement.style.setProperty('--better-sub', ColorLuminance(storedSetting.selectedColor, -0.15)); if (storedSetting.selectedColor == "#ffffff") { document.documentElement.style.setProperty("--better-light", "#b7b7b7"); } else { document.documentElement.style.setProperty( "--better-light", ColorLuminance(storedSetting.selectedColor, 0.95), ); } ApplyCSSToHiddenMenuItems(); loading(); CheckLoadOnPeriods(); if (!isChrome || isChrome == "undefined") { tryLoad(); } window.addEventListener("load", function () { tryLoad(); }); } else { if (!isChrome || isChrome == "undefined") { waitForElm(".code").then(() => { AppendElementsToDisabledPage(); }); } window.addEventListener("load", function () { waitForElm(".code").then(() => { AppendElementsToDisabledPage(); }); }); } } async function CheckForMenuList() { if (!MenuItemMutation) { try { if (document.getElementById("menu").firstChild) { ObserveMenuItemPosition(); MenuItemMutation = true; } } catch (error) { return; } } } var MenuItemMutation = false; var NonSEQTAPage = false; var IsSEQTAPage = false; document.addEventListener( "load", function () { CheckForMenuList(); if ( document.childNodes[1].textContent?.includes( "Copyright (c) SEQTA Software", ) && document.title.includes("SEQTA Learn") && !IsSEQTAPage ) { IsSEQTAPage = true; console.log("[BetterSEQTA+] Verified SEQTA Page"); var link = document.createElement("link"); link.href = chrome.runtime.getURL("inject/documentload.css"); link.type = "text/css"; link.rel = "stylesheet"; document.getElementsByTagName("html")[0].appendChild(link); chrome.storage.local.get(null, function (items) { RunFunctionOnTrue(items); }); } if ( !document.childNodes[1].textContent?.includes("SEQTA") && !NonSEQTAPage ) { NonSEQTAPage = true; } }, true, ); function RunExtensionSettingsJS() { const whatsnewsettings = document.getElementById("whatsnewsettings"); whatsnewsettings.addEventListener("click", function () { if (!WhatsNewOpen) { WhatsNewOpen = true; OpenWhatsNewPopup(); } }); const onoffselection = document.querySelector("#onoff"); const notificationcollector = document.querySelector("#notification"); const lessonalert = document.querySelector("#lessonalert"); const aboutsection = document.querySelector("#aboutsection"); const shortcutsection = document.querySelector("#shortcutsection"); const miscsection = document.querySelector("#miscsection"); //const mainpage = document.querySelector("#mainpage"); const colorpicker = document.querySelector("#colorpicker"); const animatedbk = document.querySelector("#animatedbk"); const customshortcutbutton = document.getElementsByClassName( "custom-shortcuts-button", )[0]; const customshortcutdiv = document.getElementsByClassName( "custom-shortcuts-container", )[0]; const customshortcutsubmit = document.getElementsByClassName( "custom-shortcuts-submit", )[0]; const customshortcutinputname = document.querySelector("#shortcutname"); const customshortcutinputurl = document.querySelector("#shortcuturl"); const shortcutmenuitemselection = document.getElementsByClassName("menushortcut")[0]; const applybutton = document.querySelector("#applychanges"); const navbuttons = document.getElementsByClassName("navitem"); const menupages = document.getElementsByClassName("menu-page"); const allinputs = document.getElementsByTagName("input"); const menupage = document.querySelector("#menupage"); const shortcutpage = document.querySelector("#shortcutpage"); const miscpage = document.querySelector("#miscpage"); var shortcutbuttons = document.getElementsByClassName("shortcutitem"); var validURL = false; var validName = false; const github = document.getElementById("github"); function openGithub() { chrome.runtime.sendMessage({ type: "githubTab" }); } function resetActive() { for (let i = 0; i < navbuttons.length; i++) { navbuttons[i].classList.remove("activenav"); } for (let i = 0; i < menupages.length; i++) { menupages[i].classList.add("hiddenmenu"); } } function FindSEQTATab() { chrome.runtime.sendMessage({ type: "reloadTabs" }); } /* Store the currently selected settings using chrome.storage.local. */ function storeSettings() { chrome.storage.local.set({ onoff: onoffselection.checked }, function () { FindSEQTATab(); }); } function storeNotificationSettings() { chrome.storage.local.set({ notificationcollector: notificationcollector.checked, }); chrome.storage.local.set({ lessonalert: lessonalert.checked }); chrome.storage.local.set({ animatedbk: animatedbk.checked }); } function StoreAllSettings() { chrome.storage.local.get(["shortcuts"], function (result) { var shortcuts = Object.values(result)[0]; for (var i = 0; i < shortcutbuttons.length; i++) { shortcuts[i].enabled = shortcutbuttons[i].checked; } chrome.storage.local.set({ shortcuts: shortcuts }); }); FindSEQTATab(); } /* Update the options UI with the settings values retrieved from storage, or the default settings if the stored settings are empty. */ function updateUI(restoredSettings) { if (typeof restoredSettings.onoff == "undefined") { chrome.runtime.sendMessage({ type: "setDefaultStorage" }); chrome.storage.local.get(null, function (result) { updateUI(result); }); } else { onoffselection.checked = restoredSettings.onoff; notificationcollector.checked = restoredSettings.notificationcollector; lessonalert.checked = restoredSettings.lessonalert; animatedbk.checked = restoredSettings.animatedbk; chrome.storage.local.get(["shortcuts"], function (result) { var shortcuts = Object.values(result)[0]; for (var i = 0; i < shortcutbuttons.length; i++) { shortcutbuttons[i].checked = shortcuts[i].enabled; } chrome.storage.local.set({ shortcuts: shortcuts }); }); } } function CreateShortcutDiv(name) { let div = stringToHTML(` `).firstChild; shortcutmenuitemselection.append(div); const deletebutton = document.getElementById(`delete-${name}`); deletebutton.addEventListener("click", function () { DeleteCustomShortcut(name); applybutton.style.left = "4px"; }); } function AddCustomShortcuts() { chrome.storage.local.get(["customshortcuts"], function (result) { var customshortcuts = Object.values(result)[0]; for (let i = 0; i < customshortcuts.length; i++) { const element = customshortcuts[i]; CreateShortcutDiv(element.name); } }); } function DeleteCustomShortcut(name) { let item = document.querySelector(`[data-customshortcut="${name}"]`); item.remove(); chrome.storage.local.get(["customshortcuts"], function (result) { var customshortcuts = Object.values(result)[0]; for (let i = 0; i < customshortcuts.length; i++) { if (customshortcuts[i].name == name) { customshortcuts.splice(i, 1); } } chrome.storage.local.set({ customshortcuts: customshortcuts }); }); } function CustomShortcutMenu() { customshortcutinputname.value = ""; customshortcutinputurl.value = ""; validURL = false; validName = false; customshortcutsubmit.classList.remove("customshortcut-submit-valid"); if ( customshortcutdiv.classList.contains("custom-shortcuts-container-shown") ) { customshortcutdiv.classList.remove("custom-shortcuts-container-shown"); } else { customshortcutdiv.classList.add("custom-shortcuts-container-shown"); } } function CreateCustomShortcut() { const shortcutname = customshortcutinputname.value; var shortcuturl = customshortcutinputurl.value; if (!shortcuturl.includes("http")) { shortcuturl = "https://" + shortcuturl; } chrome.storage.local.get(["customshortcuts"], function (result) { var customshortcuts = Object.values(result)[0]; customshortcuts.push({ name: shortcutname, url: shortcuturl, icon: shortcutname[0].toUpperCase(), }); chrome.storage.local.set({ customshortcuts: customshortcuts }); }); CreateShortcutDiv(shortcutname); document.getElementsByClassName("shortcut-container")[0].style.display = "block"; } chrome.storage.local.get(null, function (result) { document.getElementsByClassName("clr-field")[0].style.color = result.selectedColor; colorpicker.value = result.selectedColor; updateUI(result); }); github.addEventListener("click", openGithub); aboutsection.addEventListener("click", () => { resetActive(); aboutsection.classList.add("activenav"); menupage.classList.remove("hiddenmenu"); }); shortcutsection.addEventListener("click", () => { resetActive(); shortcutsection.classList.add("activenav"); shortcutpage.classList.remove("hiddenmenu"); }); miscsection.addEventListener("click", () => { resetActive(); miscsection.classList.add("activenav"); miscpage.classList.remove("hiddenmenu"); }); customshortcutbutton.addEventListener("click", () => { CustomShortcutMenu(); }); customshortcutsubmit.addEventListener("click", () => { if (validName && validURL) { CreateCustomShortcut(); CustomShortcutMenu(); } }); var sameName = false; customshortcutinputname.addEventListener("input", function () { sameName = false; chrome.storage.local.get(["customshortcuts"], function (result) { var customshortcuts = Object.values(result)[0]; for (let i = 0; i < customshortcuts.length; i++) { if (customshortcuts[i].name == customshortcutinputname.value) { sameName = true; } } if ( customshortcutinputname.value.length > 0 && customshortcutinputname.value.length < 22 && !sameName ) { validName = true; } else { validName = false; } if (validName && validURL) { customshortcutsubmit.classList.add("customshortcut-submit-valid"); } else { customshortcutsubmit.classList.remove("customshortcut-submit-valid"); } }); }); customshortcutinputurl.addEventListener("input", function () { if ( customshortcutinputurl.value.length > 0 && customshortcutinputurl.value.includes(".") ) { validURL = true; } else { validURL = false; } if (validName && validURL) { customshortcutsubmit.classList.add("customshortcut-submit-valid"); } else { customshortcutsubmit.classList.remove("customshortcut-submit-valid"); } }); AddCustomShortcuts(); onoffselection.addEventListener("change", storeSettings); notificationcollector.addEventListener("change", storeNotificationSettings); lessonalert.addEventListener("change", storeNotificationSettings); animatedbk.addEventListener("change", storeNotificationSettings); for (let i = 0; i < allinputs.length; i++) { if ( allinputs[i].id != "colorpicker" && allinputs[i].id != "shortcuturl" && allinputs[i].id != "shortcutname" ) { allinputs[i].addEventListener("change", () => { applybutton.style.left = "4px"; }); } } applybutton.addEventListener("click", () => { StoreAllSettings(); applybutton.style.left = "-150px"; }); colorpicker.addEventListener("input", function () { var colorPreview = document.querySelector("#clr-color-preview"); if (colorPreview.style.color) { var hex = colorPreview.style.color.split("(")[1].split(")")[0]; hex = hex.split(","); var b = hex.map(function (x) { //For each array element x = parseInt(x).toString(16); //Convert to a base16 string return x.length == 1 ? "0" + x : x; //Add zero if we get only one character }); b = "#" + b.join(""); chrome.storage.local.set({ selectedColor: b }); } }); } function CallExtensionSettings() { // Injecting CSS File to the webpage to overwrite iFrame default CSS var cssFile = chrome.runtime.getURL("popup/info.css"); var fileref = document.createElement("link"); fileref.setAttribute("rel", "stylesheet"); fileref.setAttribute("type", "text/css"); fileref.setAttribute("href", cssFile); document.head.append(fileref); var jsFile = chrome.runtime.getURL("popup/coloris.js"); fileref = document.createElement("script"); fileref.setAttribute("src", jsFile); document.head.append(fileref); cssFile = chrome.runtime.getURL("popup/coloris.css"); fileref = document.createElement("link"); fileref.setAttribute("rel", "stylesheet"); fileref.setAttribute("type", "text/css"); fileref.setAttribute("href", cssFile); document.head.append(fileref); let Settings = stringToHTML( String.raw` `); document.body.append(Settings.firstChild); var container = document.getElementById("container"); var extensionsettings = document.getElementById("ExtensionPopup"); container.onclick = function () { if (!SettingsClicked) { extensionsettings.classList.add("hidden"); } SettingsClicked = false; }; } function ApplyDraggableFunctions() { var listItens = document.querySelectorAll(".draggable"); [].forEach.call(listItens, function (item) { addEventsDragAndDrop(item); }); } var dragSrcEl; function dragStart(e) { this.style.opacity = "0.4"; dragSrcEl = this; e.dataTransfer.effectAllowed = "move"; e.dataTransfer.setData("text/html", this.innerHTML); } function dragEnter() { this.classList.add("over"); } function dragLeave(e) { e.stopPropagation(); this.classList.remove("over"); } function dragOver(e) { e.preventDefault(); e.dataTransfer.dropEffect = "move"; return false; } function dragDrop() { if (dragSrcEl != this) { const parentA = this.parentNode; const siblingA = this.nextSibling === dragSrcEl ? this : this.nextSibling; // Move `this` to before the `dragSrcEl` dragSrcEl.parentNode.insertBefore(this, dragSrcEl); // Move `dragSrcEl` to before the sibling of `this` parentA.insertBefore(dragSrcEl, siblingA); // Save position of all menu items let children = parentA.childNodes; // console.log(children) let listorder = []; for (let i = 0; i < children.length; i++) { const elm = children[i]; listorder.push(elm.dataset.key); } chrome.storage.local.set({ menuorder: listorder }); } return false; } function dragEnd() { var listItens = document.querySelectorAll(".draggable"); [].forEach.call(listItens, function (item) { item.classList.remove("over"); }); this.style.opacity = "1"; } function addEventsDragAndDrop(el) { el.addEventListener("dragstart", dragStart, false); el.addEventListener("dragenter", dragEnter, false); el.addEventListener("dragover", dragOver, false); el.addEventListener("dragleave", dragLeave, false); el.addEventListener("drop", dragDrop, false); el.addEventListener("dragend", dragEnd, false); } function cloneAttributes(target, source) { [...source.attributes].forEach((attr) => { target.setAttribute(attr.nodeName, attr.nodeValue); }); } function OpenMenuOptions() { chrome.storage.local.get(null, function (result) { var container = document.getElementById("container"); var menu = document.getElementById("menu"); if (result.defaultmenuorder.length == "0") { let childnodes = menu.firstChild.childNodes; let newdefaultmenuorder = []; for (let i = 0; i < childnodes.length; i++) { const element = childnodes[i]; newdefaultmenuorder.push(element.dataset.key); chrome.storage.local.set({ defaultmenuorder: newdefaultmenuorder }); } } let childnodes = menu.firstChild.childNodes; if (result.defaultmenuorder.length != childnodes.length) { for (let i = 0; i < childnodes.length; i++) { const element = childnodes[i]; if (!result.defaultmenuorder.indexOf(element.dataset.key)) { let newdefaultmenuorder = result.defaultmenuorder; newdefaultmenuorder.push(element.dataset.key); chrome.storage.local.set({ defaultmenuorder: newdefaultmenuorder }); } } } MenuOptionsOpen = true; let cover = document.createElement("div"); cover.classList.add("notMenuCover"); menu.style.zIndex = "20"; menu.style.setProperty("--menuHidden", "flex"); container.append(cover); let menusettings = document.createElement("div"); menusettings.classList.add("editmenuoption-container"); let defaultbutton = document.createElement("div"); defaultbutton.classList.add("editmenuoption"); defaultbutton.innerText = "Restore Default"; defaultbutton.id = "restoredefaultoption"; let savebutton = document.createElement("div"); savebutton.classList.add("editmenuoption"); savebutton.innerText = "Save"; savebutton.id = "restoredefaultoption"; menusettings.appendChild(defaultbutton); menusettings.appendChild(savebutton); menu.appendChild(menusettings); let ListItems = menu.firstChild.childNodes; for (let i = 0; i < ListItems.length; i++) { const element = ListItems[i]; element.classList.add("draggable"); element.setAttribute("draggable", true); if (element.classList.contains("hasChildren")) { element.classList.remove("active"); menu.firstChild.classList.remove("noscroll"); } let MenuItemToggle = stringToHTML( `
    `, ).firstChild; element.append(MenuItemToggle); if (!element.dataset.betterseqta) { var a = document.createElement("section"); a.innerHTML = element.innerHTML; cloneAttributes(a, element); menu.firstChild.insertBefore(a, element); element.remove(); } } if (Object.keys(result.menuitems).length == 0) { menubuttons = menu.firstChild.childNodes; var menuItems = {}; for (var i = 0; i < menubuttons.length; i++) { var id = menubuttons[i].dataset.key; const element = {}; element.toggle = true; menuItems[id] = element; } chrome.storage.local.set({ menuitems: menuItems }); } var menubuttons = document.getElementsByClassName("menuitem"); chrome.storage.local.get(["menuitems"], function (result) { var menuItems = result.menuitems; let buttons = document.getElementsByClassName("menuitem"); for (var i = 0; i < buttons.length; i++) { var id = buttons[i].id; if (menuItems[id]) { buttons[i].checked = menuItems[id].toggle; } if (!menuItems[id]) { buttons[i].checked = true; } } }); ApplyDraggableFunctions(); function StoreMenuSettings() { chrome.storage.local.get(["menuitems"], function () { var menuItems = {}; menubuttons = menu.firstChild.childNodes; let button = document.getElementsByClassName("menuitem"); for (var i = 0; i < menubuttons.length; i++) { var id = menubuttons[i].dataset.key; const element = {}; element.toggle = button[i].checked; menuItems[id] = element; } chrome.storage.local.set({ menuitems: menuItems }); }); } function changeDisplayProperty(element) { if (!element.checked) { element.parentNode.parentNode.style.display = "var(--menuHidden)"; } if (element.checked) { element.parentNode.parentNode.style.setProperty( "display", "flex", "important", ); } } for (let i = 0; i < menubuttons.length; i++) { const element = menubuttons[i]; element.addEventListener("change", () => { StoreMenuSettings(); changeDisplayProperty(element); }); } function closeAll() { ListItems = menu.firstChild.childNodes; menusettings.remove(); cover.remove(); MenuOptionsOpen = false; menu.style.setProperty("--menuHidden", "none"); for (let i = 0; i < ListItems.length; i++) { const element = ListItems[i]; element.classList.remove("draggable"); element.setAttribute("draggable", false); if (!element.dataset.betterseqta) { var a = document.createElement("li"); a.innerHTML = element.innerHTML; cloneAttributes(a, element); menu.firstChild.insertBefore(a, element); element.remove(); } } let switches = menu.querySelectorAll(".onoffswitch"); for (let i = 0; i < switches.length; i++) { switches[i].remove(); } StoreMenuSettings(); } cover.addEventListener("click", closeAll); savebutton.addEventListener("click", closeAll); defaultbutton.addEventListener("click", function () { chrome.storage.local.get(null, function (response) { const options = response.defaultmenuorder; chrome.storage.local.set({ menuorder: options }); ChangeMenuItemPositions(options); for (let i = 0; i < menubuttons.length; i++) { const element = menubuttons[i]; element.checked = true; element.parentNode.parentNode.style.setProperty( "display", "flex", "important", ); } StoreMenuSettings(); }); }); }); } function ReplaceMenuSVG(element, svg) { let item = element.firstChild; item.firstChild.remove(); if (element.dataset.key == "messages") { element.firstChild.innerText = "Direct Messages"; } let newsvg = stringToHTML(svg).firstChild; item.insertBefore(newsvg, item.firstChild); } function AddBetterSEQTAElements(toggle) { var code = document.getElementsByClassName("code")[0]; // Replaces students code with the version of BetterSEQTA if (code != null) { if (!code.innerHTML.includes("BetterSEQTA")) { UserInitalCode = code.innerText; code.innerText = `BetterSEQTA v${chrome.runtime.getManifest().version}`; code.setAttribute("data-hover", "Click for user code"); code.addEventListener("click", function () { var code = document.getElementsByClassName("code")[0]; if (code.innerText.includes("BetterSEQTA")) { code.innerText = UserInitalCode; code.setAttribute("data-hover", "Click for BetterSEQTA version"); } else { code.innerText = `BetterSEQTA v${ chrome.runtime.getManifest().version }`; code.setAttribute("data-hover", "Click for user code"); } }); if (toggle) { // Creates Home menu button and appends it as the first child of the list chrome.storage.local.get(["animatedbk"], function (result) { if (result.animatedbk) { CreateBackground(); } else { document.getElementById("container").style.background = "var(--background-secondary)"; } }); // Load darkmode state chrome.storage.local.get(["DarkMode"], function (result) { DarkMode = result.DarkMode; }); var titlebar = document.createElement("div"); titlebar.classList.add("titlebar"); let container = document.getElementById("content"); container.append(titlebar); var NewButtonStr = "
  • "; var NewButton = stringToHTML(NewButtonStr); var menu = document.getElementById("menu"); var List = menu.firstChild; List.insertBefore(NewButton.firstChild, List.firstChild); 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, }), }) .then((result) => result.json()) .then((response) => { let info = response.payload; var titlebar = document.getElementsByClassName("titlebar")[0]; titlebar.append( stringToHTML( "
    ", ).firstChild, ); var userinfostr = `

    ${info.userDesc}

    ${UserInitalCode}

    `; var userinfo = stringToHTML(userinfostr).firstChild; titlebar.append(userinfo); var logoutbutton = document.getElementsByClassName("logout")[0]; var userInfosvgdiv = document.getElementById("logouttooltip"); userInfosvgdiv.appendChild(logoutbutton); fetch(`${location.origin}/seqta/student/load/message/people`, { method: "POST", headers: { "Content-Type": "application/json; charset=utf-8", }, body: JSON.stringify({ mode: "student" }), }) .then((result) => result.json()) .then((response) => { let students = response.payload; var index = students.findIndex(function (person) { return ( person.firstname == info.userDesc.split(" ")[0] && person.surname == info.userDesc.split(" ")[1] ); }); let houseelement = document.getElementsByClassName("userInfohouse")[0]; if (students[index]?.house) { houseelement.style.background = students[index].house_colour; try { let colorresult = GetThresholdofHex( students[index]?.house_colour, ); if (colorresult > 300) { houseelement.style.color = "black"; } else { houseelement.style.color = "white"; } houseelement.innerText = students[index].year + students[index].house; } catch(e) { console.log(e); } } else { houseelement.innerText = students[index].year; } }); }); var NewsButtonStr = "
  • "; var NewsButton = stringToHTML(NewsButtonStr); List.appendChild(NewsButton.firstChild); editmenu = document.createElement("div"); editmenu.classList.add("editmenu"); let svg = stringToHTML( "", ); editmenu.append(svg.firstChild); menu.appendChild(editmenu); let a = document.createElement("div"); a.classList.add("icon-cover"); a.id = "icon-cover"; menu.appendChild(a); var editmenu = document.querySelector("#editmenu"); editmenu.addEventListener("click", function () { if (!MenuOptionsOpen) { OpenMenuOptions(); } }); var menuCover = document.querySelector("#icon-cover"); menuCover.addEventListener("click", function () { location.href = "../#?page=/home"; SendHomePage(); document .getElementById("menu") .firstChild.classList.remove("noscroll"); }); // Creates the home container when the menu button is pressed var homebutton = document.getElementById("homebutton"); homebutton.addEventListener("click", function () { if (!MenuOptionsOpen) { SendHomePage(); } }); // Creates the news container when the menu button is pressed var newsbutton = document.getElementById("newsbutton"); newsbutton.addEventListener("click", function () { if (!MenuOptionsOpen) { SendNewsPage(); } }); } CallExtensionSettings(); RunExtensionSettingsJS(); if (toggle) { // Creates settings and dashboard buttons next to alerts var SettingsButton = stringToHTML( "", ); var ContentDiv = document.getElementById("content"); ContentDiv.append(SettingsButton.firstChild); chrome.storage.local.get(["DarkMode"], function (result) { DarkMode = result.DarkMode; let tooltipstring = GetLightDarkModeString(DarkMode); var LightDarkModeButton = stringToHTML( String.raw``, ); ContentDiv.append(LightDarkModeButton.firstChild); let LightDarkModeElement = document.getElementById("LightDarkModeButton"); if (DarkMode) { LightDarkModeElement.firstChild.innerHTML = ""; document.documentElement.style.removeProperty("--better-pale"); } else { LightDarkModeElement.firstChild.innerHTML = ""; try { chrome.storage.local.get(null, function (result) { document.documentElement.style.setProperty( "--better-pale", lightenAndPaleColor(result.selectedColor), ); }); } catch (err) { console.log(err); } } let darklightText = document.getElementById("darklighttooliptext"); LightDarkModeElement.addEventListener("click", function () { chrome.storage.local.get(["DarkMode"], function (result) { DarkMode = result.DarkMode; let alliframes = document.getElementsByTagName("iframe"); let fileref = GetiFrameCSSElement(); if (!DarkMode) { document.documentElement.style.setProperty( "--background-primary", "#232323", ); document.documentElement.style.setProperty( "--background-secondary", "#1a1a1a", ); document.documentElement.style.setProperty( "--text-primary", "white", ); document.documentElement.style.removeProperty("--better-pale"); LightDarkModeElement.firstChild.innerHTML = ""; for (let i = 0; i < alliframes.length; i++) { const element = alliframes[i]; element.contentDocument.documentElement.childNodes[1].style.color = "white"; element.contentDocument.documentElement.firstChild.appendChild( fileref, ); } } else { document.documentElement.style.setProperty( "--background-primary", "#ffffff", ); document.documentElement.style.setProperty( "--background-secondary", "#e5e7eb", ); document.documentElement.style.setProperty( "--text-primary", "black", ); try { chrome.storage.local.get(null, function (result) { document.documentElement.style.setProperty( "--better-pale", lightenAndPaleColor(result.selectedColor), ); }); } catch (err) { console.log(err); } LightDarkModeElement.firstChild.innerHTML = ""; for (let i = 0; i < alliframes.length; i++) { const element = alliframes[i]; element.contentDocument.documentElement.childNodes[1].style.color = "black"; element.contentDocument.documentElement.firstChild.lastChild.remove(); } } tooltipstring = GetLightDarkModeString(!result.DarkMode); darklightText.innerText = tooltipstring; chrome.storage.local.set({ DarkMode: !result.DarkMode }); }); }); }); } else { // Creates settings and dashboard buttons next to alerts SettingsButton = stringToHTML( "", ); ContentDiv = document.getElementById("content"); ContentDiv.append(SettingsButton.firstChild); } var AddedSettings = document.getElementById("AddedSettings"); var extensionsettings = document.getElementById("ExtensionPopup"); AddedSettings.addEventListener("click", function () { extensionsettings.classList.toggle("hidden"); SettingsClicked = true; }); } } } let tooltipstring; function GetLightDarkModeString(darkmodetoggle) { if (darkmodetoggle) { tooltipstring = "Switch to light theme"; } else { tooltipstring = "Switch to dark theme"; } return tooltipstring; } function CheckCurrentLesson(lesson, num) { var startTime = lesson.from; var endTime = lesson.until; // Gets current time let currentDate = new Date(); // Takes start time of current lesson and makes it into a Date function for comparison let startDate = new Date(currentDate.getTime()); startDate.setHours(startTime.split(":")[0]); startDate.setMinutes(startTime.split(":")[1]); startDate.setSeconds("00"); // Takes end time of current lesson and makes it into a Date function for comparison let endDate = new Date(currentDate.getTime()); endDate.setHours(endTime.split(":")[0]); endDate.setMinutes(endTime.split(":")[1]); endDate.setSeconds("00"); // Gets the difference between the start time and current time var difference = startDate.getTime() - currentDate.getTime(); // Converts the difference into minutes var minutes = Math.floor(difference / 1000 / 60); // Checks if current time is between the start time and end time of current tested lesson let valid = startDate < currentDate && endDate > currentDate; let id = lesson.code + num; const date = new Date(); var elementA = document.getElementById(id); if (!elementA) { clearInterval(LessonInterval); } else { if ( currentSelectedDate.toLocaleDateString("en-au") == date.toLocaleDateString("en-au") ) { if (valid) { // Apply the activelesson class to increase the box-shadow of current lesson elementA.classList.add("activelesson"); } else { // Removes the activelesson class to ensure only the active lesson have the class if (elementA != null) { elementA.classList.remove("activelesson"); } } } } // If 5 minutes before the start of another lesson: if (minutes == 5) { chrome.storage.local.get("lessonalert", function (result) { if (result.lessonalert) { // Checks if notifications are supported if (!window.Notification) { console.log("Browser does not support notifications."); } else { // check if permission is already granted if (Notification.permission === "granted") { // show notification here } else { // request permission from user Notification.requestPermission() .then(function (p) { if (p === "granted") { // show notification here /* notify = new Notification("Next Lesson in 5 Minutes:", { body: "Subject: " + lesson.description + " \nRoom: " + lesson.room + " \nTeacher: " + lesson.staff, }); */ } else { console.log("User blocked notifications."); } }) .catch(function (err) { console.error(err); }); } } } }); } } function hexToRGB(hex) { try { var r = parseInt(hex.slice(1, 3), 16), g = parseInt(hex.slice(3, 5), 16), b = parseInt(hex.slice(5, 7), 16); return { r: r, g: g, b: b }; } catch { // do nothing becuase this functoin is a bit broken right now (feel free to fix it!) } } function GetThresholdofHex(hex) { var rgb = hexToRGB(hex); return Math.sqrt(rgb.r ** 2 + rgb.g ** 2 + rgb.b ** 2); } function CheckCurrentLessonAll(lessons) { // Checks each lesson and sets an interval to run every 60 seconds to continue updating LessonInterval = setInterval( function () { for (let i = 0; i < lessons.length; i++) { CheckCurrentLesson(lessons[i], i + 1); } }.bind(lessons), 60000, ); } function MakeLessonDiv(lesson, num) { let assessmentstring = ""; var lessonstring = `

    ${lesson?.description ?? "Unknown"}

    ${ lesson?.staff ?? "Unknown" }

    ${lesson?.room ?? "Unknown"}

    ${ lesson?.from ?? "Unknown" } - ${lesson?.until ?? "Unknown"}

    ${ lesson?.attendanceTitle ?? "Unknown" }
    `; if (lesson.programmeID != 0) { lessonstring += `
    ${assessmentsicon}
    ${coursesicon}
    `; } if (lesson.assessments.length > 0) { for (let i = 0; i < lesson.assessments.length; i++) { const element = lesson.assessments[i]; assessmentstring += `

    ${element.title}

    `; } lessonstring += `
    ${assessmentstring}
    `; } lessonstring += "
    "; var lessondiv = stringToHTML(lessonstring); return lessondiv; } function CheckUnmarkedAttendance(lessonattendance) { if (lessonattendance) { var lesson = lessonattendance.label; } else { lesson = " "; } return lesson; } function callHomeTimetable(date, change) { // Creates a HTTP Post Request to the SEQTA page for the students timetable var xhr = new XMLHttpRequest(); xhr.open("POST", `${location.origin}/seqta/student/load/timetable?`, true); // Sets the response type to json xhr.setRequestHeader("Content-Type", "application/json; charset=utf-8"); xhr.onreadystatechange = function () { // Once the response is ready if (xhr.readyState === 4) { var serverResponse = JSON.parse(xhr.response); let lessonArray = []; var DayContainer = document.getElementById("day-container"); // If items in response: if (serverResponse.payload.items.length > 0) { if (!DayContainer.innerText || change) { // console.log(serverResponse.payload.items.length); 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); }); // If items in the response, set each corresponding value into divs // lessonArray = lessonArray.splice(1) GetLessonColours().then((colours) => { let subjects = colours; for (let i = 0; i < lessonArray.length; i++) { let subjectname = `timetable.subject.colour.${lessonArray[i].code}`; let subject = subjects.find( (element) => element.name === subjectname, ); if (!subject) { lessonArray[i].colour = "--item-colour: #8e8e8e;"; } else { lessonArray[i].colour = `--item-colour: ${subject.value};`; let result = GetThresholdofHex(subject.value); if (result > 300) { lessonArray[i].invert = true; } } // Removes seconds from the start and end times lessonArray[i].from = lessonArray[i].from.substring(0, 5); lessonArray[i].until = lessonArray[i].until.substring(0, 5); // Checks if attendance is unmarked, and sets the string to " ". lessonArray[i].attendanceTitle = CheckUnmarkedAttendance( lessonArray[i].attendance, ); } // If on home page, apply each lesson to HTML with information in each div DayContainer.innerText = ""; for (let i = 0; i < lessonArray.length; i++) { var div = MakeLessonDiv(lessonArray[i], i + 1); // Append each of the lessons into the day-container if (lessonArray[i].invert) { div.firstChild.classList.add("day-inverted"); } DayContainer.append(div.firstChild); } const today = new Date(); if (currentSelectedDate.getDate() == today.getDate()) { for (let i = 0; i < lessonArray.length; i++) { CheckCurrentLesson(lessonArray[i], i + 1); } // For each lesson, check the start and end times CheckCurrentLessonAll(lessonArray); } }); } } else { if (!DayContainer.innerText || change) { DayContainer.innerText = ""; var dummyDay = document.createElement("div"); dummyDay.classList.add("day-empty"); let img = document.createElement("img"); img.src = chrome.runtime.getURL("icons/betterseqta-light-icon.png"); let text = document.createElement("p"); text.innerText = "No lessons available."; dummyDay.append(img); dummyDay.append(text); DayContainer.append(dummyDay); } } } }; xhr.send( JSON.stringify({ // Information sent to SEQTA page as a request with the dates and student number from: date, until: date, // Funny number student: 69, }), ); } function GetUpcomingAssessments() { let func = 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); } function GetActiveClasses() { let func = fetch(`${location.origin}/seqta/student/load/subjects?`, { method: "POST", headers: { "Content-Type": "application/json; charset=utf-8", }, body: JSON.stringify({}), }); return func .then((result) => result.json()) .then((response) => response.payload); } function comparedate(obj1, obj2) { if (obj1.date < obj2.date) { return -1; } if (obj1.date > obj2.date) { return 1; } return 0; } function CreateElement(type, class_, id, innerText, innerHTML, style) { let element = document.createElement(type); if (class_ !== undefined) { element.classList.add(class_); } if (id !== undefined) { element.id = id; } if (innerText !== undefined) { element.innerText = innerText; } if (innerHTML !== undefined) { element.innerHTML = innerHTML; } if (style !== undefined) { element.style = style; } return element; } function createAssessmentDateDiv(date, value, datecase = undefined) { var options = { weekday: "long", month: "long", day: "numeric" }; const FormattedDate = new Date(date); const assessments = value.assessments; const container = value.div; let DateTitleDiv = document.createElement("div"); DateTitleDiv.classList.add("upcoming-date-title"); if (datecase) { let 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"); DateTitle.innerText = FormattedDate.toLocaleDateString("en-AU", options); DateTitleDiv.append(DateTitle); container.append(DateTitleDiv); let 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"); item.classList.add("upcoming-assessment"); item.setAttribute("data-subject", element.code); item.id = `assessment${element.id}`; item.style = element.colour; let titlediv = document.createElement("div"); titlediv.classList.add("upcoming-subject-title"); let titlesvg = stringToHTML(` `).firstChild; titlediv.append(titlesvg); let detailsdiv = document.createElement("div"); detailsdiv.classList.add("upcoming-details"); let detailstitle = document.createElement("h5"); detailstitle.innerText = `${element.subject} assessment`; let subject = document.createElement("p"); subject.innerText = element.title; subject.classList.add("upcoming-assessment-title"); subject.onclick = function () { location.href = `../#?page=/assessments/${element.programmeID}:${element.metaclassID}&item=${element.id}`; }; detailsdiv.append(detailstitle); detailsdiv.append(subject); item.append(titlediv); item.append(detailsdiv); assessmentContainer.append(item); fetch(`${location.origin}/seqta/student/assessment/submissions/get`, { method: "POST", headers: { "Content-Type": "application/json; charset=utf-8", }, body: JSON.stringify({ assessment: element.id, metaclass: element.metaclassID, student: 69, }), }) .then((result) => result.json()) .then((response) => { if (response.payload.length > 0) { const assessment = document.querySelector(`#assessment${element.id}`); // ticksvg = stringToHTML(``).firstChild // ticksvg.classList.add('upcoming-tick'); // assessment.append(ticksvg); let submittedtext = document.createElement("div"); submittedtext.classList.add("upcoming-submittedtext"); submittedtext.innerText = "Submitted"; assessment.append(submittedtext); } }); } container.append(assessmentContainer); return container; } function CheckSpecialDay(date1, date2) { if ( date1.getFullYear() === date2.getFullYear() && date1.getMonth() === date2.getMonth() && date1.getDate() - 1 === date2.getDate() ) { return "Yesterday"; } if ( date1.getFullYear() === date2.getFullYear() && date1.getMonth() === date2.getMonth() && date1.getDate() === date2.getDate() ) { return "Today"; } if ( date1.getFullYear() === date2.getFullYear() && date1.getMonth() === date2.getMonth() && date1.getDate() + 1 === date2.getDate() ) { return "Tomorrow"; } } function CreateSubjectFilter(subjectcode, itemcolour, checked) { let label = CreateElement("label", "upcoming-checkbox-container"); label.innerText = subjectcode; let input = CreateElement("input"); input.type = "checkbox"; input.checked = checked; input.id = `filter-${subjectcode}`; label.style = itemcolour; let span = CreateElement("span", "upcoming-checkmark"); label.append(input); label.append(span); input.addEventListener("change", function (change) { chrome.storage.local.get(null, function (storage) { let filters = storage.subjectfilters; let id = change.target.id.split("-")[1]; filters[id] = change.target.checked; chrome.storage.local.set({ subjectfilters: filters }); }); }); return label; } function CreateFilters(subjects) { chrome.storage.local.get(null, function (result) { let filteroptions = result.subjectfilters; let filterdiv = document.querySelector("#upcoming-filters"); for (let i = 0; i < subjects.length; i++) { const element = subjects[i]; // eslint-disable-next-line if (!Object.prototype.hasOwnProperty.call(filteroptions, element.code)) { filteroptions[element.code] = true; chrome.storage.local.set({ subjectfilters: filteroptions }); } let elementdiv = CreateSubjectFilter( element.code, element.colour, filteroptions[element.code], ); filterdiv.append(elementdiv); } }); } function CreateUpcomingSection(assessments) { let upcomingitemcontainer = document.querySelector("#upcoming-items"); let overdueDates = []; let upcomingDates = {}; // date = '2022/3/20'; // var Today = new Date(date); var Today = new Date(); // Removes overdue assessments from the upcoming assessments array and pushes to overdue array for (let i = 0; i < assessments.length; i++) { const element = assessments[i]; let assessmentdue = new Date(element.due); CheckSpecialDay(Today, assessmentdue); if (assessmentdue < Today) { if (!CheckSpecialDay(Today, assessmentdue)) { overdueDates.push(element); assessments.splice(i, 1); i--; } } } var TomorrowDate = new Date(); TomorrowDate.setDate(TomorrowDate.getDate() + 1); GetLessonColours().then((colours) => { let subjects = colours; for (let i = 0; i < assessments.length; i++) { let subjectname = `timetable.subject.colour.${assessments[i].code}`; let subject = subjects.find((element) => element.name === subjectname); if (!subject) { assessments[i].colour = "--item-colour: #8e8e8e;"; } else { assessments[i].colour = `--item-colour: ${subject.value};`; GetThresholdofHex(subject.value); // result (originally) result = GetThresholdofHex } } let activeSubjects = []; // TODO: IDK what is going on here, but it didn't exist for (let i = 0; i < activeSubjects.length; i++) { const element = activeSubjects[i]; let subjectname = `timetable.subject.colour.${element.code}`; let colour = colours.find((element) => element.name === subjectname); if (!colour) { element.colour = "--item-colour: #8e8e8e;"; } else { element.colour = `--item-colour: ${colour.value};`; let result = GetThresholdofHex(colour.value); if (result > 300) { element.invert = true; } } } CreateFilters(activeSubjects); let type; let class_; for (let i = 0; i < assessments.length; i++) { const element = assessments[i]; if (!upcomingDates[element.due]) { let dateObj = new Object(); dateObj.div = CreateElement( // TODO: not sure whats going on here? // eslint-disable-next-line type = "div", // eslint-disable-next-line class_ = "upcoming-date-container", ); dateObj.assessments = []; upcomingDates[element.due] = dateObj; } let assessmentDateDiv = upcomingDates[element.due]; assessmentDateDiv.assessments.push(element); } for (var date in upcomingDates) { let assessmentdue = new Date(upcomingDates[date].assessments[0].due); let specialcase = CheckSpecialDay(Today, assessmentdue); let assessmentDate; let datecase; if (specialcase) { assessmentDate = createAssessmentDateDiv( date, upcomingDates[date], // eslint-disable-next-line datecase = specialcase, ); } else { assessmentDate = createAssessmentDateDiv(date, upcomingDates[date]); } if (specialcase === "Yesterday") { upcomingitemcontainer.insertBefore( assessmentDate, upcomingitemcontainer.firstChild, ); } else { upcomingitemcontainer.append(assessmentDate); } } chrome.storage.local.get(null, function (result) { FilterUpcomingAssessments(result.subjectfilters); }); }); } function AddPlaceHolderToParent(parent, numberofassessments) { let textcontainer = CreateElement("div", "upcoming-blank"); let textblank = CreateElement("p", "upcoming-hiddenassessment"); let s = ""; if (numberofassessments > 1) { s = "s"; } textblank.innerText = `${numberofassessments} hidden assessment${s} due`; textcontainer.append(textblank); textcontainer.setAttribute("data-hidden", true); parent.append(textcontainer); } function FilterUpcomingAssessments(subjectoptions) { for (var item in subjectoptions) { let subjectdivs = document.querySelectorAll(`[data-subject="${item}"]`); for (let i = 0; i < subjectdivs.length; i++) { const element = subjectdivs[i]; if (!subjectoptions[item]) { element.classList.add("hidden"); } if (subjectoptions[item]) { element.classList.remove("hidden"); } element.parentNode.classList.remove("hidden"); let children = element.parentNode.parentNode.children; for (let i = 0; i < children.length; i++) { const element = children[i]; if (element.hasAttribute("data-hidden")) { element.remove(); } } if ( element.parentNode.children.length == element.parentNode.querySelectorAll(".hidden").length ) { if (element.parentNode.querySelectorAll(".hidden").length > 0) { if (!element.parentNode.parentNode.hasAttribute("data-day")) { element.parentNode.parentNode.classList.add("hidden"); } else { AddPlaceHolderToParent( element.parentNode.parentNode, element.parentNode.querySelectorAll(".hidden").length, ); } } } else { element.parentNode.parentNode.classList.remove("hidden"); } } } } chrome.storage.onChanged.addListener(function (changes) { if (changes.subjectfilters) { FilterUpcomingAssessments(changes.subjectfilters.newValue); } }); 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); } function CreateCustomShortcutDiv(element) { // Creates the stucture and element information for each seperate shortcut var shortcut = document.createElement("a"); shortcut.setAttribute("href", element.url); shortcut.setAttribute("target", "_blank"); var shortcutdiv = document.createElement("div"); shortcutdiv.classList.add("shortcut"); shortcutdiv.classList.add("customshortcut"); let image = stringToHTML( `${element.icon}`, ).firstChild; image.classList.add("shortcuticondiv"); var text = document.createElement("p"); text.textContent = element.name; shortcutdiv.append(image); shortcutdiv.append(text); shortcut.append(shortcutdiv); document.getElementById("shortcuts").append(shortcut); } function AddCustomShortcutsToPage() { chrome.storage.local.get(["customshortcuts"], function (result) { var customshortcuts = Object.values(result)[0]; if (customshortcuts.length > 0) { document.getElementsByClassName("shortcut-container")[0].style.display = "block"; for (let i = 0; i < customshortcuts.length; i++) { const element = customshortcuts[i]; CreateCustomShortcutDiv(element); } } }); } function SendHomePage() { setTimeout(function () { // 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]"); // 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 titlediv = document.getElementById("title").firstChild; titlediv.innerText = "Home"; document.querySelector("link[rel*=\"icon\"]").href = chrome.runtime.getURL("icons/icon-48.png"); currentSelectedDate = new Date(); // Creates the root of the home page added to the main div var htmlStr = "
    "; var html = stringToHTML(htmlStr); // Appends the html file to main div // Note : firstChild of html is done due to needing to grab the body from the stringToHTML function main.append(html.firstChild); // Gets the current date const date = new Date(); // Formats the current date used send a request for timetable and notices later var TodayFormatted = date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDate(); // Replaces actual date with a selected date. Used for testing. // TodayFormatted = "2020-08-31"; // Creates the shortcut container into the home container var ShortcutStr = "
    "; var Shortcut = stringToHTML(ShortcutStr); // Appends the shortcut container into the home container document.getElementById("home-container").append(Shortcut.firstChild); // Creates the container div for the timetable portion of the home page var TimetableStr = "

    Today's Lessons

    "; var Timetable = stringToHTML(TimetableStr); // Appends the timetable container into the home container document.getElementById("home-container").append(Timetable.firstChild); var timetablearrowback = document.getElementById("home-timetable-back"); var timetablearrowforward = document.getElementById( "home-timetable-forward", ); function SetTimetableSubtitle() { var homelessonsubtitle = document.getElementById("home-lesson-subtitle"); const date = new Date(); if ( date.getYear() == currentSelectedDate.getYear() && date.getMonth() == currentSelectedDate.getMonth() ) { if (date.getDate() == currentSelectedDate.getDate()) { // Change text to Today's Lessons homelessonsubtitle.innerText = "Today's Lessons"; } else if (date.getDate() - 1 == currentSelectedDate.getDate()) { // Change text to Yesterday's Lessons homelessonsubtitle.innerText = "Yesterday's Lessons"; } else if (date.getDate() + 1 == currentSelectedDate.getDate()) { // Change text to Tomorrow's Lessons homelessonsubtitle.innerText = "Tomorrow's Lessons"; } else { // Change text to date of the day homelessonsubtitle.innerText = `${currentSelectedDate.toLocaleString( "en-us", { weekday: "short" }, )} ${currentSelectedDate.toLocaleDateString("en-au")}`; } } else { // Change text to date of the day homelessonsubtitle.innerText = `${currentSelectedDate.toLocaleString( "en-us", { weekday: "short" }, )} ${currentSelectedDate.toLocaleDateString("en-au")}`; } } function changeTimetable(value) { currentSelectedDate.setDate(currentSelectedDate.getDate() + value); let FormattedDate = currentSelectedDate.getFullYear() + "-" + (currentSelectedDate.getMonth() + 1) + "-" + currentSelectedDate.getDate(); callHomeTimetable(FormattedDate, true); SetTimetableSubtitle(); } timetablearrowback.addEventListener("click", function () { changeTimetable(-1); }); timetablearrowforward.addEventListener("click", function () { changeTimetable(1); }); function createNewShortcut(link, icon, viewBox, title) { // Creates the stucture and element information for each seperate shortcut var shortcut = document.createElement("a"); shortcut.setAttribute("href", link); shortcut.setAttribute("target", "_blank"); var shortcutdiv = document.createElement("div"); shortcutdiv.classList.add("shortcut"); let image = stringToHTML( ``, ).firstChild; image.classList.add("shortcuticondiv"); var text = document.createElement("p"); text.textContent = title; shortcutdiv.append(image); shortcutdiv.append(text); shortcut.append(shortcutdiv); document.getElementById("shortcuts").append(shortcut); } // Adds the shortcuts to the shortcut container chrome.storage.local.get(["shortcuts"], function (result) { var shortcuts = Object.values(result)[0]; for (let i = 0; i < shortcuts.length; i++) { if (shortcuts[i].enabled) { let Itemname = shortcuts[i].name.replace(/ /g, ""); createNewShortcut( ShortcutLinks[Itemname].link, ShortcutLinks[Itemname].icon, ShortcutLinks[Itemname].viewBox, shortcuts[i].name, ); } } AddCustomShortcutsToPage(); // Checks if shortcut container is empty if (document.getElementById("shortcuts").childElementCount == 0) { // If there are no shortcuts, hide the container document.getElementsByClassName("shortcut-container")[0].style.display = "none"; } }); // Creates the upcoming container and appends to the home container var upcomingcontainer = document.createElement("div"); upcomingcontainer.classList.add("upcoming-container"); upcomingcontainer.classList.add("border"); let upcomingtitlediv = CreateElement("div", "upcoming-title"); let upcomingtitle = document.createElement("h2"); upcomingtitle.classList.add("home-subtitle"); upcomingtitle.innerText = "Upcoming Assessments"; upcomingtitlediv.append(upcomingtitle); let upcomingfilterdiv = CreateElement( "div", "upcoming-filters", "upcoming-filters", ); upcomingtitlediv.append(upcomingfilterdiv); upcomingcontainer.append(upcomingtitlediv); let upcomingitems = document.createElement("div"); upcomingitems.id = "upcoming-items"; upcomingitems.classList.add("upcoming-items"); upcomingcontainer.append(upcomingitems); document.getElementById("home-container").append(upcomingcontainer); // Creates the notices container into the home container var NoticesStr = "

    Notices

    "; var Notices = stringToHTML(NoticesStr); // Appends the shortcut container into the home container document.getElementById("home-container").append(Notices.firstChild); callHomeTimetable(TodayFormatted); // Sends similar HTTP Post Request for the notices var xhr2 = new XMLHttpRequest(); xhr2.open("POST", `${location.origin}/seqta/student/load/notices?`, true); xhr2.setRequestHeader("Content-Type", "application/json; charset=utf-8"); xhr2.onreadystatechange = function () { if (xhr2.readyState === 4) { var NoticesPayload = JSON.parse(xhr2.response); var NoticeContainer = document.getElementById("notice-container"); if (NoticesPayload.payload.length == 0) { if (!NoticeContainer.innerText) { // If no notices: display no notices var dummyNotice = document.createElement("div"); dummyNotice.textContent = "No notices for today."; dummyNotice.classList.add("dummynotice"); NoticeContainer.append(dummyNotice); } } else { if (!NoticeContainer.innerText) { // For each element in the response json: chrome.storage.local.get(["DarkMode"], function (result) { DarkMode = result.DarkMode; for (let i = 0; i < NoticesPayload.payload.length; i++) { // Create a div, and place information from json response var NewNotice = document.createElement("div"); NewNotice.classList.add("notice"); var title = stringToHTML( "

    " + NoticesPayload.payload[i].title + "

    ", ); NewNotice.append(title.firstChild); if (NoticesPayload.payload[i].label_title != undefined) { var label = stringToHTML( "
    " + NoticesPayload.payload[i].label_title + "
    ", ); NewNotice.append(label.firstChild); } var staff = stringToHTML( "
    " + NoticesPayload.payload[i].staff + "
    ", ); NewNotice.append(staff.firstChild); // Converts the string into HTML let styles; var content = stringToHTML( NoticesPayload.payload[i].contents, // eslint-disable-next-line styles = true, ); for (let i = 0; i < content.childNodes.length; i++) { NewNotice.append(content.childNodes[i]); } // Gets the colour for the top section of each notice var colour = NoticesPayload.payload[i].colour; if (typeof colour == "string") { let rgb = GetThresholdofHex(colour); if (rgb < 100 && result.DarkMode) { colour = undefined; } } var colourbar = document.createElement("div"); colourbar.classList.add("colourbar"); colourbar.style.background = "var(--colour)"; NewNotice.style = `--colour: ${colour}`; // Appends the colour bar to the new notice NewNotice.append(colourbar); // Appends the new notice into the notice container NoticeContainer.append(NewNotice); } }); } } } }; // Data sent as the POST request xhr2.send(JSON.stringify({ date: TodayFormatted })); // Sends similar HTTP Post Request for the notices chrome.storage.local.get(null, function (result) { if (result.notificationcollector) { var xhr3 = new XMLHttpRequest(); xhr3.open("POST", `${location.origin}/seqta/student/heartbeat?`, true); xhr3.setRequestHeader( "Content-Type", "application/json; charset=utf-8", ); xhr3.onreadystatechange = function () { if (xhr3.readyState === 4) { var Notifications = JSON.parse(xhr3.response); var alertdiv = document.getElementsByClassName( "notifications__bubble___1EkSQ", )[0]; if (typeof alertdiv == "undefined") { console.log("[BetterSEQTA] No notifications currently"); } else { alertdiv.textContent = Notifications.payload.notifications.length; } } }; xhr3.send( JSON.stringify({ timestamp: "1970-01-01 00:00:00.0", hash: "#?page=/home", }), ); } }); console.log("Getting assessments"); let activeClassList; GetUpcomingAssessments().then((assessments) => { GetActiveClasses().then((classes) => { // Gets all subjects for the student for (let i = 0; i < classes.length; i++) { const element = classes[i]; // eslint-disable-next-line if (element.hasOwnProperty("active")) { // for some reason eslint gets mad, even though it works? // Finds the active class list with the current subjects activeClassList = classes[i]; } } let activeSubjects = activeClassList.subjects; let activeSubjectCodes = []; // Gets the code for each of the subjects and puts them in an array let element; for (let i = 0; i < activeSubjects.length; i++) { element = activeSubjects[i]; activeSubjectCodes.push(element.code); } let CurrentAssessments = []; for (let i = 0; i < assessments.length; i++) { element = assessments[i]; if (activeSubjectCodes.includes(element.code)) { CurrentAssessments.push(element); } } CurrentAssessments.sort(comparedate); console.log(CurrentAssessments, activeSubjects); CreateUpcomingSection(CurrentAssessments, activeSubjects); // Run function to check if gap between assessments > 7 days? }); }); }, 8); } function SendNewsPage() { setTimeout(function () { // Sends the html data for the home page console.log("[BetterSEQTA] Started Loading News Page"); document.title = "News ― SEQTA Learn"; var element = document.querySelector("[data-key=news]"); // 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 = ""; // Creates the root of the home page added to the main div var htmlStr = "

    Latest Headlines - ABC News

    "; var html = stringToHTML(htmlStr); // Appends the html file to main div // Note : firstChild of html is done due to needing to grab the body from the stringToHTML function main.append(html.firstChild); const titlediv = document.getElementById("title").firstChild; titlediv.innerText = "News"; AppendLoadingSymbol("newsloading", "#news-container"); chrome.runtime.sendMessage({ type: "sendNews" }, function (response) { let newsarticles = response.news.articles; var newscontainer = document.querySelector("#news-container"); document.getElementById("newsloading").remove(); for (let i = 0; i < newsarticles.length; i++) { let newsarticle = document.createElement("a"); newsarticle.classList.add("NewsArticle"); newsarticle.href = newsarticles[i].url; newsarticle.target = "_blank"; let articleimage = document.createElement("div"); articleimage.classList.add("articleimage"); if (newsarticles[i].urlToImage == "null") { articleimage.style.backgroundImage = `url(${chrome.runtime.getURL( "icons/betterseqta-light-outline.png", )})`; articleimage.style.width = "20%"; articleimage.style.margin = "0 7.5%"; } else { articleimage.style.backgroundImage = `url(${newsarticles[i].urlToImage})`; } let articletext = document.createElement("div"); articletext.classList.add("ArticleText"); let title = document.createElement("a"); title.innerText = newsarticles[i].title; title.href = newsarticles[i].url; title.target = "_blank"; let description = document.createElement("p"); description.innerHTML = newsarticles[i].description; articletext.append(title); articletext.append(description); newsarticle.append(articleimage); newsarticle.append(articletext); newscontainer.append(newsarticle); } }); }, 8); } /* function EnabledDisabledToBool(input) { if (input == "enabled") { return true; } if (input == "disabled") { return false; } } */ function LoadInit() { console.log("[BetterSEQTA] Started Init"); chrome.storage.local.get(null, function (result) { if (result.onoff) { SendHomePage(); } }); }