mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-27 07:52:24 +00:00
Align sidebar loading indicators and history heading
This commit is contained in:
1 parent
259bd3b281
commit
284bab6cff
8 files changed
+96
-35
No files matched your search
+23
-6
@@ -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);
|
||||
|
||||
@@ -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
@@ -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 = "";
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
// js/sidebarLoading.js
|
||||
|
||||
function escapeHtml(value) {
|
||||
if (typeof value !== "string") {
|
||||
return "";
|
||||
}
|
||||
|
||||
return value
|
||||
.replace(/&/g, "&")
|
||||
.replace(/</g, "<")
|
||||
.replace(/>/g, ">")
|
||||
.replace(/"/g, """)
|
||||
.replace(/'/g, "'");
|
||||
}
|
||||
|
||||
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>
|
||||
`;
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
+14
-15
@@ -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"
|
||||
<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"
|
||||
></div>
|
||||
<p
|
||||
id="watchHistoryStatus"
|
||||
class="text-gray-300 text-center hidden"
|
||||
aria-live="polite"
|
||||
></p>
|
||||
></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">
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
Reference in new issue
Block a user