feat: keep preview glow permanently after animation completes
This commit is contained in:
@@ -539,6 +539,7 @@ function resetSuccessIndicators() {
|
||||
elements.previewWrapper?.classList.remove("matched");
|
||||
elements.previewWrapper?.classList.remove("completed-glow");
|
||||
elements.previewSection?.classList.remove("matched");
|
||||
elements.previewSection?.classList.remove("completed-glow");
|
||||
|
||||
// Remove completion badge if present
|
||||
const badge = document.querySelector(".completion-badge");
|
||||
@@ -661,8 +662,9 @@ function loadCurrentLesson() {
|
||||
elements.lessonTitleRow.appendChild(badge);
|
||||
}
|
||||
|
||||
// Show gradient border for completed lessons
|
||||
// Show gradient border and glow for completed lessons
|
||||
elements.previewWrapper?.classList.add("completed-glow");
|
||||
elements.previewSection?.classList.add("completed-glow");
|
||||
} else {
|
||||
elements.runBtn.querySelector("span").textContent = t("run");
|
||||
|
||||
@@ -670,6 +672,7 @@ function loadCurrentLesson() {
|
||||
const badge = document.querySelector(".completion-badge");
|
||||
if (badge) badge.remove();
|
||||
elements.previewWrapper?.classList.remove("completed-glow");
|
||||
elements.previewSection?.classList.remove("completed-glow");
|
||||
}
|
||||
|
||||
// Update level indicator (hide in playground mode)
|
||||
@@ -932,8 +935,9 @@ function runCode() {
|
||||
state.animationTimeout = setTimeout(() => {
|
||||
elements.previewWrapper?.classList.remove("matched");
|
||||
elements.previewSection?.classList.remove("matched");
|
||||
// Keep the gradient border visible after animation
|
||||
// Keep the gradient border and glow visible after animation
|
||||
elements.previewWrapper?.classList.add("completed-glow");
|
||||
elements.previewSection?.classList.add("completed-glow");
|
||||
state.animationTimeout = null;
|
||||
}, 3500);
|
||||
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
import { t, applyTranslations } from "./i18n.js";
|
||||
|
||||
// Analytics tracking helper
|
||||
function track(eventName, eventData = {}) {
|
||||
if (typeof umami !== "undefined" && umami.track) {
|
||||
umami.track(eventName, eventData);
|
||||
}
|
||||
}
|
||||
|
||||
let currentUser = null;
|
||||
let oauthHandled = false;
|
||||
let lessonEngineRef = null;
|
||||
@@ -40,6 +47,8 @@ export async function handleOAuthCallback() {
|
||||
|
||||
if (!error && data?.session) {
|
||||
oauthHandled = true;
|
||||
const provider = data.session.user?.app_metadata?.provider || "oauth";
|
||||
track("auth_login", { method: provider });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
14
src/main.css
14
src/main.css
@@ -662,6 +662,18 @@ kbd {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* Persistent glow for completed lessons */
|
||||
.preview-section.completed-glow::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: var(--spacing-md);
|
||||
border-radius: var(--border-radius-md);
|
||||
background: conic-gradient(from 0deg, #9163b8, #d45aa0, #1aafb8, #7c4dff, #9163b8);
|
||||
filter: blur(30px);
|
||||
opacity: 0.35;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.preview-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
@@ -813,7 +825,7 @@ kbd {
|
||||
}
|
||||
100% {
|
||||
--border-angle: -360deg;
|
||||
opacity: 0;
|
||||
opacity: 0.35;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user