diff --git a/src/interface/pages/settings.svelte b/src/interface/pages/settings.svelte index 5be5f0d2..bc1222db 100644 --- a/src/interface/pages/settings.svelte +++ b/src/interface/pages/settings.svelte @@ -55,6 +55,11 @@ closeExtensionPopup(); }; + const openPrivacyStatement = () => { + window.open("https://betterseqta.org/privacy", "_blank"); + closeExtensionPopup(); + }; + let { standalone } = $props<{ standalone?: boolean }>(); let showColourPicker = $state(false); @@ -101,25 +106,34 @@ /> {#if !standalone} - +
+ - + - + + +
{/if} diff --git a/src/plugins/monofile.ts b/src/plugins/monofile.ts index 4a692dad..b595e869 100644 --- a/src/plugins/monofile.ts +++ b/src/plugins/monofile.ts @@ -96,7 +96,13 @@ export async function finishLoad() { console.error("Error during loading cleanup:", err); } - if (settingsState.justupdated && !document.getElementById("whatsnewbk")) { + // Show privacy statement notification on first open of this version (before what's new) + if (!settingsState.privacyStatementShown && !document.getElementById("privacy-notification")) { + showPrivacyNotification(); + settingsState.privacyStatementShown = true; + } + + if (settingsState.justupdated && !document.getElementById("whatsnewbk") && !document.getElementById("privacy-notification")) { OpenWhatsNewPopup(); } } @@ -601,6 +607,86 @@ export function showConflictPopup() { }); } +export function showPrivacyNotification() { + if (document.getElementById("privacy-notification")) return; + + const background = document.createElement("div"); + background.id = "privacy-notification"; + background.classList.add("whatsnewBackground"); + background.style.zIndex = "10000001"; + + const container = document.createElement("div"); + container.classList.add("whatsnewContainer"); + container.style.height = "auto"; + container.style.maxWidth = "800px"; + container.style.width = "90%"; + + const headerHTML = /* html */ ` +
+

Privacy Statement

+

Important Information

+
+ `; + const header = stringToHTML(headerHTML).firstChild; + + const textHTML = /* html */ ` +
+

+ Several schools have expressed concerns about BetterSEQTA+. Security is at the core of what we do, and we would like to clarify any misinformation. As a Free, Libre, and Open Source software application, we ask you to thoroughly read our privacy policy and vet our code. We specifically want you to hold us accountable. +

+

+ To view our privacy policy, please click the shield icon in the settings menu, or click here. +

+

+ We have never collected, are not collecting, and will never collect any personal information about any user. That is a guarantee. +

+
+ `; + const text = stringToHTML(textHTML).firstChild; + + const exitButton = document.createElement("div"); + exitButton.id = "whatsnewclosebutton"; + + if (header) container.append(header); + if (text) container.append(text); + container.append(exitButton); + + background.append(container); + + document.getElementById("container")?.append(background); + + if (settingsState.animations) { + animate([background as HTMLElement], { opacity: [0, 1] }); + } + + background.addEventListener("click", (event) => { + if (event.target === background) { + background.remove(); + // Show what's new if it was waiting + if (settingsState.justupdated && !document.getElementById("whatsnewbk")) { + OpenWhatsNewPopup(); + } + } + }); + + exitButton.addEventListener("click", () => { + background.remove(); + // Show what's new if it was waiting + if (settingsState.justupdated && !document.getElementById("whatsnewbk")) { + OpenWhatsNewPopup(); + } + }); + + // Handle privacy link click - ensure it opens in new tab + const privacyLink = document.getElementById("privacy-link"); + if (privacyLink) { + privacyLink.addEventListener("click", (e) => { + e.preventDefault(); + window.open("https://betterseqta.org/privacy", "_blank", "noopener,noreferrer"); + }); + } +} + export function init() { const handleDisabled = () => { waitForElm(".code", true, 50).then(AppendElementsToDisabledPage); diff --git a/src/types/storage.ts b/src/types/storage.ts index a085567d..5b6e7c1d 100644 --- a/src/types/storage.ts +++ b/src/types/storage.ts @@ -30,6 +30,7 @@ export interface SettingsState { subjectfilters: Record; transparencyEffects: boolean; justupdated?: boolean; + privacyStatementShown?: boolean; timeFormat?: string; animations: boolean; defaultPage: string;