Align sidebar loading indicators and history heading

This commit is contained in:
thePR0M3TH3AN committed 2025-10-01 13:42:50 -04:00
1 parent 259bd3b281
commit 284bab6cff
8 files changed
+97 -36

No files matched your search

+23 -6
View File
@@ -1144,12 +1144,6 @@ button:not(.icon-button):focus {
display: flex;
}
.watch-history-status {
display: inline-flex;
align-items: center;
gap: 0.5rem;
}
.status-spinner--inline {
animation: spin 1s linear infinite;
border: 0.125rem solid rgba(96, 165, 250, 0.35);
@@ -1160,6 +1154,29 @@ button:not(.icon-button):focus {
width: 1rem;
}
.sidebar-loading-wrapper {
display: flex;
justify-content: center;
align-items: center;
padding: 3rem 0;
width: 100%;
grid-column: 1 / -1;
}
.sidebar-loading-indicator {
display: inline-flex;
align-items: center;
gap: 0.75rem;
color: #6b7280;
font-size: 0.875rem;
font-weight: 500;
letter-spacing: 0.01em;
}
.sidebar-loading-text {
white-space: nowrap;
}
.status-banner {
align-items: center;
background-color: rgba(31, 41, 55, 0.9);
+4 -4
View File
@@ -42,6 +42,7 @@ import {
} from "./storage/r2-s3.js";
import { initQuickR2Upload } from "./r2-quick.js";
import { createWatchHistoryRenderer } from "./historyView.js";
import { getSidebarLoadingMarkup } from "./sidebarLoading.js";
import {
initViewCounter,
subscribeToVideoViewCount,
@@ -7534,10 +7535,9 @@ class bitvidApp {
if (!this.videoSubscription) {
if (this.videoList) {
this.lastRenderedVideoSignature = null;
this.videoList.innerHTML = `
<p class="text-center text-gray-500">
Loading videos as they arrive...
</p>`;
this.videoList.innerHTML = getSidebarLoadingMarkup(
"Fetching recent videos…"
);
}
// Create a new subscription
+5 -8
View File
@@ -4,6 +4,7 @@ import { nostrClient } from "./nostr.js";
import { WATCH_HISTORY_BATCH_RESOLVE } from "./config.js";
import { subscriptions } from "./subscriptions.js";
import { accessControl } from "./accessControl.js";
import { getSidebarLoadingMarkup } from "./sidebarLoading.js";
const DEFAULT_BATCH_SIZE = 20;
const BATCH_SIZE = WATCH_HISTORY_BATCH_RESOLVE ? DEFAULT_BATCH_SIZE : 1;
@@ -672,14 +673,10 @@ export function createWatchHistoryRenderer(config = {}) {
const nextMessage = typeof message === "string" ? message.trim() : "";
if (nextMessage) {
if (nextMessage === WATCH_HISTORY_LOADING_STATUS) {
statusEl.innerHTML =
'<span class="watch-history-status watch-history-status--loading"><span class="status-spinner status-spinner--inline" aria-hidden="true"></span><span>' +
WATCH_HISTORY_LOADING_STATUS +
"</span></span>";
} else {
statusEl.textContent = nextMessage;
}
const showSpinner = nextMessage === WATCH_HISTORY_LOADING_STATUS;
statusEl.innerHTML = getSidebarLoadingMarkup(nextMessage, {
showSpinner,
});
statusEl.classList.remove("hidden");
} else {
statusEl.textContent = "";
+33
View File
@@ -0,0 +1,33 @@
// js/sidebarLoading.js
function escapeHtml(value) {
if (typeof value !== "string") {
return "";
}
return value
.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;")
.replace(/'/g, "&#39;");
}
export function getSidebarLoadingMarkup(message = "", options = {}) {
const trimmed = typeof message === "string" ? message.trim() : "";
const copy = trimmed || "Fetching data…";
const safeCopy = escapeHtml(copy);
const showSpinner = options?.showSpinner !== false;
const spinnerMarkup = showSpinner
? '<span class="status-spinner status-spinner--inline" aria-hidden="true"></span>'
: "";
return `
<div class="sidebar-loading-wrapper" role="status" aria-live="polite">
<div class="sidebar-loading-indicator">
${spinnerMarkup}
<span class="sidebar-loading-text">${safeCopy}</span>
</div>
</div>
`;
}
+3
View File
@@ -9,6 +9,7 @@ import {
buildSubscriptionListEvent,
SUBSCRIPTION_LIST_IDENTIFIER,
} from "./nostrEventSchemas.js";
import { getSidebarLoadingMarkup } from "./sidebarLoading.js";
function getAbsoluteShareUrl(nevent) {
if (!nevent) {
@@ -226,6 +227,8 @@ class SubscriptionsManager {
return;
}
container.innerHTML = getSidebarLoadingMarkup("Fetching subscriptions…");
// Gather all videos
const videos = await this.fetchSubscribedVideos(channelHexes);
this.renderSameGridStyle(videos, containerId);
+15 -16
View File
@@ -1,21 +1,20 @@
<!-- views/history.html -->
<section id="watchHistoryView" class="space-y-6">
<div class="flex items-center justify-between">
<h2 class="text-2xl font-semibold text-white">Watch History</h2>
</div>
<div
id="watchHistoryLoading"
class="flex flex-col items-center justify-center py-12 space-y-4"
>
<div
class="h-10 w-10 border-4 border-blue-500 border-t-transparent rounded-full animate-spin"
aria-hidden="true"
></div>
<p
id="watchHistoryStatus"
class="text-gray-300 text-center hidden"
aria-live="polite"
></p>
<h2 class="text-xl mb-4 text-gray-700">Watch History</h2>
<div id="watchHistoryLoading">
<div id="watchHistoryStatus">
<div class="sidebar-loading-wrapper" role="status" aria-live="polite">
<div class="sidebar-loading-indicator">
<span
class="status-spinner status-spinner--inline"
aria-hidden="true"
></span>
<span class="sidebar-loading-text"
>Fetching watch history from relays…</span
>
</div>
</div>
</div>
</div>
<div id="watchHistoryGrid" class="watch-history-grid hidden"></div>
<p id="watchHistoryEmpty" class="hidden text-gray-400 text-center py-12">
+6 -1
View File
@@ -8,6 +8,11 @@
id="videoList"
class="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-8"
>
<!-- Videos will be dynamically inserted here -->
<div class="sidebar-loading-wrapper" role="status" aria-live="polite">
<div class="sidebar-loading-indicator">
<span class="status-spinner status-spinner--inline" aria-hidden="true"></span>
<span class="sidebar-loading-text">Fetching recent videos…</span>
</div>
</div>
</div>
</section>
+8 -1
View File
@@ -9,5 +9,12 @@
gap: 2rem;
padding: 1.5rem 0;
"
></div>
>
<div class="sidebar-loading-wrapper" role="status" aria-live="polite">
<div class="sidebar-loading-indicator">
<span class="status-spinner status-spinner--inline" aria-hidden="true"></span>
<span class="sidebar-loading-text">Fetching subscriptions…</span>
</div>
</div>
</div>
</section>