feat: add gentle loading fallback after 3 seconds
If no lesson loads within 3 seconds, show a centered, gray notice with fade-in animation suggesting to select from menu or check help. Includes link to help dialog.
This commit is contained in:
29
src/app.js
29
src/app.js
@@ -238,6 +238,29 @@ function restoreLessonCache() {
|
||||
|
||||
// ================= MODULE INITIALIZATION =================
|
||||
|
||||
let loadingTimeout = null;
|
||||
|
||||
function showLoadingFallback() {
|
||||
// Only show if no lesson is loaded yet
|
||||
if (!elements.lessonTitle.textContent) {
|
||||
elements.lessonDescription.innerHTML = `
|
||||
<div class="loading-fallback">
|
||||
<p>${t("loadingFallbackText")}</p>
|
||||
<button class="btn btn-text" onclick="document.getElementById('help-btn').click()">
|
||||
${t("help")}
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
function clearLoadingTimeout() {
|
||||
if (loadingTimeout) {
|
||||
clearTimeout(loadingTimeout);
|
||||
loadingTimeout = null;
|
||||
}
|
||||
}
|
||||
|
||||
async function initializeModules() {
|
||||
try {
|
||||
const modules = await loadModules(getLanguage());
|
||||
@@ -257,9 +280,10 @@ async function initializeModules() {
|
||||
}
|
||||
|
||||
updateProgressDisplay();
|
||||
clearLoadingTimeout();
|
||||
} catch (error) {
|
||||
console.error("Failed to load modules:", error);
|
||||
elements.lessonDescription.textContent = t("failedToLoad");
|
||||
showLoadingFallback();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -656,6 +680,9 @@ function init() {
|
||||
// Initialize CodeMirror editor
|
||||
initCodeEditor();
|
||||
|
||||
// Set timeout to show fallback if loading takes too long
|
||||
loadingTimeout = setTimeout(showLoadingFallback, 3000);
|
||||
|
||||
// Load modules after editor is ready
|
||||
initializeModules().catch(console.error);
|
||||
|
||||
|
||||
@@ -87,6 +87,7 @@ const translations = {
|
||||
resetAll: "Reset All",
|
||||
|
||||
// Dynamic content
|
||||
loadingFallbackText: "Could not load lesson. Please select one from the menu or check the help.",
|
||||
completed: "Completed",
|
||||
successMessage: "CRISPY! ٩(◕‿◕)۶ Your code works correctly.",
|
||||
keepTrying: "Keep trying!",
|
||||
@@ -180,6 +181,7 @@ const translations = {
|
||||
resetAll: "Alles zurücksetzen",
|
||||
|
||||
// Dynamic content
|
||||
loadingFallbackText: "Lektion konnte nicht geladen werden. Bitte wähle eine aus dem Menü oder prüfe die Hilfe.",
|
||||
completed: "Erledigt",
|
||||
successMessage: "CRISPY! ٩(◕‿◕)۶ Dein Code funktioniert.",
|
||||
keepTrying: "Weiter versuchen!",
|
||||
|
||||
17
src/main.css
17
src/main.css
@@ -241,6 +241,23 @@ code, kbd {
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
/* Loading fallback notice */
|
||||
.loading-fallback {
|
||||
text-align: center;
|
||||
padding: 3rem 1rem;
|
||||
color: var(--light-text);
|
||||
animation: fadeIn 0.5s ease;
|
||||
}
|
||||
|
||||
.loading-fallback p {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from { opacity: 0; }
|
||||
to { opacity: 1; }
|
||||
}
|
||||
|
||||
.module-pill {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
|
||||
Reference in New Issue
Block a user