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 =================
|
// ================= 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() {
|
async function initializeModules() {
|
||||||
try {
|
try {
|
||||||
const modules = await loadModules(getLanguage());
|
const modules = await loadModules(getLanguage());
|
||||||
@@ -257,9 +280,10 @@ async function initializeModules() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
updateProgressDisplay();
|
updateProgressDisplay();
|
||||||
|
clearLoadingTimeout();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Failed to load modules:", error);
|
console.error("Failed to load modules:", error);
|
||||||
elements.lessonDescription.textContent = t("failedToLoad");
|
showLoadingFallback();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -656,6 +680,9 @@ function init() {
|
|||||||
// Initialize CodeMirror editor
|
// Initialize CodeMirror editor
|
||||||
initCodeEditor();
|
initCodeEditor();
|
||||||
|
|
||||||
|
// Set timeout to show fallback if loading takes too long
|
||||||
|
loadingTimeout = setTimeout(showLoadingFallback, 3000);
|
||||||
|
|
||||||
// Load modules after editor is ready
|
// Load modules after editor is ready
|
||||||
initializeModules().catch(console.error);
|
initializeModules().catch(console.error);
|
||||||
|
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ const translations = {
|
|||||||
resetAll: "Reset All",
|
resetAll: "Reset All",
|
||||||
|
|
||||||
// Dynamic content
|
// Dynamic content
|
||||||
|
loadingFallbackText: "Could not load lesson. Please select one from the menu or check the help.",
|
||||||
completed: "Completed",
|
completed: "Completed",
|
||||||
successMessage: "CRISPY! ٩(◕‿◕)۶ Your code works correctly.",
|
successMessage: "CRISPY! ٩(◕‿◕)۶ Your code works correctly.",
|
||||||
keepTrying: "Keep trying!",
|
keepTrying: "Keep trying!",
|
||||||
@@ -180,6 +181,7 @@ const translations = {
|
|||||||
resetAll: "Alles zurücksetzen",
|
resetAll: "Alles zurücksetzen",
|
||||||
|
|
||||||
// Dynamic content
|
// Dynamic content
|
||||||
|
loadingFallbackText: "Lektion konnte nicht geladen werden. Bitte wähle eine aus dem Menü oder prüfe die Hilfe.",
|
||||||
completed: "Erledigt",
|
completed: "Erledigt",
|
||||||
successMessage: "CRISPY! ٩(◕‿◕)۶ Dein Code funktioniert.",
|
successMessage: "CRISPY! ٩(◕‿◕)۶ Dein Code funktioniert.",
|
||||||
keepTrying: "Weiter versuchen!",
|
keepTrying: "Weiter versuchen!",
|
||||||
|
|||||||
17
src/main.css
17
src/main.css
@@ -241,6 +241,23 @@ code, kbd {
|
|||||||
opacity: 0.3;
|
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 {
|
.module-pill {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|||||||
Reference in New Issue
Block a user