feat(ui): shared LoadingState — a centered accent spinner instead of plain loading text

Replaces the plain "Loading…" text in every R3 loading branch with a single shared LoadingState
(a spinning lucide Loader2 in the accent colour + label, centered, role=status/aria-live) — one
component so all loads read the same and can be swapped for skeletons later in one place. Applied
across Feed, Channels, ChannelDiscovery, AuditLog, NotificationsPanel, Messages, Scheduler, Stats,
PlexBrowse (grid + subviews), PlexPlaylistView, ConfigPanel, DownloadCenter, AdminUsers, ChatThread.
Left the small "load more" footer and lazy Suspense fallbacks as-is.
This commit is contained in:
2026-07-22 04:35:02 +02:00
parent bf96318dea
commit b5573b62d1
15 changed files with 54 additions and 35 deletions
+3 -3
View File
@@ -7,7 +7,7 @@ import { notify } from "../lib/notifications";
import { ADMIN_USERS_TAB_KEY } from "../lib/adminUsersTab";
import Tooltip from "./Tooltip";
import { Section } from "./ui/form";
import { StateMessage } from "./QueryState";
import { LoadingState, StateMessage } from "./QueryState";
import { useConfirm } from "./ConfirmProvider";
import Tabs, { usePersistedTab } from "./Tabs";
import { PageToolbar } from "./PageShell";
@@ -165,7 +165,7 @@ function UsersRoles({ me }: { me: Me }) {
{t("common.loadError")}
</StateMessage>
) : q.isLoading && !q.data ? (
<p className="text-sm text-muted">{t("common.loading")}</p>
<LoadingState />
) : rows.length === 0 ? (
<p className="text-sm text-muted">{t("users.roles.empty")}</p>
) : (
@@ -319,7 +319,7 @@ function AdminInvites() {
{t("common.loadError")}
</StateMessage>
) : invites.isLoading && !invites.data ? (
<p className="text-sm text-muted">{t("common.loading")}</p>
<LoadingState />
) : pending.length === 0 ? (
<p className="text-sm text-muted">{t("settings.invites.noPending")}</p>
) : (