diff --git a/interface/src/App.tsx b/interface/src/App.tsx
index 991ec02d..d686838b 100644
--- a/interface/src/App.tsx
+++ b/interface/src/App.tsx
@@ -4,9 +4,9 @@ import Settings from './pages/Settings';
import logo from './assets/betterseqta-dark-full.png';
import logoDark from './assets/betterseqta-light-full.png';
import Shortcuts from './pages/Shortcuts';
-import About from './pages/About';
import { useSettingsContext } from './SettingsContext';
import Picker from './components/Picker';
+import Themes from './pages/Themes';
const App: React.FC = () => {
@@ -30,8 +30,8 @@ const App: React.FC = () => {
content:
},
{
- title: 'About',
- content:
+ title: 'Themes',
+ content:
}
];
diff --git a/interface/src/pages/Themes.tsx b/interface/src/pages/Themes.tsx
new file mode 100644
index 00000000..5d7793ba
--- /dev/null
+++ b/interface/src/pages/Themes.tsx
@@ -0,0 +1,104 @@
+import React, { useState, useEffect } from 'react';
+
+// IndexedDB utility functions
+const openDB = () => {
+ return new Promise((resolve, reject) => {
+ const request = indexedDB.open('MyDatabase', 1);
+
+ request.onerror = () => reject(request.error);
+ request.onsuccess = () => resolve(request.result);
+
+ request.onupgradeneeded = (event) => {
+ const db = (event.target as IDBOpenDBRequest).result;
+ db.createObjectStore('backgrounds', { keyPath: 'id' });
+ };
+ });
+};
+
+const writeData = async (type: string, data: any) => {
+ return new Promise((resolve, reject) => {
+ openDB().then(async db => {
+ const tx = db.transaction('backgrounds', 'readwrite');
+ const store = tx.objectStore('backgrounds');
+ const request = store.put({ id: 'customBackground', type, data });
+
+ // Wait for the transaction to complete
+ await new Promise((res, rej) => {
+ tx.oncomplete = () => res(request.result);
+ tx.onerror = () => rej(tx.error);
+ }).then(resolve, reject);
+
+ }).catch(reject);
+ });
+};
+
+
+const readData = async () => {
+ const db = await openDB();
+ const tx = db.transaction('backgrounds', 'readonly');
+ const store = tx.objectStore('backgrounds');
+ const request = store.get('customBackground');
+
+ return await new Promise((resolve, reject) => {
+ request.onsuccess = () => resolve(request.result);
+ request.onerror = () => reject(request.error);
+ });
+};
+
+const Themes: React.FC = () => {
+ const [imageSrc, setImageSrc] = useState(null);
+
+ const handleFileChange = async (e: React.ChangeEvent) => {
+ const file = e.target.files?.[0];
+ if (!file) return;
+
+ const fileType = 'image';
+ const reader = new FileReader();
+
+ reader.onload = async () => {
+ const dataURL = reader.result;
+ await writeData(fileType, dataURL);
+ setImageSrc(dataURL as string);
+ };
+
+ if (fileType === 'image') {
+ reader.readAsDataURL(file);
+ } else {
+ // Handle video file
+ }
+ };
+
+ useEffect(() => {
+ (async () => {
+ const data = await readData();
+ if (data?.type === 'image') {
+ setImageSrc(data.data);
+ }
+ })();
+ }, []);
+
+ return (
+
+
+
Custom Background
+
+
+
+ {imageSrc &&

}
+
+
+
Themes
+
+
+
+
+
+
+ );
+};
+
+export default Themes;
\ No newline at end of file
diff --git a/src/SEQTA.js b/src/SEQTA.js
index 7c3ec932..ce96b552 100644
--- a/src/SEQTA.js
+++ b/src/SEQTA.js
@@ -10,14 +10,17 @@ import loading, { AppendLoadingSymbol } from "./seqta/ui/Loading.js";
import assessmentsicon from "./seqta/icons/assessmentsIcon.js";
import coursesicon from "./seqta/icons/coursesIcon.js";
import StorageListener from "./seqta/utils/StorageListener.js";
+import { updateBgDurations } from "./seqta/ui/Animation.js";
+import { updateAllColors } from "./seqta/ui/Colors.js";
+import { appendBackgroundToUI } from "./seqta/ui/Background.js";
-let isChrome = window.chrome;
+export let isChrome = window.chrome;
let SettingsClicked = false;
let MenuOptionsOpen = false;
let UserInitalCode = "";
let currentSelectedDate = new Date();
let LessonInterval;
-let DarkMode;
+export let DarkMode;
function delay(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
@@ -36,27 +39,7 @@ function animbkEnable(item) {
}
}
-function bkValues (item) {
- const bg = document.getElementsByClassName("bg");
- const bg2 = document.getElementsByClassName("bg2");
- const bg3 = document.getElementsByClassName("bg3");
- const value = 200 - item.bksliderinput; // reverse the slider direction to match the animation direction
-
- if (bg.length == 0 || bg2.length == 0 || bg3.length == 0) return;
-
- const minDuration = 1; // minimum duration in seconds
- const maxDuration = 10; // maximum duration in seconds
- const durationRange = maxDuration - minDuration;
- const bgDuration = minDuration + (value / 200) * durationRange;
- const bg2Duration = minDuration + ((value / 200) + 0.05) * durationRange;
- const bg3Duration = minDuration + ((value / 200) + 0.1) * durationRange;
-
- bg[0].style.animationDuration = `${bgDuration}s`;
- bg2[0].style.animationDuration = `${bg2Duration}s`;
- bg3[0].style.animationDuration = `${bg3Duration}s`;
-}
-
-function ApplyCSSToHiddenMenuItems() {
+export function ApplyCSSToHiddenMenuItems() {
var stylesheetInnerText = "";
chrome.storage.local.get(null, function (result) {
for (let i = 0; i < Object.keys(result.menuitems).length; i++) {
@@ -245,7 +228,7 @@ function RemoveBackground() {
bk3[0].remove();
}
-function waitForElm(selector) {
+export function waitForElm(selector) {
return new Promise((resolve) => {
if (document.querySelector(selector)) {
return resolve(document.querySelector(selector));
@@ -518,7 +501,7 @@ function CheckNoticeTextColour(notice) {
});
}
-function tryLoad() {
+export function tryLoad() {
waitForElm(".login").then(() => {
finishLoad();
});
@@ -573,7 +556,7 @@ function ChangeMenuItemPositions(storage) {
}
}
-async function ObserveMenuItemPosition() {
+export async function ObserveMenuItemPosition() {
chrome.storage.local.get(null, function (result) {
let menuorder = result.menuorder;
if (menuorder && result.onoff) {
@@ -601,7 +584,67 @@ async function ObserveMenuItemPosition() {
});
}
-function AppendElementsToDisabledPage() {
+function main(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);
+
+ updateAllColors(storedSetting);
+
+ 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();
+ });
+ });
+ }
+}
+
+export function AppendElementsToDisabledPage() {
AddBetterSEQTAElements(false);
let settingsStyle = document.createElement("style");
@@ -757,146 +800,6 @@ async function CheckLoadOnPeriods() {
}
}
-function main(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,
- );
-
- 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;
@@ -933,361 +836,8 @@ document.addEventListener(
},
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 colorpicker = document.querySelector("#colorpicker");
- const animatedbk = document.querySelector("#animatedbk");
- const bkslider = document.querySelector("#bksliderinput");
-
- 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;
-
- 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 });
- chrome.storage.local.set({ bksliderinput: bkslider.value });
- }
-
- 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;
- bkslider.value = restoredSettings.bksliderinput;
- 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);
- });
-
- 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);
- bkslider.addEventListener("change", () => {
- storeNotificationSettings();
- chrome.storage.local.get(["bksliderinput"]).then(bkValues);
- });
- animatedbk.addEventListener("change", () => {
- storeNotificationSettings();
- animbkEnable({ animatedbk: animatedbk.checked });
- });
-
- for (let i = 0; i < allinputs.length; i++) {
- if (
- allinputs[i].id != "colorpicker" &&
- allinputs[i].id != "shortcuturl" &&
- allinputs[i].id != "shortcutname" &&
- allinputs[i].id != "bkslider" &&
- allinputs[i].id != "bksliderinput"
- ) {
- 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`
@@ -1607,6 +1157,7 @@ function ReplaceMenuSVG(element, svg) {
function AddBetterSEQTAElements(toggle) {
var code = document.getElementsByClassName("code")[0];
+ appendBackgroundToUI();
// Replaces students code with the version of BetterSEQTA
if (code != null) {
if (!code.innerHTML.includes("BetterSEQTA")) {
@@ -1632,7 +1183,7 @@ function AddBetterSEQTAElements(toggle) {
const sliderVal = chrome.storage.local.get(["bksliderinput"]);
result.then(animbkEnable);
- sliderVal.then(bkValues);
+ sliderVal.then(updateBgDurations);
// Load darkmode state
chrome.storage.local.get(["DarkMode"], function (result) {
@@ -1776,7 +1327,6 @@ function AddBetterSEQTAElements(toggle) {
}
CallExtensionSettings();
- //RunExtensionSettingsJS();
// If betterSEQTA+ is enabled, run the code
if (toggle) {
@@ -3098,16 +2648,18 @@ function SendNewsPage() {
}, 8);
}
-/*
-function EnabledDisabledToBool(input) {
- if (input == "enabled") {
- return true;
- }
- if (input == "disabled") {
- return false;
+async function CheckForMenuList() {
+ if (!MenuItemMutation) {
+ try {
+ if (document.getElementById("menu").firstChild) {
+ ObserveMenuItemPosition();
+ MenuItemMutation = true;
+ }
+ } catch (error) {
+ return;
+ }
}
}
-*/
function LoadInit() {
console.log("[BetterSEQTA] Started Init");
diff --git a/src/background.js b/src/background.js
index 28133432..1016ae73 100644
--- a/src/background.js
+++ b/src/background.js
@@ -1,5 +1,7 @@
/*global chrome*/
+import { readData, writeData } from "./seqta/utils/IndexedDB.js";
+
function ReloadSEQTAPages() {
chrome.tabs.query({}, function (tabs) {
for (let tab of tabs) {
@@ -10,69 +12,110 @@ function ReloadSEQTAPages() {
});
}
-chrome.runtime.onMessage.addListener(function (request) {
- if (request.type == "reloadTabs") {
- ReloadSEQTAPages();
- } else if (request.type == "githubTab") {
- chrome.tabs.create({
- url: "github.com/SethBurkart123/EvenBetterSEQTA",
- });
- } else if (request.type == "setDefaultStorage") {
- console.log("setting default values");
- SetStorageValue(DefaultValues);
- } else if (request.type == "addPermissions") {
- if (typeof chrome.declarativeContent != "undefined") {
- chrome.declarativeContent.onPageChanged.removeRules(
- undefined,
- function () {},
- );
+// Helper function to handle IndexedDB actions
+const handleIndexedDBActions = (request) => {
+ return new Promise((resolve, reject) => {
+ console.log("request");
+ if (request.action === "save") {
+ writeData(request.data.type, request.data.data)
+ .then(() => {
+ resolve({ message: "Data saved successfully" });
+ })
+ .catch(reject);
+ } else if (request.action === "read") {
+ readData()
+ .then(data => {
+ resolve(data);
+ })
+ .catch(reject);
+ } else {
+ reject(new Error("Invalid action type"));
}
- chrome.permissions.request(
- { permissions: ["declarativeContent"], origins: ["*://*/*"] },
- function (granted) {
- if (granted) {
- let rules = [
- {
- conditions: [
- new chrome.declarativeContent.PageStateMatcher({
- pageUrl: {
- urlContains: "site.seqta.com.au",
- schemes: ["https"],
- },
- }),
- ],
- actions: [
- new chrome.declarativeContent.RequestContentScript({
- js: ["SEQTA.js"],
- }),
- ],
- },
- {
- conditions: [
- new chrome.declarativeContent.PageStateMatcher({
- pageUrl: { urlContains: "learn.", schemes: ["https"] },
- }),
- ],
- actions: [
- new chrome.declarativeContent.RequestContentScript({
- js: ["SEQTA.js"],
- }),
- ],
- },
- ];
- for (let i = 0; i < rules.length; i++) {
- chrome.declarativeContent.onPageChanged.addRules([rules[i]]);
- }
- alert(
- "Permissions granted. Reload SEQTA pages to see changes. If this workaround doesn't work, please contact the developer. It will be an easy fix",
- );
- }
- },
- );
+ });
+};
+
+// Helper function to handle setting permissions
+const handleAddPermissions = () => {
+ if (typeof chrome.declarativeContent !== "undefined") {
+ chrome.declarativeContent.onPageChanged.removeRules(undefined, () => {});
+ }
+
+ chrome.permissions.request(
+ { permissions: ["declarativeContent"], origins: ["*://*/*"] },
+ (granted) => {
+ if (granted) {
+ const rules = [
+ // Define your rules here
+ ];
+
+ rules.forEach(rule => {
+ chrome.declarativeContent.onPageChanged.addRules([rule]);
+ });
+
+ alert("Permissions granted. Reload SEQTA pages to see changes. If this workaround doesn't work, please contact the developer. It will be an easy fix");
+ }
+ }
+ );
+};
+
+// Main message listener
+chrome.runtime.onMessage.addListener(async (request, sender, sendResponse) => {
+ console.log("Message received in background script", request);
+
+ sendResponse({ type: "success" });
+ switch (request.type) {
+ case "reloadTabs":
+ ReloadSEQTAPages();
+ break;
+
+ case "IndexedDB":
+ handleIndexedDBActions(request, sendResponse);
+ return true; // This keeps the message channel open for async sendResponse
+ // eslint-disable-next-line no-unreachable
+ break;
+
+ case "githubTab":
+ chrome.tabs.create({ url: "github.com/SethBurkart123/EvenBetterSEQTA" });
+ break;
+
+ case "setDefaultStorage":
+ console.log("Setting default values");
+ SetStorageValue(DefaultValues);
+ break;
+
+ case "addPermissions":
+ handleAddPermissions();
+ break;
+
+ case "sendNews":
+ GetNews(sendResponse);
+ return true;
+ // eslint-disable-next-line no-unreachable
+ break;
+
+ default:
+ console.log("Unknown request type");
}
});
-function GetNews(url, sendResponse) {
+function GetNews(sendResponse) {
+ // Gets the current date
+ const date = new Date();
+ // Formats the current date used send a request for timetable and notices later
+ const TodayFormatted =
+ date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDate();
+
+ const from =
+ date.getFullYear() +
+ "-" +
+ (date.getMonth() + 1) +
+ "-" +
+ (date.getDate() - 1);
+ console.log(TodayFormatted);
+ console.log(from);
+
+ let url = `https://newsapi.org/v2/everything?domains=abc.net.au&from=${from}&apiKey=17c0da766ba347c89d094449504e3080`;
+
fetch(url)
.then((result) => result.json())
.then((response) => {
@@ -85,31 +128,6 @@ function GetNews(url, sendResponse) {
});
}
-chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
- if (request.type === "sendNews") {
- // 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();
-
- var from =
- date.getFullYear() +
- "-" +
- (date.getMonth() + 1) +
- "-" +
- (date.getDate() - 1);
- console.log(TodayFormatted);
- console.log(from);
-
- var url = `https://newsapi.org/v2/everything?domains=abc.net.au&from=${from}&apiKey=17c0da766ba347c89d094449504e3080`;
-
- GetNews(url, sendResponse);
-
- return true;
- }
-});
-
const DefaultValues = {
onoff: true,
animatedbk: true,
@@ -241,7 +259,7 @@ function migrateOldStorage() {
}
}
- // If there's something to update, set the new values in storage
+ // If there"s something to update, set the new values in storage
if (shouldUpdate) {
chrome.storage.local.set({ shortcuts: items.shortcuts }, function() {
console.log("Migration completed.");
diff --git a/src/inject/iframe.css b/src/inject/iframe.css
index cb4516ae..d3205e41 100644
--- a/src/inject/iframe.css
+++ b/src/inject/iframe.css
@@ -41,6 +41,10 @@ table th {
background-color: #161616;
}
+/* .cke_panel_listItem {
+
+} */
+
::-webkit-scrollbar {
width: 10px;
height: 10px;
diff --git a/src/inject/injected.css b/src/inject/injected.css
index b2b06bc2..89a3eed8 100644
--- a/src/inject/injected.css
+++ b/src/inject/injected.css
@@ -1169,6 +1169,17 @@ div > ol:has(.uiFileHandlerWrapper) {
border-radius: 0.5rem;
}
+.cke_panel > iframe {
+ height: 180px;
+ background: var(--background-primary);
+}
+
+.cke_panel {
+ border-radius: 1rem;
+ overflow: hidden;
+ background: unset;
+}
+
.Avatar__Avatar___gE5kx.Avatar__staff___4gVLs {
--person-colour: var(--better-light);
background: var(--person-colour, var(--navy));
diff --git a/src/inject/injected/popup.css b/src/inject/injected/popup.css
index a03f151c..700f4bae 100644
--- a/src/inject/injected/popup.css
+++ b/src/inject/injected/popup.css
@@ -19,4 +19,10 @@
top: 80px;
height: 590px;
z-index: 20;
+}
+
+.imageBackground {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
}
\ No newline at end of file
diff --git a/src/seqta/ui/Animation.js b/src/seqta/ui/Animation.js
new file mode 100644
index 00000000..a6059f09
--- /dev/null
+++ b/src/seqta/ui/Animation.js
@@ -0,0 +1,32 @@
+/**
+ * Update the background animation durations based on the slider input.
+ * @param {Object} item - The object containing the bksliderinput property.
+ * @param {number} [minDuration=1] - The minimum animation duration in seconds.
+ * @param {number} [maxDuration=10] - The maximum animation duration in seconds.
+ */
+export function updateBgDurations(item, minDuration = 1, maxDuration = 10) {
+ // Class names to look for
+ const bgClasses = ["bg", "bg2", "bg3"];
+
+ // Reverse the slider direction to align with the animation
+ const reversedValue = 200 - item.bksliderinput;
+
+ // Range of possible animation durations
+ const durationRange = maxDuration - minDuration;
+
+ // Function to calculate animation duration
+ const calcDuration = (baseValue, offset = 0) => minDuration + ((baseValue / 200) + offset) * durationRange;
+
+ // Iterate through each class name to update its animation duration
+ bgClasses.forEach((className, index) => {
+ const elements = document.getElementsByClassName(className);
+ if (elements.length === 0) {
+ console.error(`No elements found with class name: ${className}`);
+ return;
+ }
+
+ const offset = index * 0.05;
+ const duration = calcDuration(reversedValue, offset);
+ elements[0].style.animationDuration = `${duration}s`;
+ });
+}
\ No newline at end of file
diff --git a/src/seqta/ui/Background.js b/src/seqta/ui/Background.js
new file mode 100644
index 00000000..2619d5d6
--- /dev/null
+++ b/src/seqta/ui/Background.js
@@ -0,0 +1,37 @@
+/* global chrome */
+
+export async function appendBackgroundToUI() {
+ try {
+ const response = await new Promise((resolve, reject) => {
+ chrome.runtime.sendMessage({ type: "IndexedDB" }, (response) => {
+ if (chrome.runtime.lastError) {
+ return reject(chrome.runtime.lastError);
+ }
+ resolve(response);
+ });
+ });
+ console.log("response:", response);
+ } catch (error) {
+ console.log("Error:", error);
+ }
+
+
+ const mount = document.getElementById("container");
+ console.log("Starting to append background");
+ let data;
+ const response = await chrome.runtime.sendMessage({ type: "IndexedDB" });
+ data = response;
+ const imgElement = document.createElement("img");
+ imgElement.src = data;
+ imgElement.alt = "Uploaded Image";
+ imgElement.classList.add("imageBackground");
+ mount.appendChild(imgElement);
+
+/* if (data) {
+ continue
+ } else if (data?.type === "video") {
+ // Handle video
+ } */
+}
+
+appendBackgroundToUI();
diff --git a/src/seqta/ui/Colors.js b/src/seqta/ui/Colors.js
index 406c767c..c580d6c2 100644
--- a/src/seqta/ui/Colors.js
+++ b/src/seqta/ui/Colors.js
@@ -1,19 +1,52 @@
/* global chrome */
-import { ColorLuminance, GetThresholdofHex } from "../../SEQTA.js";
+import { ColorLuminance, GetThresholdofHex, lightenAndPaleColor } from "../../SEQTA.js";
-export function updateDocumentColors(newColor) {
- const rbg = GetThresholdofHex(newColor);
- const textColor = rbg > 210 ? "black" : "white";
- const logo = `url(${chrome.runtime.getURL(
- `icons/betterseqta-${textColor === "black" ? "dark" : "light"}-full.png`
- )})`;
+// Helper functions
+const setCSSVar = (varName, value) => document.documentElement.style.setProperty(varName, value);
+const getChromeURL = (path) => chrome.runtime.getURL(path);
+const applyProperties = (props) => Object.entries(props).forEach(([key, value]) => setCSSVar(key, value));
- document.documentElement.style.setProperty("--text-color", textColor);
- document.documentElement.style.setProperty("--betterseqta-logo", logo);
- document.documentElement.style.setProperty("--better-main", newColor);
+export function updateAllColors(storedSetting, newColor = null) {
+ // Determine the color to use
+ const selectedColor = newColor || storedSetting.selectedColor;
+ const DarkMode = storedSetting ? storedSetting.DarkMode : null;
- const lightColor =
- newColor === "#ffffff" ? "#b7b7b7" : ColorLuminance(newColor, 0.99);
+ // Common properties, always applied
+ const commonProps = {
+ "--better-sub": "#161616",
+ "--better-alert-highlight": "#c61851",
+ "--better-main": selectedColor
+ };
- document.documentElement.style.setProperty("--better-light", lightColor);
-}
\ No newline at end of file
+ // Mode-based properties, applied if storedSetting is provided
+ let modeProps = {};
+ if (DarkMode !== null) {
+ modeProps = DarkMode ? {
+ "--background-primary": "#232323",
+ "--background-secondary": "#1a1a1a",
+ "--text-primary": "white"
+ } : {
+ "--background-primary": "#ffffff",
+ "--background-secondary": "#e5e7eb",
+ "--text-primary": "black",
+ "--better-pale": lightenAndPaleColor(selectedColor) // Wrap this in try-catch if needed
+ };
+ }
+
+ // Dynamic properties, always applied
+ const rgbThreshold = GetThresholdofHex(selectedColor);
+ const isBright = rgbThreshold > 210;
+ const dynamicProps = {
+ "--text-color": isBright ? "black" : "white",
+ "--betterseqta-logo": `url(${getChromeURL(`icons/betterseqta-${isBright ? "dark" : "light"}-full.png`)})`,
+ "--better-light": selectedColor === "#ffffff" ? "#b7b7b7" : ColorLuminance(selectedColor, 0.95)
+ };
+
+ // Apply all the properties
+ applyProperties({ ...commonProps, ...modeProps, ...dynamicProps });
+
+ // Set favicon, if storedSetting is provided
+ if (DarkMode !== null) {
+ document.querySelector("link[rel*='icon']").href = getChromeURL("icons/icon-48.png");
+ }
+}
diff --git a/src/seqta/utils/IndexedDB.js b/src/seqta/utils/IndexedDB.js
new file mode 100644
index 00000000..56d9446e
--- /dev/null
+++ b/src/seqta/utils/IndexedDB.js
@@ -0,0 +1,34 @@
+// IndexedDB utility functions
+export const openDB = () => {
+ return new Promise((resolve, reject) => {
+ const request = indexedDB.open("MyDatabase", 1);
+
+ request.onerror = () => reject(request.error);
+ request.onsuccess = () => resolve(request.result);
+
+ request.onupgradeneeded = (event) => {
+ const db = (event.target).result;
+ db.createObjectStore("backgrounds", { keyPath: "id" });
+ };
+ });
+};
+
+export const writeData = async (type, data) => {
+ return new Promise((resolve, reject) => {
+ openDB().then(db => {
+ const tx = db.transaction("backgrounds", "readwrite");
+ const store = tx.objectStore("backgrounds");
+ const request = store.put({ id: "customBackground", type, data });
+
+ tx.oncomplete = () => resolve(request.result);
+ tx.onerror = () => reject(tx.error);
+ }).catch(reject);
+ });
+};
+
+export const readData = async () => {
+ const db = await openDB();
+ const tx = db.transaction("backgrounds", "readonly");
+ const store = tx.objectStore("backgrounds");
+ return store.get("customBackground");
+};
\ No newline at end of file
diff --git a/src/seqta/utils/StorageListener.js b/src/seqta/utils/StorageListener.js
index 39f9aa19..5b9e21af 100644
--- a/src/seqta/utils/StorageListener.js
+++ b/src/seqta/utils/StorageListener.js
@@ -4,7 +4,7 @@ import {
CreateCustomShortcutDiv,
RemoveCustomShortcutDiv,
} from "../../SEQTA.js";
-import { updateDocumentColors } from "../ui/Colors.js";
+import { updateAllColors } from "../ui/Colors.js";
export default class StorageListener {
constructor() {
@@ -26,11 +26,7 @@ export default class StorageListener {
handleSelectedColorChange(newColor) {
try {
- chrome.storage.local.get(["DarkMode"], (result) => {
- if (!result.DarkMode) {
- updateDocumentColors(newColor);
- }
- });
+ updateAllColors(null, newColor);
} catch (err) {
console.error(err);
}