mirror of
https://github.com/BetterSEQTA/BetterSEQTA-Plus.git
synced 2026-06-06 03:34:40 +00:00
feat: simplify startup popups and convert engage announcement to toast
Remove auto-showing privacy statement and BS Cloud announcement from startup queue. Convert SEQTA Engage announcement from a blocking modal to a subtle bottom-right dismissable toast.
This commit is contained in:
@@ -4371,3 +4371,41 @@ h2.home-subtitle {
|
|||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.bsplus-toast {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 24px;
|
||||||
|
right: 24px;
|
||||||
|
z-index: 10000;
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 12px;
|
||||||
|
max-width: 380px;
|
||||||
|
padding: 16px 18px;
|
||||||
|
border-radius: 12px;
|
||||||
|
background: var(--background-secondary, #fff);
|
||||||
|
color: var(--text-primary, #1a1a1a);
|
||||||
|
box-shadow: 0 8px 30px rgba(0, 0, 0, 0.18);
|
||||||
|
font-size: 0.9rem;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
.bsplus-toast-content p {
|
||||||
|
margin: 6px 0 0;
|
||||||
|
opacity: 0.8;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
}
|
||||||
|
.bsplus-toast-close {
|
||||||
|
flex-shrink: 0;
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
color: var(--text-primary, #1a1a1a);
|
||||||
|
font-size: 1.3rem;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 0 2px;
|
||||||
|
line-height: 1;
|
||||||
|
opacity: 0.5;
|
||||||
|
transition: opacity 0.15s;
|
||||||
|
}
|
||||||
|
.bsplus-toast-close:hover {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,61 +1,54 @@
|
|||||||
import stringToHTML from "../stringToHTML";
|
|
||||||
import { settingsState } from "../listeners/SettingsState";
|
import { settingsState } from "../listeners/SettingsState";
|
||||||
import { openPopup } from "./PopupManager";
|
import { animate as motionAnimate } from "motion";
|
||||||
import { attachPopupMediaFullscreenIfPresent } from "./attachPopupMediaFullscreen";
|
|
||||||
|
|
||||||
/** Same hosting pattern as the privacy statement branding images (avoids page-relative extension URLs on Engage). */
|
|
||||||
const ENGAGE_PROMO_IMG_URL =
|
|
||||||
"https://raw.githubusercontent.com/BetterSEQTA/BetterSEQTA-Plus/main/src/resources/bq%2Bengage.png";
|
|
||||||
|
|
||||||
export function shouldShowEngageParentsAnnouncement(): boolean {
|
export function shouldShowEngageParentsAnnouncement(): boolean {
|
||||||
return !settingsState.engageParentsAnnouncementShown;
|
return !settingsState.engageParentsAnnouncementShown;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* One-time announcement that BetterSEQTA Plus works on SEQTA Engage (parents).
|
* Non-blocking bottom-right toast announcing SEQTA Engage support. Shown once.
|
||||||
*/
|
*/
|
||||||
export function showEngageParentsAnnouncement(onDismissed?: () => void) {
|
export function showEngageParentsToast() {
|
||||||
if (document.getElementById("whatsnewbk")) {
|
if (!shouldShowEngageParentsAnnouncement()) return;
|
||||||
onDismissed?.();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!shouldShowEngageParentsAnnouncement()) {
|
|
||||||
onDismissed?.();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const header = stringToHTML(
|
|
||||||
/* html */
|
|
||||||
`<div class="whatsnewHeader engageParentsAnnouncementHeader">
|
|
||||||
<h1>BetterSEQTA Plus now supports <span class="seqtaEngageAccent">SEQTA Engage</span></h1>
|
|
||||||
<p class="engageParentsSubheading">Buy your mom a BetterSEQTA Plus</p>
|
|
||||||
</div>`,
|
|
||||||
).firstChild as HTMLElement;
|
|
||||||
|
|
||||||
const text = stringToHTML(/* html */ `
|
|
||||||
<div class="whatsnewTextContainer privacyStatement" style="overflow-y: auto; font-size: 1.2rem; line-height: 1.6;">
|
|
||||||
<div class="engageParentsPromoWrap">
|
|
||||||
<img class="engageParentsPromoImg" src="${ENGAGE_PROMO_IMG_URL}" width="1920" height="1080" alt="BetterSEQTA Plus now supports SEQTA Engage" />
|
|
||||||
</div>
|
|
||||||
<p>
|
|
||||||
BetterSEQTA Plus now supports <strong class="seqtaEngageAccent">SEQTA Engage</strong>, so parents get the same kinds of improvements you are used to on SEQTA Learn—themes, a clearer home experience, and other Plus polish while browsing Engage.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
The title is a bit of fun; if the extension saves you time, you can always support development via Open Collective or Ko-fi from the What is New changelog or related links in settings.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Close this dialog when you are done. We will not show this announcement again.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
`).firstChild as HTMLElement;
|
|
||||||
|
|
||||||
attachPopupMediaFullscreenIfPresent(text, ".engageParentsPromoImg");
|
|
||||||
|
|
||||||
settingsState.engageParentsAnnouncementShown = true;
|
settingsState.engageParentsAnnouncementShown = true;
|
||||||
|
|
||||||
openPopup({
|
const toast = document.createElement("div");
|
||||||
header,
|
toast.className = "bsplus-toast";
|
||||||
content: [text],
|
toast.innerHTML = /* html */ `
|
||||||
afterClose: onDismissed,
|
<div class="bsplus-toast-content">
|
||||||
});
|
<strong>BetterSEQTA+ now supports <span class="seqtaEngageAccent">SEQTA Engage</span></strong>
|
||||||
|
<p>Buy your mum a BetterSEQTA Plus! Parents now get themes, a cleaner home page, and all the Plus polish on SEQTA Engage.</p>
|
||||||
|
</div>
|
||||||
|
<button class="bsplus-toast-close" aria-label="Dismiss">×</button>
|
||||||
|
`;
|
||||||
|
|
||||||
|
toast.style.opacity = "0";
|
||||||
|
document.getElementById("container")?.append(toast);
|
||||||
|
|
||||||
|
if (settingsState.animations) {
|
||||||
|
(motionAnimate as any)(
|
||||||
|
toast,
|
||||||
|
{ opacity: [0, 1], y: [40, 0] },
|
||||||
|
{ duration: 0.35, easing: [0.22, 0.03, 0.26, 1] },
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
toast.style.opacity = "1";
|
||||||
|
}
|
||||||
|
|
||||||
|
const dismiss = () => {
|
||||||
|
if (settingsState.animations) {
|
||||||
|
(motionAnimate as any)(
|
||||||
|
toast,
|
||||||
|
{ opacity: [1, 0], y: [0, 40] },
|
||||||
|
{ duration: 0.2, easing: [0.22, 0.03, 0.26, 1] },
|
||||||
|
).then(() => toast.remove());
|
||||||
|
} else {
|
||||||
|
toast.remove();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
toast.querySelector(".bsplus-toast-close")!.addEventListener("click", dismiss);
|
||||||
|
|
||||||
|
setTimeout(dismiss, 10000);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,24 +1,15 @@
|
|||||||
import { settingsState } from "../listeners/SettingsState";
|
import { settingsState } from "../listeners/SettingsState";
|
||||||
import { OpenWhatsNewPopup } from "./OpenWhatsNewPopup";
|
import { OpenWhatsNewPopup } from "./OpenWhatsNewPopup";
|
||||||
import {
|
|
||||||
shouldShowPrivacyNotification,
|
|
||||||
showPrivacyNotification,
|
|
||||||
} from "./OpenPrivacyNotification";
|
|
||||||
import {
|
import {
|
||||||
shouldShowEngageParentsAnnouncement,
|
shouldShowEngageParentsAnnouncement,
|
||||||
showEngageParentsAnnouncement,
|
showEngageParentsToast,
|
||||||
} from "./OpenEngageParentsAnnouncement";
|
} from "./OpenEngageParentsAnnouncement";
|
||||||
import {
|
|
||||||
shouldShowBsCloudAutoSyncAnnouncement,
|
|
||||||
showBsCloudAutoSyncAnnouncement,
|
|
||||||
} from "./OpenBsCloudAutoSyncAnnouncement";
|
|
||||||
|
|
||||||
type QueueStep = (goNext: () => void) => void;
|
type QueueStep = (goNext: () => void) => void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Runs startup modals in order: What's New (if the extension just updated),
|
* Runs startup modals in order: What's New (if the extension just updated),
|
||||||
* privacy statement (if required), SEQTA Engage announcement (once), then BS Cloud
|
* then shows the SEQTA Engage toast (once, non-blocking).
|
||||||
* auto-sync (once, last).
|
|
||||||
*/
|
*/
|
||||||
export function runStartupPopupQueue() {
|
export function runStartupPopupQueue() {
|
||||||
const steps: QueueStep[] = [];
|
const steps: QueueStep[] = [];
|
||||||
@@ -27,21 +18,14 @@ export function runStartupPopupQueue() {
|
|||||||
steps.push((goNext) => OpenWhatsNewPopup(goNext));
|
steps.push((goNext) => OpenWhatsNewPopup(goNext));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shouldShowPrivacyNotification()) {
|
|
||||||
steps.push((goNext) => showPrivacyNotification(goNext));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (shouldShowEngageParentsAnnouncement()) {
|
|
||||||
steps.push((goNext) => showEngageParentsAnnouncement(goNext));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (shouldShowBsCloudAutoSyncAnnouncement()) {
|
|
||||||
steps.push((goNext) => showBsCloudAutoSyncAnnouncement(goNext));
|
|
||||||
}
|
|
||||||
|
|
||||||
function runNext() {
|
function runNext() {
|
||||||
const step = steps.shift();
|
const step = steps.shift();
|
||||||
if (step) step(runNext);
|
if (step) step(runNext);
|
||||||
|
else {
|
||||||
|
if (shouldShowEngageParentsAnnouncement()) {
|
||||||
|
showEngageParentsToast();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
runNext();
|
runNext();
|
||||||
|
|||||||
Reference in New Issue
Block a user