This commit is contained in:
SethBurkart123
2025-03-30 10:41:19 +11:00
parent e3f4b59d9c
commit 19cc1a5600
17 changed files with 361 additions and 159 deletions
+126
View File
@@ -0,0 +1,126 @@
--- a/Users/sethburkart/Documents/Coding/betterseqta-plus/src/plugins/core/settings.ts
+++ b/Users/sethburkart/Documents/Coding/betterseqta-plus/src/plugins/core/settings.ts
@@ -2,7 +2,7 @@
// Base interfaces for our settings
interface BaseSettingOptions {
- title: string;
+ readonly title: string; // Mark as readonly where appropriate
description?: string;
}
@@ -11,21 +11,21 @@
}
interface StringSettingOptions extends BaseSettingOptions {
- default: string;
+ readonly default: string;
maxLength?: number;
pattern?: string;
}
interface NumberSettingOptions extends BaseSettingOptions {
- default: number;
+ readonly default: number;
min?: number;
max?: number;
step?: number;
}
interface SelectSettingOptions<T extends string> extends BaseSettingOptions {
- default: T;
- options: readonly T[];
+ readonly default: T;
+ readonly options: readonly T[];
}
// The actual decorators
@@ -34,14 +34,16 @@
// Ensure the settings property exists on the constructor's prototype
const proto = target.constructor.prototype;
if (!proto.hasOwnProperty('settings')) {
- proto.settings = {};
+ // Initialize with a base type that can be extended
+ Object.defineProperty(proto, 'settings', {
+ value: {},
+ writable: true, // Allows adding properties
+ configurable: true,
+ enumerable: true
+ });
}
-
+
// Add the setting to the prototype's settings object with const assertion
proto.settings[propertyKey] = {
type: 'boolean' as const,
...options
};
- };
-}
-
-export function StringSetting(options: StringSettingOptions): PropertyDecorator {
- return (target: Object, propertyKey: string | symbol) => {
- // Ensure the settings property exists on the constructor's prototype
- const proto = target.constructor.prototype;
- if (!proto.hasOwnProperty('settings')) {
- proto.settings = {};
- }
-
- // Add the setting to the prototype's settings object with const assertion
- proto.settings[propertyKey] = {
- type: 'string' as const,
- ...options
- };
};
}
@@ -50,14 +52,16 @@
// Ensure the settings property exists on the constructor's prototype
const proto = target.constructor.prototype;
if (!proto.hasOwnProperty('settings')) {
- proto.settings = {};
+ Object.defineProperty(proto, 'settings', {
+ value: {},
+ writable: true,
+ configurable: true,
+ enumerable: true
+ });
}
-
+
// Add the setting to the prototype's settings object with const assertion
proto.settings[propertyKey] = {
type: 'number' as const,
...options
};
- };
-}
-
-export function SelectSetting<T extends string>(options: SelectSettingOptions<T>): PropertyDecorator {
- return (target: Object, propertyKey: string | symbol) => {
- // Ensure the settings property exists on the constructor's prototype
- const proto = target.constructor.prototype;
- if (!proto.hasOwnProperty('settings')) {
- proto.settings = {};
- }
-
- // Add the setting to the prototype's settings object with const assertion
- proto.settings[propertyKey] = {
- type: 'select' as const,
- ...options
- };
};
}
// Base plugin class that handles settings
export abstract class BasePlugin<T extends PluginSettings = PluginSettings> {
// The settings property will be populated by decorators
- settings!: T;
-
+ // Keep the instance property and constructor logic as is,
+ // as changing it would require changing animated-background/index.ts
+ settings!: T; // Use definite assignment assertion
+
constructor() {
// Copy settings from the prototype to the instance
// This ensures that each instance has its own settings object
-28
View File
@@ -1010,34 +1010,6 @@ div > ol:has(.uiFileHandlerWrapper) {
margin-right: 157.5px; margin-right: 157.5px;
gap: 12px; gap: 12px;
} }
.bg {
animation: slide 3s ease-in-out infinite alternate;
background: var(--better-main);
bottom: 0;
left: -50%;
opacity: 0.5;
position: fixed;
right: -50%;
top: 0;
z-index: 0 !important;
overflow: hidden;
scale: 1.5;
}
.bg2 {
animation-direction: alternate-reverse;
animation-duration: 4s;
}
.bg3 {
animation-duration: 5s;
}
@keyframes slide {
0% {
transform: translate(50%) rotate(-60deg);
}
100% {
transform: translateX(5%) rotate(-60deg);
}
}
.home-root { .home-root {
width: 100%; width: 100%;
display: flex; display: flex;
@@ -0,0 +1,72 @@
import type { Plugin } from '../../core/types';
import styles from './styles.css?inline';
import { BasePlugin, NumberSetting } from '../../core/settings';
class AnimatedBackgroundPluginClass extends BasePlugin {
@NumberSetting({
default: 1,
title: "Animation Speed",
description: "Controls the speed of the animated background",
min: 0.1,
max: 2
})
speed!: number;
}
const settingsInstance = new AnimatedBackgroundPluginClass();
const animatedBackgroundPlugin: Plugin<typeof settingsInstance.settings> = {
id: 'animated-background',
name: 'Animated Background',
description: 'Adds an animated background to BetterSEQTA+',
version: '1.0.0',
disableToggle: true,
styles,
settings: settingsInstance.settings,
run: async (api) => {
// Create the background elements
const container = document.getElementById("container");
const menu = document.getElementById("menu");
if (!container || !menu) {
return () => {};
}
const backgrounds = [
{ classes: ["bg"] },
{ classes: ["bg", "bg2"] },
{ classes: ["bg", "bg3"] }
];
backgrounds.forEach(({ classes }) => {
const bk = document.createElement("div");
classes.forEach(cls => bk.classList.add(cls));
container.insertBefore(bk, menu);
});
// Set initial speed
updateAnimationSpeed(api.settings.speed);
// Listen for speed changes
const speedUnregister = api.settings.onChange('speed', updateAnimationSpeed);
// Return cleanup function
return () => {
speedUnregister.unregister();
// Remove background elements
const backgrounds = document.getElementsByClassName('bg');
Array.from(backgrounds).forEach(element => element.remove());
};
}
};
function updateAnimationSpeed(speed: number) {
const bgElements = document.getElementsByClassName('bg');
Array.from(bgElements).forEach((element, index) => {
const baseSpeed = index === 0 ? 3 : index === 1 ? 4 : 5;
(element as HTMLElement).style.animationDuration = `${baseSpeed / speed}s`;
});
}
export default animatedBackgroundPlugin;
@@ -0,0 +1,31 @@
.bg {
animation: slide 3s ease-in-out infinite alternate;
background: var(--better-main);
bottom: 0;
left: -50%;
opacity: 0.5;
position: fixed;
right: -50%;
top: 0;
z-index: 0 !important;
overflow: hidden;
scale: 1.5;
}
.bg2 {
animation-direction: alternate-reverse;
animation-duration: 4s;
}
.bg3 {
animation-duration: 5s;
}
@keyframes slide {
0% {
transform: translate(50%) rotate(-60deg);
}
100% {
transform: translateX(5%) rotate(-60deg);
}
}
@@ -0,0 +1,24 @@
export function CreateBackground() {
const bkCheck = document.getElementsByClassName("bg");
if (bkCheck.length !== 0) {
return;
}
// Creating and inserting 3 divs containing the background applied to the pages
const container = document.getElementById("container");
const menu = document.getElementById("menu");
if (!container || !menu) return;
const backgrounds = [
{ classes: ["bg"] },
{ classes: ["bg", "bg2"] },
{ classes: ["bg", "bg3"] }
];
backgrounds.forEach(({ classes }) => {
const bk = document.createElement("div");
classes.forEach(cls => bk.classList.add(cls));
container.insertBefore(bk, menu);
});
}
@@ -0,0 +1,6 @@
export function RemoveBackground() {
const backgrounds = document.getElementsByClassName("bg");
// Convert HTMLCollection to Array and remove each element
Array.from(backgrounds).forEach(element => element.remove());
}
+71 -14
View File
@@ -41,15 +41,28 @@ function createSEQTAAPI(): SEQTAAPI {
function createSettingsAPI<T extends PluginSettings>(plugin: Plugin<T>): SettingsAPI<T> & { loaded: Promise<void> } { function createSettingsAPI<T extends PluginSettings>(plugin: Plugin<T>): SettingsAPI<T> & { loaded: Promise<void> } {
const storageKey = `plugin.${plugin.id}.settings`; const storageKey = `plugin.${plugin.id}.settings`;
const listeners = new Map<keyof T, Set<(value: any) => void>>();
let settings: { [K in keyof T]: T[K]['default'] }; // Use SettingValue to properly type the listeners
// This ensures callbacks get correctly typed parameters
const listeners = new Map<keyof T, Set<(value: SettingValue<T[keyof T]>) => void>>();
let settings: { [K in keyof T]: SettingValue<T[K]> };
const storageListeners = new Set<(changes: { [key: string]: any }, area: string) => void>(); const storageListeners = new Set<(changes: { [key: string]: any }, area: string) => void>();
// Initialize settings with defaults // Initialize settings with defaults and proper typing
settings = Object.entries(plugin.settings).reduce((acc, [key, setting]) => { settings = Object.entries(plugin.settings).reduce((acc, [key, setting]) => {
acc[key as keyof T] = setting.default; // Extract the value from the default based on the setting type
if (setting.type === 'boolean') {
acc[key as keyof T] = setting.default as SettingValue<T[keyof T]>;
} else if (setting.type === 'number') {
acc[key as keyof T] = setting.default as SettingValue<T[keyof T]>;
} else if (setting.type === 'string') {
acc[key as keyof T] = setting.default as SettingValue<T[keyof T]>;
} else if (setting.type === 'select') {
acc[key as keyof T] = setting.default as SettingValue<T[keyof T]>;
}
return acc; return acc;
}, {} as { [K in keyof T]: T[K]['default'] }); }, {} as { [K in keyof T]: SettingValue<T[K]> });
// Create a promise that resolves when settings are loaded // Create a promise that resolves when settings are loaded
const loaded = (async () => { const loaded = (async () => {
@@ -58,9 +71,22 @@ function createSettingsAPI<T extends PluginSettings>(plugin: Plugin<T>): Setting
if (stored[storageKey]) { if (stored[storageKey]) {
Object.entries(stored[storageKey]).forEach(([key, value]) => { Object.entries(stored[storageKey]).forEach(([key, value]) => {
if (key in settings) { if (key in settings) {
settings[key as keyof T] = value as any; // Use proper type assertion based on the setting type
const settingType = plugin.settings[key as keyof T].type;
if (settingType === 'boolean' && typeof value === 'boolean') {
settings[key as keyof T] = value as SettingValue<T[keyof T]>;
} else if (settingType === 'number' && typeof value === 'number') {
settings[key as keyof T] = value as SettingValue<T[keyof T]>;
} else if (settingType === 'string' && typeof value === 'string') {
settings[key as keyof T] = value as SettingValue<T[keyof T]>;
} else if (settingType === 'select' && typeof value === 'string') {
settings[key as keyof T] = value as SettingValue<T[keyof T]>;
}
// Notify any listeners that might have been registered already // Notify any listeners that might have been registered already
listeners.get(key as keyof T)?.forEach(callback => callback(value)); listeners.get(key as keyof T)?.forEach(callback =>
callback(settings[key as keyof T] as SettingValue<T[keyof T]>)
);
} }
}); });
} }
@@ -76,8 +102,24 @@ function createSettingsAPI<T extends PluginSettings>(plugin: Plugin<T>): Setting
if (newValue) { if (newValue) {
// Update settings and notify listeners // Update settings and notify listeners
Object.entries(newValue).forEach(([key, value]) => { Object.entries(newValue).forEach(([key, value]) => {
settings[key as keyof T] = value as any; if (key in settings) {
listeners.get(key as keyof T)?.forEach(callback => callback(value)); // Use proper type assertion based on the setting type
const settingType = plugin.settings[key as keyof T].type;
if (settingType === 'boolean' && typeof value === 'boolean') {
settings[key as keyof T] = value as SettingValue<T[keyof T]>;
} else if (settingType === 'number' && typeof value === 'number') {
settings[key as keyof T] = value as SettingValue<T[keyof T]>;
} else if (settingType === 'string' && typeof value === 'string') {
settings[key as keyof T] = value as SettingValue<T[keyof T]>;
} else if (settingType === 'select' && typeof value === 'string') {
settings[key as keyof T] = value as SettingValue<T[keyof T]>;
}
// Notify listeners with the correctly typed value
listeners.get(key as keyof T)?.forEach(callback =>
callback(settings[key as keyof T] as SettingValue<T[keyof T]>)
);
}
}); });
} }
} }
@@ -89,14 +131,14 @@ function createSettingsAPI<T extends PluginSettings>(plugin: Plugin<T>): Setting
const proxy = new Proxy(settings, { const proxy = new Proxy(settings, {
get(target, prop: string) { get(target, prop: string) {
if (prop === 'onChange') { if (prop === 'onChange') {
return (key: keyof T, callback: (value: any) => void) => { return <K extends keyof T>(key: K, callback: (value: SettingValue<T[K]>) => void) => {
if (!listeners.has(key)) { if (!listeners.has(key)) {
listeners.set(key, new Set()); listeners.set(key, new Set());
} }
listeners.get(key)!.add(callback); listeners.get(key)!.add(callback as (value: SettingValue<T[keyof T]>) => void);
return { return {
unregister: () => { unregister: () => {
listeners.get(key)?.delete(callback); listeners.get(key)?.delete(callback as (value: SettingValue<T[keyof T]>) => void);
} }
}; };
}; };
@@ -108,7 +150,20 @@ function createSettingsAPI<T extends PluginSettings>(plugin: Plugin<T>): Setting
}, },
set(target, prop: string, value: any) { set(target, prop: string, value: any) {
if (prop === 'onChange' || prop === 'offChange' || prop === 'loaded') return false; if (prop === 'onChange' || prop === 'offChange' || prop === 'loaded') return false;
target[prop as keyof T] = value;
// Try to apply the right type based on the setting definition
if (prop in plugin.settings) {
const settingType = plugin.settings[prop as keyof T].type;
if (settingType === 'boolean' && typeof value === 'boolean') {
target[prop as keyof T] = value as SettingValue<T[keyof T]>;
} else if (settingType === 'number' && typeof value === 'number') {
target[prop as keyof T] = value as SettingValue<T[keyof T]>;
} else if (settingType === 'string' && typeof value === 'string') {
target[prop as keyof T] = value as SettingValue<T[keyof T]>;
} else if (settingType === 'select' && typeof value === 'string') {
target[prop as keyof T] = value as SettingValue<T[keyof T]>;
}
}
// Store all settings under the plugin's settings key // Store all settings under the plugin's settings key
browser.storage.local.set({ browser.storage.local.set({
@@ -116,7 +171,9 @@ function createSettingsAPI<T extends PluginSettings>(plugin: Plugin<T>): Setting
}); });
// Notify listeners // Notify listeners
listeners.get(prop as keyof T)?.forEach(callback => callback(value)); listeners.get(prop as keyof T)?.forEach(callback =>
callback(target[prop as keyof T] as SettingValue<T[keyof T]>)
);
return true; return true;
}, },
}) as SettingsAPI<T> & { loaded: Promise<void> }; }) as SettingsAPI<T> & { loaded: Promise<void> };
+16
View File
@@ -19,6 +19,7 @@ export class PluginManager {
private eventBacklog: Map<string, any[]> = new Map(); private eventBacklog: Map<string, any[]> = new Map();
private cleanupFunctions: Map<string, () => void> = new Map(); private cleanupFunctions: Map<string, () => void> = new Map();
private listeners: Map<string, Set<(...args: any[]) => void>> = new Map(); private listeners: Map<string, Set<(...args: any[]) => void>> = new Map();
private styleElements: Map<string, HTMLStyleElement> = new Map();
private constructor() { private constructor() {
this.setupPluginStateListener(); this.setupPluginStateListener();
@@ -89,6 +90,14 @@ export class PluginManager {
return; return;
} }
} }
// Inject plugin styles if provided
if (plugin.styles) {
const styleElement = document.createElement('style');
styleElement.textContent = plugin.styles;
document.head.appendChild(styleElement);
this.styleElements.set(pluginId, styleElement);
}
// Wait for both settings and storage to be loaded before starting the plugin // Wait for both settings and storage to be loaded before starting the plugin
await Promise.all([ await Promise.all([
@@ -123,6 +132,13 @@ export class PluginManager {
} }
public async stopPlugin(pluginId: string): Promise<void> { public async stopPlugin(pluginId: string): Promise<void> {
// Remove plugin styles
const styleElement = this.styleElements.get(pluginId);
if (styleElement) {
styleElement.remove();
this.styleElements.delete(pluginId);
}
const cleanup = this.cleanupFunctions.get(pluginId); const cleanup = this.cleanupFunctions.get(pluginId);
if (cleanup) { if (cleanup) {
cleanup(); cleanup();
+10 -10
View File
@@ -37,9 +37,9 @@ export function BooleanSetting(options: BooleanSettingOptions): PropertyDecorato
proto.settings = {}; proto.settings = {};
} }
// Add the setting to the prototype's settings object // Add the setting to the prototype's settings object with const assertion
proto.settings[propertyKey] = { proto.settings[propertyKey] = {
type: 'boolean', type: 'boolean' as const,
...options ...options
}; };
}; };
@@ -53,9 +53,9 @@ export function StringSetting(options: StringSettingOptions): PropertyDecorator
proto.settings = {}; proto.settings = {};
} }
// Add the setting to the prototype's settings object // Add the setting to the prototype's settings object with const assertion
proto.settings[propertyKey] = { proto.settings[propertyKey] = {
type: 'string', type: 'string' as const,
...options ...options
}; };
}; };
@@ -69,9 +69,9 @@ export function NumberSetting(options: NumberSettingOptions): PropertyDecorator
proto.settings = {}; proto.settings = {};
} }
// Add the setting to the prototype's settings object // Add the setting to the prototype's settings object with const assertion
proto.settings[propertyKey] = { proto.settings[propertyKey] = {
type: 'number', type: 'number' as const,
...options ...options
}; };
}; };
@@ -85,9 +85,9 @@ export function SelectSetting<T extends string>(options: SelectSettingOptions<T>
proto.settings = {}; proto.settings = {};
} }
// Add the setting to the prototype's settings object // Add the setting to the prototype's settings object with const assertion
proto.settings[propertyKey] = { proto.settings[propertyKey] = {
type: 'select', type: 'select' as const,
...options ...options
}; };
}; };
@@ -96,13 +96,13 @@ export function SelectSetting<T extends string>(options: SelectSettingOptions<T>
// Base plugin class that handles settings // Base plugin class that handles settings
export abstract class BasePlugin<T extends PluginSettings = PluginSettings> { export abstract class BasePlugin<T extends PluginSettings = PluginSettings> {
// The settings property will be populated by decorators // The settings property will be populated by decorators
settings: T = {} as T; settings!: T;
constructor() { constructor() {
// Copy settings from the prototype to the instance // Copy settings from the prototype to the instance
// This ensures that each instance has its own settings object // This ensures that each instance has its own settings object
if (this.constructor.prototype.settings) { if (this.constructor.prototype.settings) {
this.settings = { ...this.constructor.prototype.settings }; this.settings = { ...this.constructor.prototype.settings } as T;
} }
} }
} }
+3 -2
View File
@@ -41,7 +41,7 @@ export type PluginSettings = {
} }
// Helper type to extract the actual value type from a setting // Helper type to extract the actual value type from a setting
type SettingValue<T extends PluginSetting> = T extends BooleanSetting ? boolean : export type SettingValue<T extends PluginSetting> = T extends BooleanSetting ? boolean :
T extends StringSetting ? string : T extends StringSetting ? string :
T extends NumberSetting ? number : T extends NumberSetting ? number :
T extends SelectSetting<infer O> ? O : T extends SelectSetting<infer O> ? O :
@@ -50,7 +50,7 @@ type SettingValue<T extends PluginSetting> = T extends BooleanSetting ? boolean
export type SettingsAPI<T extends PluginSettings> = { export type SettingsAPI<T extends PluginSettings> = {
[K in keyof T]: SettingValue<T[K]>; [K in keyof T]: SettingValue<T[K]>;
} & { } & {
onChange: <K extends keyof T>(key: K, callback: (value: SettingValue<T[K]>) => void) => void; onChange: <K extends keyof T>(key: K, callback: (value: SettingValue<T[K]>) => void) => { unregister: () => void };
offChange: <K extends keyof T>(key: K, callback: (value: SettingValue<T[K]>) => void) => void; offChange: <K extends keyof T>(key: K, callback: (value: SettingValue<T[K]>) => void) => void;
loaded: Promise<void>; // Promise that resolves when settings are loaded loaded: Promise<void>; // Promise that resolves when settings are loaded
} }
@@ -96,6 +96,7 @@ export interface Plugin<T extends PluginSettings = PluginSettings, S = any> {
description: string; description: string;
version: string; version: string;
settings: T; settings: T;
styles?: string; // Optional CSS styles for the plugin
disableToggle?: boolean; // Optional flag to show/hide the plugin's enable/disable toggle in settings disableToggle?: boolean; // Optional flag to show/hide the plugin's enable/disable toggle in settings
run: (api: PluginAPI<T, S>) => void | Promise<void> | (() => void) | Promise<(() => void)>; run: (api: PluginAPI<T, S>) => void | Promise<void> | (() => void) | Promise<(() => void)>;
} }
+2
View File
@@ -4,6 +4,7 @@ import { PluginManager } from './core/manager';
import timetablePlugin from './built-in/timetable'; import timetablePlugin from './built-in/timetable';
import notificationCollectorPlugin from './built-in/notificationCollector'; import notificationCollectorPlugin from './built-in/notificationCollector';
import themesPlugin from './built-in/themes'; import themesPlugin from './built-in/themes';
import animatedBackgroundPlugin from './built-in/animated-background';
// Initialize plugin manager // Initialize plugin manager
const pluginManager = PluginManager.getInstance(); const pluginManager = PluginManager.getInstance();
@@ -12,6 +13,7 @@ const pluginManager = PluginManager.getInstance();
pluginManager.registerPlugin(timetablePlugin); pluginManager.registerPlugin(timetablePlugin);
pluginManager.registerPlugin(notificationCollectorPlugin); pluginManager.registerPlugin(notificationCollectorPlugin);
pluginManager.registerPlugin(themesPlugin); pluginManager.registerPlugin(themesPlugin);
pluginManager.registerPlugin(animatedBackgroundPlugin);
//pluginManager.registerPlugin(testPlugin); //pluginManager.registerPlugin(testPlugin);
export { init as Monofile } from './monofile'; export { init as Monofile } from './monofile';
-8
View File
@@ -1,12 +1,10 @@
import { addExtensionSettings } from "@/seqta/utils/Adders/AddExtensionSettings"; import { addExtensionSettings } from "@/seqta/utils/Adders/AddExtensionSettings";
import { enableAnimatedBackground } from "@/seqta/utils/CreateEnable/EnableAnimatedBackground";
import { loadHomePage } from "@/seqta/utils/Loaders/LoadHomePage"; import { loadHomePage } from "@/seqta/utils/Loaders/LoadHomePage";
import { SendNewsPage } from "@/seqta/utils/SendNewsPage"; import { SendNewsPage } from "@/seqta/utils/SendNewsPage";
import { setupSettingsButton } from "@/seqta/utils/setupSettingsButton"; import { setupSettingsButton } from "@/seqta/utils/setupSettingsButton";
import { GetThresholdOfColor } from "@/seqta/ui/colors/getThresholdColour"; import { GetThresholdOfColor } from "@/seqta/ui/colors/getThresholdColour";
import { updateBgDurations } from "./Animation";
import { appendBackgroundToUI } from "./ImageBackgrounds"; import { appendBackgroundToUI } from "./ImageBackgrounds";
import stringToHTML from "@/seqta/utils/stringToHTML"; import stringToHTML from "@/seqta/utils/stringToHTML";
import { settingsState } from "@/seqta/utils/listeners/SettingsState"; import { settingsState } from "@/seqta/utils/listeners/SettingsState";
@@ -42,7 +40,6 @@ async function getUserInfo() {
export async function AddBetterSEQTAElements() { export async function AddBetterSEQTAElements() {
if (settingsState.onoff) { if (settingsState.onoff) {
initializeSettings();
if (settingsState.DarkMode) { if (settingsState.DarkMode) {
document.documentElement.classList.add('dark'); document.documentElement.classList.add('dark');
} }
@@ -76,11 +73,6 @@ export async function AddBetterSEQTAElements() {
setupSettingsButton(); setupSettingsButton();
} }
function initializeSettings() {
enableAnimatedBackground();
updateBgDurations();
}
function createHomeButton(fragment: DocumentFragment, menuList: HTMLElement) { function createHomeButton(fragment: DocumentFragment, menuList: HTMLElement) {
const container = document.getElementById('content')!; const container = document.getElementById('content')!;
const div = document.createElement('div'); const div = document.createElement('div');
-37
View File
@@ -1,37 +0,0 @@
import { settingsState } from "@/seqta/utils/listeners/SettingsState";
/**
* 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() {
// Class names to look for
const bgClasses = ['bg', 'bg2', 'bg3'];
// Function to calculate animation duration
const calcDuration = (
baseValue: number,
offset = 0,
minBase = 50,
maxBase = 150,
) => {
const scaledValue = 2 + ((maxBase - baseValue) / (maxBase - minBase)) ** 4;
return scaledValue + offset;
};
// Iterate through each class name to update its animation duration
bgClasses.forEach((className, index) => {
const elements = document.getElementsByClassName(className);
if (elements.length === 0) {
return;
}
const offset = index * 0.05;
const duration = calcDuration(parseInt(settingsState.bksliderinput), offset);
(elements[0] as HTMLElement).style.animationDuration = `${duration}s`;
(elements[0] as HTMLElement).style.animationDelay = `${offset * 5}s`;
});
}
@@ -1,23 +0,0 @@
export function CreateBackground() {
var bkCheck = document.getElementsByClassName("bg")
if (bkCheck.length !== 0) {
return
}
// 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)
}
@@ -1,13 +0,0 @@
import { settingsState } from "../listeners/SettingsState"
import { CreateBackground } from "./CreateBackground"
import { RemoveBackground } from "../DisableRemove/RemoveBackground"
export function enableAnimatedBackground() {
if (settingsState.animatedbk) {
CreateBackground()
} else {
RemoveBackground()
document.getElementById("container")!.style.background =
"var(--background-secondary)"
}
}
@@ -1,10 +0,0 @@
export function RemoveBackground() {
var bk = document.getElementsByClassName("bg")
var bk2 = document.getElementsByClassName("bg2")
var bk3 = document.getElementsByClassName("bg3")
if (bk.length == 0 || bk2.length == 0 || bk3.length == 0) return
bk[0].remove()
bk2[0].remove()
bk3[0].remove()
}
@@ -3,14 +3,11 @@ import { updateAllColors } from '@/seqta/ui/colors/Manager';
import { addShortcuts } from "@/seqta/utils/Adders/AddShortcuts"; import { addShortcuts } from "@/seqta/utils/Adders/AddShortcuts";
import { CreateBackground } from "@/seqta/utils/CreateEnable/CreateBackground";
import { CreateCustomShortcutDiv } from "@/seqta/utils/CreateEnable/CreateCustomShortcutDiv"; import { CreateCustomShortcutDiv } from "@/seqta/utils/CreateEnable/CreateCustomShortcutDiv";
import { FilterUpcomingAssessments } from "@/seqta/utils/FilterUpcomingAssessments"; import { FilterUpcomingAssessments } from "@/seqta/utils/FilterUpcomingAssessments";
import { RemoveBackground } from "@/seqta/utils/DisableRemove/RemoveBackground";
import { RemoveShortcutDiv } from "@/seqta/utils/DisableRemove/RemoveShortcutDiv"; import { RemoveShortcutDiv } from "@/seqta/utils/DisableRemove/RemoveShortcutDiv";
import { updateBgDurations } from '@/seqta/ui/Animation';
import browser from 'webextension-polyfill'; import browser from 'webextension-polyfill';
import type { CustomShortcut } from '@/types/storage'; import type { CustomShortcut } from '@/types/storage';
@@ -25,8 +22,6 @@ export class StorageChangeHandler {
settingsState.register('onoff', this.handleOnOffChange.bind(this)); settingsState.register('onoff', this.handleOnOffChange.bind(this));
settingsState.register('shortcuts', this.handleShortcutsChange.bind(this)); settingsState.register('shortcuts', this.handleShortcutsChange.bind(this));
settingsState.register('customshortcuts', this.handleCustomShortcutsChange.bind(this)); settingsState.register('customshortcuts', this.handleCustomShortcutsChange.bind(this));
settingsState.register('bksliderinput', updateBgDurations.bind(this));
settingsState.register('animatedbk', this.handleAnimatedBkChange.bind(this));
settingsState.register('transparencyEffects', this.handleTransparencyEffectsChange.bind(this)); settingsState.register('transparencyEffects', this.handleTransparencyEffectsChange.bind(this));
settingsState.register('subjectfilters', FilterUpcomingAssessments.bind(this)); settingsState.register('subjectfilters', FilterUpcomingAssessments.bind(this));
} }
@@ -83,15 +78,6 @@ export class StorageChangeHandler {
RemoveShortcutDiv(removedShortcuts); RemoveShortcutDiv(removedShortcuts);
} }
private handleAnimatedBkChange(newValue: boolean) {
if (newValue) {
CreateBackground();
} else {
RemoveBackground();
document.getElementById('container')!.style.background = 'var(--background-secondary)';
}
}
private handleTransparencyEffectsChange(newValue: boolean) { private handleTransparencyEffectsChange(newValue: boolean) {
if (newValue) { if (newValue) {
document.documentElement.classList.add('transparencyEffects'); document.documentElement.classList.add('transparencyEffects');