schoolbox web extension :)
1import { getCurrentPeriod } from "@/utils/periodUtils";
2import { Plugin } from "@/utils/plugin";
3import type { Slider, Toggle } from "@/utils/storage";
4import type { StorageState } from "@/utils/storage/state.svelte";
5
6let interval: NodeJS.Timeout | null = null;
7let controller: AbortController | null = null;
8
9export type Settings = {
10 resetCooldownOnMouseMove: StorageState<Toggle>;
11 cooldownDuration: StorageState<Slider>;
12};
13
14export default new Plugin<Settings>(
15 {
16 id: "scrollPeriod",
17 name: "Scroll Period",
18 description: "Scrolls to the current period on the timetable.",
19 },
20 true,
21 {
22 resetCooldownOnMouseMove: { toggle: true },
23 cooldownDuration: { min: 1, max: 60, value: 10 },
24 },
25 async (settings) => {
26 const timetable = document.querySelector("[data-timetable-container] div.scrollable");
27
28 if (window.location.pathname === "/" && timetable) {
29 updateScrollbar(timetable);
30
31 const cooldownDuration = await settings.cooldownDuration.get();
32 const resetCooldownOnMouseMove = await settings.resetCooldownOnMouseMove.get();
33
34 const setUpdateInterval = () => {
35 interval = setInterval(() => updateScrollbar(timetable), (cooldownDuration?.value || 10) * 1000);
36 };
37
38 setUpdateInterval();
39
40 if (resetCooldownOnMouseMove.toggle === true) {
41 controller = new AbortController();
42 document.addEventListener(
43 "mousemove",
44 () => {
45 if (interval) {
46 clearInterval(interval);
47 setUpdateInterval();
48 }
49 },
50 { signal: controller.signal },
51 );
52 }
53 }
54 },
55 () => {
56 if (controller) {
57 controller.abort();
58 controller = null;
59 }
60 if (interval) {
61 clearInterval(interval);
62 interval = null;
63 }
64 },
65 [".timetable"],
66);
67
68function updateScrollbar(timetable: Element) {
69 const currentPeriod = getCurrentPeriod();
70 if (currentPeriod && currentPeriod.index && timetable) {
71 const period = document.querySelector(`.timetable thead tr th:nth-child(${currentPeriod.index})`) as HTMLElement;
72 if (period) {
73 timetable.scroll({
74 left: period.offsetLeft - 55, // adjusted for alignment
75 behavior: "smooth", // or 'auto' for instant scroll
76 });
77 }
78 }
79}