tangled
alpha
login
or
join now
leaflet.pub
/
leaflet
289
fork
atom
a tool for shared writing and social publishing
289
fork
atom
overview
issues
28
pulls
pipelines
add loading.tsx for route level suspense boundary
awarm.space
1 month ago
44f2cb22
07da0858
+22
-34
6 changed files
expand all
collapse all
unified
split
app
(home-pages)
reader
GlobalContent.tsx
hot
page.tsx
loading.tsx
new
page.tsx
page.tsx
components
PostListing.tsx
+1
-7
app/(home-pages)/reader/GlobalContent.tsx
···
14
14
}) => {
15
15
const initialData = use(props.promise);
16
16
17
17
-
const { data, isLoading } = useSWR(
17
17
+
const { data } = useSWR(
18
18
"hot_feed",
19
19
async () => {
20
20
const res = await callRPC("get_hot_feed", {});
···
26
26
);
27
27
28
28
const posts = data?.posts ?? [];
29
29
-
30
30
-
if (isLoading) {
31
31
-
return (
32
32
-
<div className="text-center text-tertiary py-8">Loading posts...</div>
33
33
-
);
34
34
-
}
35
29
36
30
if (posts.length === 0) {
37
31
return (
+1
-7
app/(home-pages)/reader/hot/page.tsx
···
1
1
-
import { Suspense } from "react";
2
1
import { getHotFeed } from "../getHotFeed";
3
2
import { GlobalContent } from "../GlobalContent";
4
4
-
import { FeedSkeleton } from "../FeedSkeleton";
5
3
6
4
export default async function HotPage() {
7
5
const feedPromise = getHotFeed();
8
8
-
return (
9
9
-
<Suspense fallback={<FeedSkeleton />}>
10
10
-
<GlobalContent promise={feedPromise} />
11
11
-
</Suspense>
12
12
-
);
6
6
+
return <GlobalContent promise={feedPromise} />;
13
7
}
+4
app/(home-pages)/reader/loading.tsx
···
1
1
+
import { FeedSkeleton } from "./FeedSkeleton";
2
2
+
export default function Loading() {
3
3
+
return <FeedSkeleton />;
4
4
+
}
+1
-7
app/(home-pages)/reader/new/page.tsx
···
1
1
-
import { Suspense } from "react";
2
1
import { getNewFeed } from "../getNewFeed";
3
2
import { NewContent } from "../NewContent";
4
4
-
import { FeedSkeleton } from "../FeedSkeleton";
5
3
6
4
export default async function NewPage() {
7
5
const feedPromise = getNewFeed();
8
8
-
return (
9
9
-
<Suspense fallback={<FeedSkeleton />}>
10
10
-
<NewContent promise={feedPromise} />
11
11
-
</Suspense>
12
12
-
);
6
6
+
return <NewContent promise={feedPromise} />;
13
7
}
+1
-7
app/(home-pages)/reader/page.tsx
···
1
1
-
import { Suspense } from "react";
2
1
import { getReaderFeed } from "./getReaderFeed";
3
2
import { InboxContent } from "./InboxContent";
4
4
-
import { FeedSkeleton } from "./FeedSkeleton";
5
3
6
4
export default async function Reader() {
7
5
const feedPromise = getReaderFeed();
8
8
-
return (
9
9
-
<Suspense fallback={<FeedSkeleton />}>
10
10
-
<InboxContent promise={feedPromise} />
11
11
-
</Suspense>
12
12
-
);
6
6
+
return <InboxContent promise={feedPromise} />;
13
7
}
+14
-6
components/PostListing.tsx
···
11
11
import type { Post } from "app/(home-pages)/reader/getReaderFeed";
12
12
13
13
import Link from "next/link";
14
14
+
import { useEffect, useRef, useState } from "react";
14
15
import { InteractionPreview, TagPopover } from "./InteractionsPreview";
15
16
import { useLocalizedDate } from "src/hooks/useLocalizedDate";
16
17
import { useSmoker } from "./Toast";
···
42
43
let isStandalone = !pubRecord;
43
44
let theme = usePubTheme(pubRecord?.theme || postRecord?.theme, isStandalone);
44
45
let themeRecord = pubRecord?.theme || postRecord?.theme;
45
45
-
let el = document?.getElementById(`post-listing-${postUri}`);
46
46
+
let elRef = useRef<HTMLDivElement>(null);
47
47
+
let [hasBackgroundImage, setHasBackgroundImage] = useState(false);
46
48
47
47
-
let hasBackgroundImage =
48
48
-
!!themeRecord?.backgroundImage?.image &&
49
49
-
el &&
50
50
-
Number(window.getComputedStyle(el).getPropertyValue("--bg-page-alpha")) <
51
51
-
0.7;
49
49
+
useEffect(() => {
50
50
+
if (!themeRecord?.backgroundImage?.image || !elRef.current) {
51
51
+
setHasBackgroundImage(false);
52
52
+
return;
53
53
+
}
54
54
+
let alpha = Number(
55
55
+
window.getComputedStyle(elRef.current).getPropertyValue("--bg-page-alpha"),
56
56
+
);
57
57
+
setHasBackgroundImage(alpha < 0.7);
58
58
+
}, [themeRecord?.backgroundImage?.image]);
52
59
53
60
let backgroundImage =
54
61
themeRecord?.backgroundImage?.image?.ref && uri
···
82
89
<div className="postListing flex flex-col gap-1">
83
90
<BaseThemeProvider {...theme} local>
84
91
<div
92
92
+
ref={elRef}
85
93
id={`post-listing-${postUri}`}
86
94
className={`
87
95
relative