diff --git a/web/src/components/layout/ListSkeleton.tsx b/web/src/components/layout/ListSkeleton.tsx
new file mode 100644
index 0000000..39e7055
--- /dev/null
+++ b/web/src/components/layout/ListSkeleton.tsx
@@ -0,0 +1,9 @@
+export default function ListSkeleton() {
+ return (
+
+ );
+}
diff --git a/web/src/pages/BBS.tsx b/web/src/pages/BBS.tsx
index c806b11..876b8cb 100644
--- a/web/src/pages/BBS.tsx
+++ b/web/src/pages/BBS.tsx
@@ -29,6 +29,7 @@ import ListLink from "../components/nav/ListLink";
import ActionBar from "../components/nav/ActionBar";
import { ActionLink } from "../components/nav/ActionButton";
import PinButton from "../components/PinButton";
+import ListSkeleton from "../components/layout/ListSkeleton";
const INITIAL_NEWS_COUNT = 3;
@@ -41,7 +42,7 @@ export default function BBSPage() {
const [showAllNews, setShowAllNews] = useState(false);
const { data: bbs } = useSuspenseQuery(bbsQuery(handle!));
- const { data: news } = useSuspenseQuery(newsQuery(bbs.identity.did));
+ const { data: news } = useQuery(newsQuery(bbs.identity.did));
const { data: pins } = useQuery({
...pinsQuery(user?.pdsUrl ?? "", user?.did ?? ""),
enabled: !!user,
@@ -104,7 +105,11 @@ export default function BBSPage() {
});
}
- const visibleNews = showAllNews ? news : news.slice(0, INITIAL_NEWS_COUNT);
+ const visibleNews = news
+ ? showAllNews
+ ? news
+ : news.slice(0, INITIAL_NEWS_COUNT)
+ : [];
return (
<>
@@ -185,7 +190,9 @@ export default function BBSPage() {
)}
- {news.length ? (
+ {!news ? (
+
+ ) : news.length ? (
<>
{visibleNews.map((item, i) => (
page.threads);
- const threads = isSysop
- ? allThreads
- : allThreads.filter(
- (t) =>
- !moderation.banRkeys[t.did] &&
- !moderation.hideRkeys[t.uri],
- );
+ const ready = !!threadPages && !!moderation;
+ const allThreads = threadPages?.pages.flatMap((page) => page.threads) ?? [];
+ const threads =
+ isSysop || !moderation
+ ? allThreads
+ : allThreads.filter(
+ (t) =>
+ !moderation.banRkeys[t.did] && !moderation.hideRkeys[t.uri],
+ );
const [title, setTitle] = useState("");
const [body, setBody] = useState("");
@@ -195,7 +196,9 @@ export default function BoardPage() {
)}
- {threads.length ? (
+ {!ready ? (
+
+ ) : threads.length ? (
<>
{threads.map((t) => (
diff --git a/web/src/pages/Dashboard.tsx b/web/src/pages/Dashboard.tsx
index 1db0c6f..9fa2e58 100644
--- a/web/src/pages/Dashboard.tsx
+++ b/web/src/pages/Dashboard.tsx
@@ -1,5 +1,5 @@
import { useMemo, useState } from "react";
-import { useSuspenseQuery, useMutation } from "@tanstack/react-query";
+import { useQuery, useMutation } from "@tanstack/react-query";
import { useAuth, type AuthUser } from "../lib/auth";
import { deleteBBS } from "../lib/deletebbs";
import { usePageTitle } from "../hooks/usePageTitle";
@@ -20,6 +20,7 @@ import PinnedList from "../components/dashboard/PinnedList";
import MyThreadList from "../components/dashboard/MyThreadList";
import ActivityList from "../components/dashboard/ActivityList";
import BBSPanel from "../components/dashboard/BBSPanel";
+import ListSkeleton from "../components/layout/ListSkeleton";
type Tab = "inbox" | "threads" | "pinned" | "bbs";
@@ -37,17 +38,14 @@ export default function Dashboard({ user }: DashboardProps) {
const [tab, setTab] = useState
("inbox");
usePageTitle("atbbs");
- const { data: sysopInfo } = useSuspenseQuery(homeSysopQuery(user.did));
- const { data: pins } = useSuspenseQuery(pinsQuery(user.pdsUrl, user.did));
- const { data: threads } = useSuspenseQuery(
- myThreadsQuery(user.pdsUrl, user.did),
- );
- const { data: activity } = useSuspenseQuery(
- activityQuery(user.pdsUrl, user.did),
- );
- const { data: discovered } = useSuspenseQuery(discoveryQuery());
+ const { data: sysopInfo } = useQuery(homeSysopQuery(user.did));
+ const { data: pins } = useQuery(pinsQuery(user.pdsUrl, user.did));
+ const { data: threads } = useQuery(myThreadsQuery(user.pdsUrl, user.did));
+ const { data: activity } = useQuery(activityQuery(user.pdsUrl, user.did));
+ const { data: discovered } = useQuery(discoveryQuery());
- const suggestions = useMemo(() => {
+ const suggestions = useMemo(() => {
+ if (!pins || !discovered) return undefined;
const pinnedDids = new Set(pins.map((pin) => pin.did));
const fromPins = pins.map(bbsToSuggestion);
const fromDiscovery = discovered
@@ -120,7 +118,7 @@ export default function Dashboard({ user }: DashboardProps) {
Recent replies from other users.
-
+ {activity ? : }
>
)}
@@ -129,7 +127,7 @@ export default function Dashboard({ user }: DashboardProps) {
Threads you've posted across all communities.
-
+ {threads ? : }
>
)}
@@ -138,7 +136,7 @@ export default function Dashboard({ user }: DashboardProps) {
Communities you've pinned for quick access.
-
+ {pins ? : }
>
)}
@@ -147,15 +145,20 @@ export default function Dashboard({ user }: DashboardProps) {
Manage your community.
-
+ {sysopInfo ? (
+
+ ) : (
+
+ )}
>
)}
>
);
}
+
diff --git a/web/src/pages/LoggedOutHome.tsx b/web/src/pages/LoggedOutHome.tsx
index 0a2b9f4..35c8ee1 100644
--- a/web/src/pages/LoggedOutHome.tsx
+++ b/web/src/pages/LoggedOutHome.tsx
@@ -1,6 +1,6 @@
import { useMemo, useState } from "react";
import { Phone, Copy, Check } from "lucide-react";
-import { useSuspenseQuery } from "@tanstack/react-query";
+import { useQuery } from "@tanstack/react-query";
import { usePageTitle } from "../hooks/usePageTitle";
import { discoveryQuery } from "../lib/queries";
import DialBBS, {
@@ -10,9 +10,9 @@ import DialBBS, {
import DiscoveryList from "../components/dashboard/DiscoveryList";
export default function LoggedOutHome() {
- const { data: discovered } = useSuspenseQuery(discoveryQuery());
- const suggestions = useMemo(
- () => discovered.map(bbsToSuggestion),
+ const { data: discovered } = useQuery(discoveryQuery());
+ const suggestions = useMemo(
+ () => discovered?.map(bbsToSuggestion),
[discovered],
);
const [tab, setTab] = useState<"brew" | "uv" | "telnet">("brew");
@@ -73,7 +73,7 @@ export default function LoggedOutHome() {
-
+ {discovered && }
diff --git a/web/src/pages/Profile.tsx b/web/src/pages/Profile.tsx
index d338404..3080134 100644
--- a/web/src/pages/Profile.tsx
+++ b/web/src/pages/Profile.tsx
@@ -1,6 +1,6 @@
import { useState } from "react";
import { useParams } from "react-router-dom";
-import { useSuspenseQuery, useMutation } from "@tanstack/react-query";
+import { useQuery, useMutation } from "@tanstack/react-query";
import { MessageSquare } from "lucide-react";
import { useAuth } from "../lib/auth";
import { usePageTitle } from "../hooks/usePageTitle";
@@ -10,16 +10,18 @@ import { queryClient } from "../lib/queryClient";
import ViewProfile from "../components/profile/ViewProfile";
import EditProfile from "../components/profile/EditProfile";
import MyThreadList from "../components/dashboard/MyThreadList";
+import ListSkeleton from "../components/layout/ListSkeleton";
export default function Profile() {
const { handle } = useParams();
const { user, agent } = useAuth();
const [editing, setEditing] = useState(false);
- const { data: profile } = useSuspenseQuery(profileQuery(handle!));
- const { data: threads } = useSuspenseQuery(
- myThreadsQuery(profile?.pdsUrl ?? "", profile?.did ?? ""),
- );
+ const { data: profile } = useQuery(profileQuery(handle!));
+ const { data: threads } = useQuery({
+ ...myThreadsQuery(profile?.pdsUrl ?? "", profile?.did ?? ""),
+ enabled: !!profile,
+ });
usePageTitle(`${profile?.name ?? handle} — atbbs`);
@@ -58,7 +60,7 @@ export default function Profile() {
<>
setEditing(true)}
/>
@@ -66,7 +68,11 @@ export default function Profile() {
Recent Threads
-
+ {threads ? (
+
+ ) : (
+
+ )}
>
);