diff --git a/frontend/src/components/ChatThread.tsx b/frontend/src/components/ChatThread.tsx
index dd3552eb..07c500e4 100644
--- a/frontend/src/components/ChatThread.tsx
+++ b/frontend/src/components/ChatThread.tsx
@@ -5,6 +5,7 @@ import { Send } from "lucide-react";
import { api, HttpError, type Message, type MessageUser } from "../lib/api";
import { useLiveQuery } from "../lib/useLiveQuery";
import { useScrollFade } from "../lib/useScrollFade";
+import { StateMessage } from "./QueryState";
import { relativeTime } from "../lib/format";
import { notify } from "../lib/notifications";
import { partnerPub, POLL_MS, useKeyState } from "../lib/messaging";
@@ -139,7 +140,15 @@ export default function ChatThread({
style={fade.style}
className="flex-1 overflow-y-auto no-scrollbar p-3 flex flex-col gap-2"
>
- {items.length === 0 ? (
+ {q.isError && !q.data ? (
+
+ q.refetch()}>
+ {t("common.loadError")}
+
+
+ ) : q.isPending ? (
+
{t("common.loading")}
+ ) : items.length === 0 ? (
{t("messages.threadEmpty")}
) : (
items.map((m) => {
diff --git a/frontend/src/components/ConfigPanel.tsx b/frontend/src/components/ConfigPanel.tsx
index 74c5b32e..56f740a8 100644
--- a/frontend/src/components/ConfigPanel.tsx
+++ b/frontend/src/components/ConfigPanel.tsx
@@ -6,6 +6,7 @@ import { api, type ConfigItem, type PlexTestResult } from "../lib/api";
import { notify } from "../lib/notifications";
import Tooltip from "./Tooltip";
import Tabs, { usePersistedTab } from "./Tabs";
+import { StateMessage } from "./QueryState";
import { PageToolbar } from "./PageShell";
import { Switch } from "./ui/form";
import { DraftSaveBar, type SaveState } from "./ui/DraftSaveBar";
@@ -148,6 +149,13 @@ export default function ConfigPanel() {
setDraft((d) => ({ ...d, plex_libraries: next.join(",") }));
};
+ if (q.isError && !data) {
+ return (
+
q.refetch()}>
+ {t("common.loadError")}
+
+ );
+ }
if (q.isLoading || !data) {
return
{t("config.loading")}
;
}
diff --git a/frontend/src/components/DownloadCenter.tsx b/frontend/src/components/DownloadCenter.tsx
index 408e7b8e..a2f53c79 100644
--- a/frontend/src/components/DownloadCenter.tsx
+++ b/frontend/src/components/DownloadCenter.tsx
@@ -19,6 +19,7 @@ import {
import clsx from "clsx";
import Tabs, { usePersistedTab } from "./Tabs";
import { PageToolbar } from "./PageShell";
+import { StateMessage } from "./QueryState";
import Modal from "./Modal";
// Lazy: these dialogs/editors open on demand, so they stay out of the Downloads page chunk until
// used (the video editor in particular is heavy — filmstrip + scrubber).
@@ -803,11 +804,18 @@ export default function DownloadCenter() {
))}
- {queue.length === 0 && (
-
- {t("downloads.empty.queue")}
-
- )}
+ {queue.length === 0 &&
+ (jobsQ.isError && !jobsQ.data ? (
+
jobsQ.refetch()}>
+ {t("common.loadError")}
+
+ ) : jobsQ.isLoading ? (
+
{t("common.loading")}
+ ) : (
+
+ {t("downloads.empty.queue")}
+
+ ))}
>
)}
@@ -860,11 +868,18 @@ export default function DownloadCenter() {
))}
- {library.length === 0 && (
-