mirror of
https://github.com/BetterSEQTA/BetterSEQTA-Plus.git
synced 2026-06-05 19:24:39 +00:00
feat: auto lesson navigation command
This commit is contained in:
@@ -1660,6 +1660,10 @@ iframe.userHTML {
|
|||||||
background: var(--auto-background);
|
background: var(--auto-background);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.pane .navigator::after {
|
||||||
|
content: unset !important;
|
||||||
|
}
|
||||||
|
|
||||||
.programmeNavigator {
|
.programmeNavigator {
|
||||||
box-shadow: 0 0 40px 0px rgba(0,0,0,0.05);
|
box-shadow: 0 0 40px 0px rgba(0,0,0,0.05);
|
||||||
|
|
||||||
|
|||||||
@@ -421,17 +421,3 @@
|
|||||||
<span>{text}</span>
|
<span>{text}</span>
|
||||||
</div>
|
</div>
|
||||||
{/snippet}
|
{/snippet}
|
||||||
|
|
||||||
<style>
|
|
||||||
:global(.highlight) {
|
|
||||||
background-color: rgba(200, 200, 200, 0.3);
|
|
||||||
font-weight: 500;
|
|
||||||
border-radius: 2px;
|
|
||||||
padding: 0 2px;
|
|
||||||
margin: 0 -2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dark :global(.highlight) {
|
|
||||||
background-color: rgba(79, 79, 79, 0.2);
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
import { settingsState } from "@/seqta/utils/listeners/SettingsState";
|
import { settingsState } from "@/seqta/utils/listeners/SettingsState";
|
||||||
import { loadHomePage } from "@/seqta/utils/Loaders/LoadHomePage";
|
import { loadHomePage } from "@/seqta/utils/Loaders/LoadHomePage";
|
||||||
|
import { waitForElm } from "@/seqta/utils/waitForElm";
|
||||||
|
|
||||||
export interface BaseCommandItem {
|
export interface BaseCommandItem {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -16,6 +17,121 @@ export interface StaticCommandItem extends BaseCommandItem {
|
|||||||
keybindLabel?: string[];
|
keybindLabel?: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Function to get current lesson
|
||||||
|
async function getCurrentLesson() {
|
||||||
|
const date = new Date();
|
||||||
|
const todayFormatted = formatDate(date);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch(`${location.origin}/seqta/student/load/timetable?`, {
|
||||||
|
method: "POST",
|
||||||
|
headers: { "Content-Type": "application/json" },
|
||||||
|
body: JSON.stringify({
|
||||||
|
from: todayFormatted,
|
||||||
|
until: todayFormatted,
|
||||||
|
student: 69,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
const timetableData = await response.json();
|
||||||
|
|
||||||
|
if (!timetableData.payload.items.length) {
|
||||||
|
alert("No lessons today!");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const lessons = timetableData.payload.items.sort((a: any, b: any) =>
|
||||||
|
a.from.localeCompare(b.from)
|
||||||
|
);
|
||||||
|
|
||||||
|
const currentTime = new Date();
|
||||||
|
|
||||||
|
for (const lesson of lessons) {
|
||||||
|
const [startHour, startMinute] = lesson.from.split(":").map(Number);
|
||||||
|
const [endHour, endMinute] = lesson.until.split(":").map(Number);
|
||||||
|
|
||||||
|
const startDate = new Date(currentTime);
|
||||||
|
startDate.setHours(startHour, startMinute, 0);
|
||||||
|
|
||||||
|
const endDate = new Date(currentTime);
|
||||||
|
endDate.setHours(endHour, endMinute, 0);
|
||||||
|
|
||||||
|
if (startDate <= currentTime && endDate > currentTime) {
|
||||||
|
return lesson;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
alert("There is no current lesson!");
|
||||||
|
return null;
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error fetching current lesson:", error);
|
||||||
|
alert("Error getting current lesson. Please try again.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function navigateToSpecificLesson(lesson: any) {
|
||||||
|
try {
|
||||||
|
await waitForElm(".course .navigator", true, 100, 100);
|
||||||
|
|
||||||
|
const today = new Date();
|
||||||
|
const todayDateString = today.toLocaleDateString('en-GB', {
|
||||||
|
day: 'numeric',
|
||||||
|
month: 'short'
|
||||||
|
});
|
||||||
|
|
||||||
|
const weeks = document.querySelectorAll(".course .navigator .week");
|
||||||
|
|
||||||
|
for (const week of weeks) {
|
||||||
|
// Look for lessons in this week
|
||||||
|
const lessons = week.querySelectorAll(".lesson");
|
||||||
|
|
||||||
|
for (const lessonElement of lessons) {
|
||||||
|
const metaElement = lessonElement.querySelector(".meta");
|
||||||
|
if (!metaElement) continue;
|
||||||
|
|
||||||
|
const dateElement = metaElement.querySelector(".date");
|
||||||
|
const periodElement = metaElement.querySelector(".period");
|
||||||
|
|
||||||
|
if (!dateElement || !periodElement) continue;
|
||||||
|
|
||||||
|
const lessonDate = dateElement.textContent?.trim();
|
||||||
|
const lessonPeriod = periodElement.textContent?.trim().match(/\d+/)?.[0];
|
||||||
|
|
||||||
|
// extract the number from the period
|
||||||
|
const normalizedLessonPeriod = lesson.period?.match(/\d+/)?.[0];
|
||||||
|
|
||||||
|
// Check if this lesson matches today's date and the current lesson's period
|
||||||
|
if (lessonDate === todayDateString && lessonPeriod === normalizedLessonPeriod) {
|
||||||
|
// Found the exact matching lesson, click it
|
||||||
|
(lessonElement as HTMLElement).click();
|
||||||
|
console.log(`Navigated to exact lesson: ${lessonDate} ${lessonPeriod}`);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const todayButton = Array.from(document.querySelectorAll('#toolbar .uiButton'))
|
||||||
|
.find(button => button.textContent?.trim() === 'Today') as HTMLElement;
|
||||||
|
|
||||||
|
if (todayButton) {
|
||||||
|
todayButton.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error navigating to specific lesson:", error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatDate(date: Date): string {
|
||||||
|
const year = date.getFullYear();
|
||||||
|
const month = (date.getMonth() + 1).toString().padStart(2, "0");
|
||||||
|
const day = date.getDate().toString().padStart(2, "0");
|
||||||
|
return `${year}-${month}-${day}`;
|
||||||
|
}
|
||||||
|
|
||||||
const staticCommands: StaticCommandItem[] = [
|
const staticCommands: StaticCommandItem[] = [
|
||||||
{
|
{
|
||||||
id: "home",
|
id: "home",
|
||||||
@@ -48,6 +164,22 @@ const staticCommands: StaticCommandItem[] = [
|
|||||||
},
|
},
|
||||||
priority: 4,
|
priority: 4,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: "Current Lesson",
|
||||||
|
icon: "\ue9a5",
|
||||||
|
category: "navigation",
|
||||||
|
text: "Current Lesson",
|
||||||
|
priority: 4,
|
||||||
|
action: async () => {
|
||||||
|
const currentLesson = await getCurrentLesson();
|
||||||
|
if (currentLesson && currentLesson.programmeID !== 0) {
|
||||||
|
// Navigate to course page first
|
||||||
|
window.location.hash = `?page=/courses/${currentLesson.programmeID}:${currentLesson.metaID}`;
|
||||||
|
|
||||||
|
await navigateToSpecificLesson(currentLesson);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
id: "assessments",
|
id: "assessments",
|
||||||
icon: "\ueac3",
|
icon: "\ueac3",
|
||||||
@@ -70,15 +202,6 @@ const staticCommands: StaticCommandItem[] = [
|
|||||||
window.location.hash = "?page=/dashboard";
|
window.location.hash = "?page=/dashboard";
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
id: "toggle-dark-mode",
|
|
||||||
icon: "\uecfe",
|
|
||||||
category: "action",
|
|
||||||
text: "Toggle Dark Mode",
|
|
||||||
action: () => (settingsState.DarkMode = !settingsState.DarkMode),
|
|
||||||
priority: 2,
|
|
||||||
keywords: ["theme", "appearance"],
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
id: "compose-message",
|
id: "compose-message",
|
||||||
icon: "\ue924",
|
icon: "\ue924",
|
||||||
@@ -94,7 +217,16 @@ const staticCommands: StaticCommandItem[] = [
|
|||||||
}, "*");
|
}, "*");
|
||||||
},
|
},
|
||||||
keywords: ["compose", "message", "dm", "direct message", "new message"],
|
keywords: ["compose", "message", "dm", "direct message", "new message"],
|
||||||
priority: 4,
|
priority: 3,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "toggle-dark-mode",
|
||||||
|
icon: "\uecfe",
|
||||||
|
category: "action",
|
||||||
|
text: "Toggle Dark Mode",
|
||||||
|
action: () => (settingsState.DarkMode = !settingsState.DarkMode),
|
||||||
|
priority: 3,
|
||||||
|
keywords: ["theme", "appearance"],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ export async function searchVectors(
|
|||||||
|
|
||||||
// filter results with a similarity below 0.81
|
// filter results with a similarity below 0.81
|
||||||
const filteredResults = results.filter((r) => r.similarity > 0.81);
|
const filteredResults = results.filter((r) => r.similarity > 0.81);
|
||||||
console.log("Vector search results", filteredResults);
|
|
||||||
|
|
||||||
return filteredResults as VectorSearchResult[];
|
return filteredResults as VectorSearchResult[];
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user