schoolbox web extension :)
1import { getCurrentPeriod } from "@/utils/periodUtils";
2import { definePlugin } from "@/utils/plugin";
3
4export default function init() {
5 definePlugin(
6 "subheader",
7 (settings) => {
8 const style = document.createElement("style");
9 style.classList = "schooltape";
10 style.innerHTML = `
11 .subheader span:not(:last-child):not(.period:empty)::after {
12 content: " | ";
13 font-weight: bold;
14 }
15 .subheader a {
16 color: inherit;
17 }
18 `;
19
20 document.head.appendChild(style);
21
22 if (window.location.pathname === "/" && document.getElementsByClassName("timetable")[0]) {
23 createSubheader();
24 setInterval(updatePeriodSpan, 5000);
25 setInterval(updateClockSpan, 1000);
26 setInterval(updateDateSpan, 60000);
27 }
28
29 function createSubheader() {
30 const subheader = document.querySelector("h2.subheader");
31 if (!subheader) return;
32 // TODO: Refactor to support hot reload/uninjection
33 // delete all children of the subheader
34 while (subheader.firstChild) {
35 subheader.removeChild(subheader.firstChild);
36 }
37 const span = document.createElement("span");
38 span.classList.add("schooltape");
39 subheader.appendChild(span);
40
41 updatePeriodSpan();
42 updateClockSpan();
43 updateDateSpan();
44 }
45
46 async function updatePeriodSpan() {
47 let periodSpan = document.querySelector(".subheader .period");
48 if (!periodSpan) {
49 const subheader = document.querySelector(".subheader .schooltape");
50 if (!subheader) return;
51 periodSpan = document.createElement("span");
52 periodSpan.classList.add("period");
53 subheader.appendChild(periodSpan);
54 }
55 periodSpan.textContent = "";
56
57 const period = getCurrentPeriod();
58 if (period) {
59 const name = period.data.name || period.header.name;
60 const room = period.data.room ? ` (${period.data.room})` : "";
61 let periodLink = periodSpan.querySelector("a");
62 if (period.data.name && period.data.link) {
63 // if there's period data
64 if (!periodLink) {
65 periodLink = document.createElement("a");
66
67 periodLink.target = settings?.toggle.openInNewTab ? "_blank" : "_self";
68 periodSpan.appendChild(periodLink);
69 }
70 periodLink.href = period.data.link;
71 periodLink.textContent = `${name}${room}`;
72 } else {
73 // if there's only the header
74 periodSpan.textContent = `${name}${room}`;
75 if (periodLink) {
76 periodSpan.removeChild(periodLink);
77 }
78 }
79 }
80 }
81
82 function updateClockSpan() {
83 let clockSpan = document.querySelector(".subheader .clock");
84 if (!clockSpan) {
85 const subheader = document.querySelector(".subheader .schooltape");
86 if (!subheader) return;
87 clockSpan = document.createElement("span");
88 clockSpan.classList.add("clock");
89 subheader.appendChild(clockSpan);
90 }
91 const date = new Date();
92 clockSpan.textContent = date.toLocaleTimeString([], {
93 hour: "2-digit",
94 minute: "2-digit",
95 });
96 }
97
98 function updateDateSpan() {
99 let dateSpan = document.querySelector(".subheader .date");
100 if (!dateSpan) {
101 const subheader = document.querySelector(".subheader .schooltape");
102 if (!subheader) return;
103 dateSpan = document.createElement("span");
104 dateSpan.classList.add("date");
105 subheader.appendChild(dateSpan);
106 }
107 const date = new Date();
108 dateSpan.textContent = date.toDateString();
109 }
110 },
111 [".subheader"],
112 );
113}