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
added prev next buttons
cozylittle.house
2 months ago
645c26e1
74ba8bf0
+124
-3
4 changed files
expand all
collapse all
unified
split
app
lish
[did]
[publication]
[rkey]
LinearDocumentPage.tsx
PostPrevNextButtons.tsx
getPostPageData.ts
dashboard
settings
PostOptions.tsx
+6
-1
app/lish/[did]/[publication]/[rkey]/LinearDocumentPage.tsx
···
25
25
import { decodeQuotePosition } from "./quotePosition";
26
26
import { PollData } from "./fetchPollData";
27
27
import { SharedPageProps } from "./PostPages";
28
28
+
import { PostPrevNextButtons } from "./PostPrevNextButtons";
28
29
29
30
export function LinearDocumentPage({
30
31
blocks,
···
56
57
57
58
const isSubpage = !!pageId;
58
59
60
60
+
console.log("prev/next?: " + preferences.showPrevNext);
61
61
+
59
62
return (
60
63
<>
61
64
<PageWrapper
···
83
86
did={did}
84
87
prerenderedCodeBlocks={prerenderedCodeBlocks}
85
88
/>
86
86
-
89
89
+
<PostPrevNextButtons
90
90
+
showPrevNext={preferences.showPrevNext && !isSubpage}
91
91
+
/>
87
92
<ExpandedInteractions
88
93
pageId={pageId}
89
94
showComments={preferences.showComments}
+58
app/lish/[did]/[publication]/[rkey]/PostPrevNextButtons.tsx
···
1
1
+
"use client";
2
2
+
import { PubLeafletDocument } from "lexicons/api";
3
3
+
import { usePublicationData } from "../dashboard/PublicationSWRProvider";
4
4
+
import { getPublicationURL } from "app/lish/createPub/getPublicationURL";
5
5
+
import { AtUri } from "@atproto/api";
6
6
+
import { useParams } from "next/navigation";
7
7
+
import { getPostPageData } from "./getPostPageData";
8
8
+
import { PostPageContext } from "./PostPageContext";
9
9
+
import { useContext } from "react";
10
10
+
import { SpeedyLink } from "components/SpeedyLink";
11
11
+
import { ArrowRightTiny } from "components/Icons/ArrowRightTiny";
12
12
+
13
13
+
export const PostPrevNextButtons = (props: {
14
14
+
showPrevNext: boolean | undefined;
15
15
+
}) => {
16
16
+
let postData = useContext(PostPageContext);
17
17
+
let pub = postData?.documents_in_publications[0]?.publications;
18
18
+
19
19
+
if (!props.showPrevNext || !pub || !postData) return;
20
20
+
21
21
+
function getPostLink(uri: string) {
22
22
+
return pub && uri
23
23
+
? `${getPublicationURL(pub)}/${new AtUri(uri).rkey}`
24
24
+
: "leaflet.pub/not-found";
25
25
+
}
26
26
+
let prevPost = postData?.prevNext?.prev;
27
27
+
let nextPost = postData?.prevNext?.next;
28
28
+
29
29
+
return (
30
30
+
<div className="flex flex-col gap-1 w-full px-3 sm:px-4 pb-2 pt-2">
31
31
+
{/*<hr className="border-border-light" />*/}
32
32
+
<div className="flex justify-between w-full gap-8 ">
33
33
+
{nextPost ? (
34
34
+
<SpeedyLink
35
35
+
href={getPostLink(nextPost.uri)}
36
36
+
className="flex gap-1 items-center truncate min-w-0 basis-1/2"
37
37
+
>
38
38
+
<ArrowRightTiny className="rotate-180 shrink-0" />
39
39
+
<div className="min-w-0 truncate">{nextPost.title}</div>
40
40
+
</SpeedyLink>
41
41
+
) : (
42
42
+
<div />
43
43
+
)}
44
44
+
{prevPost ? (
45
45
+
<SpeedyLink
46
46
+
href={getPostLink(prevPost.uri)}
47
47
+
className="flex gap-1 items-center truncate min-w-0 basis-1/2 justify-end"
48
48
+
>
49
49
+
<div className="min-w-0 truncate">{prevPost.title}</div>
50
50
+
<ArrowRightTiny className="shrink-0" />
51
51
+
</SpeedyLink>
52
52
+
) : (
53
53
+
<div />
54
54
+
)}
55
55
+
</div>
56
56
+
</div>
57
57
+
);
58
58
+
};
+58
-1
app/lish/[did]/[publication]/[rkey]/getPostPageData.ts
···
10
10
data,
11
11
uri,
12
12
comments_on_documents(*, bsky_profiles(*)),
13
13
-
documents_in_publications(publications(*, publication_subscriptions(*))),
13
13
+
documents_in_publications(publications(*,
14
14
+
documents_in_publications(documents(uri, data)),
15
15
+
publication_subscriptions(*))
16
16
+
),
14
17
document_mentions_in_bsky(*),
15
18
leaflets_in_publications(*)
16
19
`,
···
51
54
?.record as PubLeafletPublication.Record
52
55
)?.theme || (document?.data as PubLeafletDocument.Record)?.theme;
53
56
57
57
+
// Calculate prev/next documents from the fetched publication documents
58
58
+
let prevNext:
59
59
+
| {
60
60
+
prev?: { uri: string; title: string };
61
61
+
next?: { uri: string; title: string };
62
62
+
}
63
63
+
| undefined;
64
64
+
65
65
+
const currentPublishedAt = (document.data as PubLeafletDocument.Record)
66
66
+
?.publishedAt;
67
67
+
const allDocs =
68
68
+
document.documents_in_publications[0]?.publications
69
69
+
?.documents_in_publications;
70
70
+
71
71
+
if (currentPublishedAt && allDocs) {
72
72
+
// Filter and sort documents by publishedAt
73
73
+
const sortedDocs = allDocs
74
74
+
.map((dip) => ({
75
75
+
uri: dip?.documents?.uri,
76
76
+
title: (dip?.documents?.data as PubLeafletDocument.Record).title,
77
77
+
publishedAt: (dip?.documents?.data as PubLeafletDocument.Record)
78
78
+
.publishedAt,
79
79
+
}))
80
80
+
.filter((doc) => doc.publishedAt) // Only include docs with publishedAt
81
81
+
.sort(
82
82
+
(a, b) =>
83
83
+
new Date(a.publishedAt!).getTime() -
84
84
+
new Date(b.publishedAt!).getTime(),
85
85
+
);
86
86
+
87
87
+
// Find current document index
88
88
+
const currentIndex = sortedDocs.findIndex((doc) => doc.uri === uri);
89
89
+
90
90
+
if (currentIndex !== -1) {
91
91
+
prevNext = {
92
92
+
prev:
93
93
+
currentIndex > 0
94
94
+
? {
95
95
+
uri: sortedDocs[currentIndex - 1].uri || "",
96
96
+
title: sortedDocs[currentIndex - 1].title,
97
97
+
}
98
98
+
: undefined,
99
99
+
next:
100
100
+
currentIndex < sortedDocs.length - 1
101
101
+
? {
102
102
+
uri: sortedDocs[currentIndex + 1].uri || "",
103
103
+
title: sortedDocs[currentIndex + 1].title,
104
104
+
}
105
105
+
: undefined,
106
106
+
};
107
107
+
}
108
108
+
}
109
109
+
54
110
return {
55
111
...document,
56
112
quotesAndMentions,
57
113
theme,
114
114
+
prevNext,
58
115
};
59
116
}
60
117
+2
-1
app/lish/[did]/[publication]/dashboard/settings/PostOptions.tsx
···
53
53
showPrevNext: showPrevNext,
54
54
},
55
55
});
56
56
-
toast({ type: "success", content: "Posts Updated!" });
56
56
+
toast({ type: "success", content: <strong>Posts Updated!</strong> });
57
57
+
console.log(record.preferences?.showPrevNext);
57
58
props.setLoading(false);
58
59
mutate("publication-data");
59
60
}}