From af93330bf5c42d60c17d2f9558a36653b34b222e Mon Sep 17 00:00:00 2001 From: Nathan Woodburn Date: Thu, 3 Jul 2025 13:17:38 +1000 Subject: [PATCH] feat: Preloader inital test --- server.py | 28 ---- templates/assets/js/loading-enhanced.js | 154 ++++++++++++++++++++ templates/assets/js/loading-enhanced.min.js | 1 + templates/loading.html | 29 ++++ 4 files changed, 184 insertions(+), 28 deletions(-) create mode 100644 templates/assets/js/loading-enhanced.js create mode 100644 templates/assets/js/loading-enhanced.min.js diff --git a/server.py b/server.py index c315cea..411b061 100644 --- a/server.py +++ b/server.py @@ -831,34 +831,6 @@ def blog_path(path): return blog.render_blog_page(path,handshake_scripts) -#TODO add rss json and xml for blog -# @app.route("/blog.rss") -# @app.route("/blog.xml") -# @app.route("/rss.xml") -# def blog_rss(): -# host = "https://" + request.host -# if ":" in request.host: -# host = "http://" + request.host -# # Generate RSS feed -# blog_pages = blog.list_blog_page_files() -# rss = f'Nathan.Woodburn/{host}See what I\'ve been up toen-us{datetime.datetime.blog(tz=datetime.timezone.utc).strftime("%a, %d %b %Y %H:%M:%S %z")}' -# for page in blog_pages: -# link = page.strip(".html") -# date = datetime.datetime.strptime(link, "%y_%m_%d") -# date = date.strftime("%A, %B %d, %Y") -# rss += f'What\'s Happening {date}{host}/blog/{link}Latest updates for {date}{host}/blog/{link}' -# rss += "" -# return make_response(rss, 200, {"Content-Type": "application/rss+xml"}) - -# @app.route("/blog.json") -# def blog_json(): -# blog_pages = blog.list_blog_page_files() -# host = "https://" + request.host -# if ":" in request.host: -# host = "http://" + request.host -# blog_pages = [{"url":host+"/blog/"+page.strip(".html"), "date":datetime.datetime.strptime(page.strip(".html"), "%y_%m_%d").strftime("%A, %B %d, %Y"), "title":"What's Happening "+datetime.datetime.strptime(page.strip(".html"), "%y_%m_%d").strftime("%A, %B %d, %Y")} for page in blog_pages] -# return jsonify(blog_pages) - # endregion diff --git a/templates/assets/js/loading-enhanced.js b/templates/assets/js/loading-enhanced.js new file mode 100644 index 0000000..8ee1aaf --- /dev/null +++ b/templates/assets/js/loading-enhanced.js @@ -0,0 +1,154 @@ +document.addEventListener("DOMContentLoaded", function() { + const loadingScreen = document.getElementById("loading-screen"); + + // Terminal simulation data + const commands = [ + { pre: '┌──(nathan@NWTux)-[~]', message: "cd Git" }, + { pre: '┌──(nathan@NWTux)-[~/Git]', message: "cd Nathanwoodburn.github.io" }, + { pre: '┌──(nathan@NWTux)-[~/Git/Nathanwoodburn.github.io]', message: "python3 main.py" } + ]; + + const serverMessages = [ + "Starting server with 1 workers and 2 threads", + "+0000] [1] [INFO] Starting gunicorn 22.0.0", + "+0000] [1] [INFO] Listening at: http://0.0.0.0:5000 (1)", + "+0000] [1] [INFO] Using worker: gthread", + "+0000] [8] [INFO] Booting worker with pid: 8", + "Preloading assets for faster navigation..." + ]; + + let currentCommand = 0; + let assetsLoaded = false; + let terminalComplete = false; + + // Enhanced asset preloading function + function preloadAssets() { + const assets = [ + // Additional CSS files that might not be in preload + '/assets/css/animate.min.min.css', + '/assets/css/fixes.min.css', + '/assets/css/Footer-Dark-icons.min.css', + '/assets/css/GridSystem-1.min.css', + // Font files + '/assets/fonts/fa-solid-900.woff2', + '/assets/fonts/fa-brands-400.woff2', + '/assets/fonts/fa-regular-400.woff2' + ]; + + let loadedCount = 0; + const totalAssets = assets.length; + + function onAssetLoad() { + loadedCount++; + if (loadedCount === totalAssets) { + assetsLoaded = true; + checkReadyToRedirect(); + } + } + + // Load additional assets + assets.forEach(assetUrl => { + const link = document.createElement('link'); + link.rel = 'preload'; + link.as = assetUrl.endsWith('.css') ? 'style' : + assetUrl.endsWith('.js') ? 'script' : + assetUrl.includes('/fonts/') ? 'font' : 'fetch'; + if (link.as === 'font') { + link.crossOrigin = 'anonymous'; + } + link.href = assetUrl; + link.onload = onAssetLoad; + link.onerror = onAssetLoad; // Count errors as loaded to prevent hanging + document.head.appendChild(link); + }); + + // If no additional assets, mark as loaded + if (totalAssets === 0) { + assetsLoaded = true; + checkReadyToRedirect(); + } + } + + function checkReadyToRedirect() { + if (assetsLoaded && terminalComplete) { + setTimeout(redirectToIndex, 200); + } + } + + function getCurrentTime() { + const now = new Date(); + return `${now.getUTCFullYear()}-${String(now.getUTCMonth() + 1).padStart(2, '0')}-${String(now.getUTCDate()).padStart(2, '0')} ${String(now.getUTCHours()).padStart(2, '0')}:${String(now.getUTCMinutes()).padStart(2, '0')}:${String(now.getUTCSeconds()).padStart(2, '0')}`; + } + + function displayServerMessages(messages, callback) { + const timestamp = getCurrentTime(); + + for (let i = 0; i < messages.length; i++) { + const messageDiv = document.createElement("div"); + messageDiv.classList.add("loading-line"); + messageDiv.innerHTML = i !== 0 ? "[" + timestamp + "] " + messages[i] : messages[i]; + loadingScreen.appendChild(messageDiv); + } + + callback(); + } + + function redirectToIndex() { + if (window.location.pathname === "/") { + window.location.reload(); + } else { + window.location.href = "/"; + } + } + + // Event listeners for manual redirect + window.addEventListener("keypress", redirectToIndex); + + if (window.innerWidth < 768) { + console.log("Screen width is less than 768px, allowing click to redirect"); + window.addEventListener("click", redirectToIndex); + } + + function typeCommand(command, callback) { + const preDiv = document.createElement("div"); + preDiv.classList.add("loading-pre"); + preDiv.innerHTML = command.pre; + loadingScreen.appendChild(preDiv); + + const commandDiv = document.createElement("div"); + commandDiv.classList.add("loading-line"); + commandDiv.innerHTML = '└─$ '; + loadingScreen.appendChild(commandDiv); + + let charIndex = 0; + const typeInterval = setInterval(() => { + commandDiv.removeChild(commandDiv.querySelector(".cursor")); + commandDiv.innerHTML += command.message[charIndex] + ''; + charIndex++; + + if (charIndex === command.message.length) { + commandDiv.removeChild(commandDiv.querySelector(".cursor")); + clearInterval(typeInterval); + callback(); + } + }, 50); + } + + function runTerminalSimulation() { + if (currentCommand < commands.length) { + typeCommand(commands[currentCommand], () => { + currentCommand++; + setTimeout(runTerminalSimulation, 200); + }); + } else { + displayServerMessages(serverMessages, () => { + terminalComplete = true; + checkReadyToRedirect(); + }); + } + } + + // Start the loading process + preloadAssets(); + runTerminalSimulation(); +}); diff --git a/templates/assets/js/loading-enhanced.min.js b/templates/assets/js/loading-enhanced.min.js new file mode 100644 index 0000000..9707582 --- /dev/null +++ b/templates/assets/js/loading-enhanced.min.js @@ -0,0 +1 @@ +document.addEventListener("DOMContentLoaded",(function(){const e=document.getElementById("loading-screen"),t=[{pre:'┌──(nathan@NWTux)-[~]',message:"cd Git"},{pre:'┌──(nathan@NWTux)-[~/Git]',message:"cd Nathanwoodburn.github.io"},{pre:'┌──(nathan@NWTux)-[~/Git/Nathanwoodburn.github.io]',message:"python3 main.py"}],n=["Starting server with 1 workers and 2 threads","+0000] [1] [INFO] Starting gunicorn 22.0.0","+0000] [1] [INFO] Listening at: http://0.0.0.0:5000 (1)","+0000] [1] [INFO] Using worker: gthread","+0000] [8] [INFO] Booting worker with pid: 8","Preloading assets for faster navigation..."];let a=0,s=!1,o=!1;function r(){s&&o&&setTimeout(c,200)}function l(){const t=["/assets/css/animate.min.min.css","/assets/css/fixes.min.css","/assets/css/Footer-Dark-icons.min.css","/assets/css/GridSystem-1.min.css","/assets/fonts/fa-solid-900.woff2","/assets/fonts/fa-brands-400.woff2","/assets/fonts/fa-regular-400.woff2"];let n=0;const a=t.length;function s(){n++,n===a&&(s=!0,r())}t.forEach((t=>{const n=document.createElement("link");n.rel="preload",n.as=t.endsWith(".css")?"style":t.endsWith(".js")?"script":t.includes("/fonts/")?"font":"fetch","font"===n.as&&(n.crossOrigin="anonymous"),n.href=t,n.onload=s,n.onerror=s,document.head.appendChild(n)})),0===a&&(s=!0,r())}function i(){const t=new Date;return`${t.getUTCFullYear()}-${String(t.getUTCMonth()+1).padStart(2,"0")}-${String(t.getUTCDate()).padStart(2,"0")} ${String(t.getUTCHours()).padStart(2,"0")}:${String(t.getUTCMinutes()).padStart(2,"0")}:${String(t.getUTCSeconds()).padStart(2,"0")}`}function d(t,n){const a=i();for(let n=0;n$ ',e.appendChild(s);let o=0;const r=setInterval((()=>{s.removeChild(s.querySelector(".cursor")),s.innerHTML+=t.message[o]+'',o++,o===t.message.length&&(s.removeChild(s.querySelector(".cursor")),clearInterval(r),n())}),50)}function g(){a{a++,setTimeout(g,200)})):d(n,(()=>{o=!0,r()}))}window.addEventListener("keypress",c),window.innerWidth<768&&(console.log("Screen width is less than 768px, allowing click to redirect"),window.addEventListener("click",c)),l(),g()})); diff --git a/templates/loading.html b/templates/loading.html index 1617046..8435206 100644 --- a/templates/loading.html +++ b/templates/loading.html @@ -33,6 +33,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +