From 34010f80cf490df1620a021c3bb7fb4cdc546980 Mon Sep 17 00:00:00 2001 From: Max Litruv Boonzaayer Date: Fri, 3 Oct 2025 05:24:43 +1000 Subject: [PATCH] Add loading indicator for post fetching and error handling --- website/main.js | 40 +++++++++++++++++++++++++++++++++++++ website/style.css | 50 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+) diff --git a/website/main.js b/website/main.js index a36813f..7b826ba 100644 --- a/website/main.js +++ b/website/main.js @@ -481,6 +481,9 @@ async function processPostQueue() { } isProcessingQueue = false; + + // Hide loading indicator when all posts are processed + hideLoadingIndicator(); } function layoutPosts(postElements) { @@ -504,7 +507,31 @@ function layoutPosts(postElements) { }, 200); } +function showLoadingIndicator() { + const postsContainer = document.getElementById("posts"); + const loadingDiv = document.createElement("div"); + loadingDiv.id = "loading-posts"; + loadingDiv.className = "loading-posts"; + loadingDiv.innerHTML = ` +
+
+ Loading posts... +
+ `; + postsContainer.appendChild(loadingDiv); +} + +function hideLoadingIndicator() { + const loadingDiv = document.getElementById("loading-posts"); + if (loadingDiv) { + loadingDiv.remove(); + } +} + async function fetchPosts() { + // Show loading indicator + showLoadingIndicator(); + try { const res = await fetch( "https://public.api.bsky.app/xrpc/app.bsky.feed.getAuthorFeed?actor=lit.mates.dev&limit=20&filter=posts_no_replies" @@ -567,6 +594,19 @@ async function fetchPosts() { } catch (err) { console.error("Error fetching posts:", err); + // Hide loading indicator on error + hideLoadingIndicator(); + + // Show error message + const postsContainer = document.getElementById("posts"); + const errorDiv = document.createElement("div"); + errorDiv.className = "loading-posts"; + errorDiv.innerHTML = ` +
+ ⚠ Failed to load posts. Please refresh the page. +
+ `; + postsContainer.appendChild(errorDiv); } } diff --git a/website/style.css b/website/style.css index 1b2c5c7..61dac20 100644 --- a/website/style.css +++ b/website/style.css @@ -658,4 +658,54 @@ footer a:hover { opacity: 0; transform: translateY(50px) rotate(var(--post-rotation, 0deg)); animation: slideUpFadeIn 0.6s cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards; +} + +/* Loading indicator styles */ +.loading-posts { + text-align: center; + margin: 2rem auto; + padding: 2rem; + background: var(--post-bg); + border: 2px solid var(--post-border); + box-shadow: 3px 3px 0 var(--shadow-light); + max-width: 400px; + transform: rotate(-1deg); + color: #666; + font-family: inherit; + position: relative; +} + +.loading-posts::before { + content: ""; + position: absolute; + top: 5px; + left: 0; + width: 100%; + height: 40px; + background-color: rgba(0, 0, 0, 0.05); + z-index: 0; + border-radius: 25%; + filter: blur(3px); +} + +.loading-posts-content { + position: relative; + z-index: 1; +} + +.loading-spinner { + display: inline-block; + width: 20px; + height: 20px; + border: 3px solid #f3f3f3; + border-top: 3px solid var(--accent); + border-radius: 50%; + animation: spin 1s linear infinite; + margin-right: 10px; + vertical-align: middle; +} + +@keyframes spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } } \ No newline at end of file