mirror of
https://github.com/BetterSEQTA/BetterSEQTA-Plus.git
synced 2026-08-28 17:21:05 +00:00
feat: refine settings, stores, and message folders
This commit is contained in:
@@ -1,39 +1,9 @@
|
||||
import { unmount } from "svelte";
|
||||
|
||||
let remove: () => void;
|
||||
|
||||
export async function OpenStorePage(): Promise<void> {
|
||||
remove = await renderStore();
|
||||
}
|
||||
|
||||
export async function renderStore() {
|
||||
const [{ default: renderSvelte }, { default: Store }] = await Promise.all([
|
||||
import("@/interface/main"),
|
||||
import("@/interface/pages/store.svelte"),
|
||||
]);
|
||||
|
||||
const container =
|
||||
document.querySelector("#container") ??
|
||||
document.getElementById("content") ??
|
||||
document.body;
|
||||
|
||||
document.getElementById("store")?.remove();
|
||||
|
||||
const child = document.createElement("div");
|
||||
child.id = "store";
|
||||
container.appendChild(child);
|
||||
|
||||
const shadow = child.attachShadow({ mode: "open" });
|
||||
const app = renderSvelte(Store, shadow);
|
||||
|
||||
return () => unmount(app);
|
||||
}
|
||||
|
||||
export function closeStore() {
|
||||
document.getElementById("store")!.classList.add("hide");
|
||||
|
||||
setTimeout(() => {
|
||||
remove();
|
||||
document.getElementById("store")!.remove();
|
||||
}, 500);
|
||||
const [{ requestSettingsDestination }, { openSettingsPopup }] =
|
||||
await Promise.all([
|
||||
import("@/seqta/utils/settingsNavigation"),
|
||||
import("@/seqta/utils/setupSettingsButton"),
|
||||
]);
|
||||
requestSettingsDestination({ page: "themes", view: "store" });
|
||||
await openSettingsPopup();
|
||||
}
|
||||
|
||||
@@ -52,7 +52,12 @@ async function loadSettingsUi(extensionPopup: HTMLElement): Promise<void> {
|
||||
const mount = () => renderSvelte(Settings, shadow);
|
||||
|
||||
if ("requestIdleCallback" in window) {
|
||||
requestIdleCallback(mount);
|
||||
await new Promise<void>((resolve) => {
|
||||
requestIdleCallback(() => {
|
||||
mount();
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
} else {
|
||||
mount();
|
||||
}
|
||||
|
||||
@@ -11,14 +11,23 @@ export const closeExtensionPopup = (extensionPopup?: HTMLElement) => {
|
||||
|
||||
extensionPopup.classList.add("hide");
|
||||
if (settingsState.animations) {
|
||||
const panel = extensionPopup.shadowRoot?.querySelector<HTMLElement>(
|
||||
"[data-settings-panel]",
|
||||
);
|
||||
animate(1, 0, {
|
||||
onUpdate: (progress) => {
|
||||
extensionPopup.style.opacity = Math.max(0, progress).toString();
|
||||
},
|
||||
type: "spring",
|
||||
stiffness: 520,
|
||||
damping: 20,
|
||||
duration: 0.18,
|
||||
ease: "easeIn",
|
||||
});
|
||||
if (panel) {
|
||||
animate(
|
||||
panel,
|
||||
{ scale: [1, 0], opacity: [1, 0] },
|
||||
{ duration: 0.18, ease: "easeIn" },
|
||||
);
|
||||
}
|
||||
} else {
|
||||
extensionPopup.style.opacity = "0";
|
||||
}
|
||||
|
||||
@@ -311,10 +311,10 @@ export async function loadEngageHomePage(): Promise<void> {
|
||||
const engageHomeBody = stringToHTML(/* html */ `
|
||||
<div class="home-root" id="engage-home-root">
|
||||
<div class="home-container" id="engage-home-container">
|
||||
<div class="bsplus-rounded shortcut-container">
|
||||
<div class="bsplus-rounded shortcuts" id="shortcuts"></div>
|
||||
<div class="border shortcut-container">
|
||||
<div class="border shortcuts" id="shortcuts"></div>
|
||||
</div>
|
||||
<div class="bsplus-rounded timetable-container">
|
||||
<div class="border timetable-container">
|
||||
<div class="home-subtitle">
|
||||
<div class="engage-timetable-title-cluster">
|
||||
<h2 id="engage-home-lesson-subtitle">Today's Lessons</h2>
|
||||
@@ -331,7 +331,7 @@ export async function loadEngageHomePage(): Promise<void> {
|
||||
</div>
|
||||
<div class="day-container loading" id="engage-day-container"></div>
|
||||
</div>
|
||||
<div class="bsplus-rounded notices-container">
|
||||
<div class="border notices-container">
|
||||
<div style="display: flex; justify-content: space-between">
|
||||
<h2 class="home-subtitle">Notices</h2>
|
||||
<input type="date" id="engage-notices-date" />
|
||||
|
||||
@@ -62,10 +62,10 @@ export async function loadHomePage() {
|
||||
|
||||
const skeletonStructure = stringToHTML(/* html */ `
|
||||
<div class="home-container" id="home-container">
|
||||
<div class="bsplus-rounded shortcut-container">
|
||||
<div class="bsplus-rounded shortcuts" id="shortcuts"></div>
|
||||
<div class="border shortcut-container">
|
||||
<div class="border shortcuts" id="shortcuts"></div>
|
||||
</div>
|
||||
<div class="bsplus-rounded timetable-container">
|
||||
<div class="border timetable-container">
|
||||
<div class="home-subtitle">
|
||||
<h2 id="home-lesson-subtitle">Today's Lessons</h2>
|
||||
<div class="timetable-arrows">
|
||||
@@ -80,7 +80,7 @@ export async function loadHomePage() {
|
||||
<div class="day-container loading" id="day-container">
|
||||
</div>
|
||||
</div>
|
||||
<div class="bsplus-rounded upcoming-container">
|
||||
<div class="border upcoming-container">
|
||||
<div class="upcoming-title">
|
||||
<h2 class="home-subtitle">Upcoming Assessments</h2>
|
||||
<div class="upcoming-filters" id="upcoming-filters"></div>
|
||||
@@ -88,7 +88,7 @@ export async function loadHomePage() {
|
||||
<div class="upcoming-items loading" id="upcoming-items">
|
||||
</div>
|
||||
</div>
|
||||
<div class="bsplus-rounded notices-container">
|
||||
<div class="border notices-container">
|
||||
<div style="display: flex; justify-content: space-between">
|
||||
<h2 class="home-subtitle">Notices</h2>
|
||||
<input type="date" />
|
||||
|
||||
@@ -11,15 +11,9 @@ export function consumePendingHighlightThemeId(): string | null {
|
||||
|
||||
export async function openThemeStoreWithHighlight(themeId: string): Promise<void> {
|
||||
pendingHighlightThemeId = themeId;
|
||||
|
||||
const existing = document.getElementById("store");
|
||||
if (existing) {
|
||||
window.dispatchEvent(
|
||||
new CustomEvent("bsplus:highlight-theme", { detail: { themeId } }),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const { OpenStorePage } = await import("@/seqta/ui/renderStore");
|
||||
await OpenStorePage();
|
||||
window.dispatchEvent(
|
||||
new CustomEvent("bsplus:highlight-theme", { detail: { themeId } }),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
export type SettingsDestination =
|
||||
| { page: "settings"; section?: string }
|
||||
| { page: "themes" | "backgrounds"; view?: "settings" | "store" };
|
||||
|
||||
export const SETTINGS_NAVIGATION_EVENT = "bsplus:navigate-settings";
|
||||
|
||||
let pendingDestination: SettingsDestination | null = null;
|
||||
|
||||
export function requestSettingsDestination(destination: SettingsDestination): void {
|
||||
pendingDestination = destination;
|
||||
window.dispatchEvent(
|
||||
new CustomEvent(SETTINGS_NAVIGATION_EVENT, { detail: destination }),
|
||||
);
|
||||
}
|
||||
|
||||
export function consumeSettingsDestination(): SettingsDestination | null {
|
||||
const destination = pendingDestination;
|
||||
pendingDestination = null;
|
||||
return destination;
|
||||
}
|
||||
@@ -17,38 +17,57 @@ export function setupSettingsButton() {
|
||||
AddedSettings.dataset.bsplusSettingsBound = "1";
|
||||
|
||||
AddedSettings.addEventListener("click", async () => {
|
||||
// Re-query each click — Engage SPA navigations can recreate the host.
|
||||
let extensionPopup = document.getElementById("ExtensionPopup");
|
||||
if (!extensionPopup) {
|
||||
const { addExtensionSettings } = await import("./Adders/AddExtensionSettings");
|
||||
addExtensionSettings();
|
||||
extensionPopup = document.getElementById("ExtensionPopup");
|
||||
}
|
||||
if (!extensionPopup) return;
|
||||
|
||||
if (SettingsClicked) {
|
||||
closeExtensionPopup(extensionPopup);
|
||||
closeExtensionPopup();
|
||||
} else {
|
||||
await renderSettingsIfNeeded();
|
||||
|
||||
await delay(30);
|
||||
|
||||
extensionPopup.style.transform = "none";
|
||||
if (settingsState.animations) {
|
||||
animate(0, 1, {
|
||||
onUpdate: (progress) => {
|
||||
extensionPopup.style.opacity = progress.toString();
|
||||
},
|
||||
type: "spring",
|
||||
stiffness: 280,
|
||||
damping: 20,
|
||||
});
|
||||
} else {
|
||||
extensionPopup.style.opacity = "1";
|
||||
extensionPopup.style.transition = "opacity 0s linear";
|
||||
}
|
||||
extensionPopup.classList.remove("hide");
|
||||
changeSettingsClicked(true);
|
||||
await openSettingsPopup();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export async function openSettingsPopup(): Promise<void> {
|
||||
if (SettingsClicked && document.getElementById("ExtensionPopup")) return;
|
||||
|
||||
// Re-query each time — Engage SPA navigations can recreate the host.
|
||||
let extensionPopup = document.getElementById("ExtensionPopup");
|
||||
if (!extensionPopup) {
|
||||
const { addExtensionSettings } = await import("./Adders/AddExtensionSettings");
|
||||
addExtensionSettings();
|
||||
extensionPopup = document.getElementById("ExtensionPopup");
|
||||
}
|
||||
if (!extensionPopup) return;
|
||||
|
||||
await renderSettingsIfNeeded();
|
||||
await delay(30);
|
||||
|
||||
extensionPopup.style.transform = "none";
|
||||
const panel = extensionPopup.shadowRoot?.querySelector<HTMLElement>(
|
||||
"[data-settings-panel]",
|
||||
);
|
||||
if (settingsState.animations) {
|
||||
animate(0, 1, {
|
||||
onUpdate: (progress) => {
|
||||
extensionPopup.style.opacity = progress.toString();
|
||||
},
|
||||
type: "spring",
|
||||
stiffness: 280,
|
||||
damping: 20,
|
||||
});
|
||||
if (panel) {
|
||||
animate(
|
||||
panel,
|
||||
{ scale: [0, 1], opacity: [0, 1] },
|
||||
{ type: "spring", stiffness: 330, damping: 30 },
|
||||
);
|
||||
}
|
||||
} else {
|
||||
extensionPopup.style.opacity = "1";
|
||||
extensionPopup.style.transition = "opacity 0s linear";
|
||||
if (panel) {
|
||||
panel.style.scale = "1";
|
||||
panel.style.opacity = "1";
|
||||
}
|
||||
}
|
||||
extensionPopup.classList.remove("hide");
|
||||
changeSettingsClicked(true);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user