a tool for shared writing and social publishing
1"use client";
2import { getRSVPData } from "actions/getRSVPData";
3import { SWRConfig } from "swr";
4import { useReplicache } from "src/replicache";
5import useSWR from "swr";
6import { callRPC } from "app/api/rpc/client";
7import { getPollData } from "actions/pollActions";
8import type { GetLeafletDataReturnType } from "app/api/rpc/[command]/get_leaflet_data";
9import { createContext, useContext } from "react";
10import { getPublicationMetadataFromLeafletData } from "src/utils/getPublicationMetadataFromLeafletData";
11import { getPublicationURL } from "app/lish/createPub/getPublicationURL";
12import { AtUri } from "@atproto/syntax";
13
14export const StaticLeafletDataContext = createContext<
15 null | GetLeafletDataReturnType["result"]["data"]
16>(null);
17export function PageSWRDataProvider(props: {
18 leaflet_id: string;
19 leaflet_data: GetLeafletDataReturnType["result"];
20 rsvp_data: Awaited<ReturnType<typeof getRSVPData>>;
21 poll_data: Awaited<ReturnType<typeof getPollData>>;
22 children: React.ReactNode;
23}) {
24 return (
25 <SWRConfig
26 value={{
27 fallback: {
28 rsvp_data: props.rsvp_data,
29 poll_data: props.poll_data,
30 [`${props.leaflet_id}-leaflet_data`]: props.leaflet_data.data,
31 },
32 }}
33 >
34 {props.children}
35 </SWRConfig>
36 );
37}
38
39export function useRSVPData() {
40 let { permission_token } = useReplicache();
41 return useSWR(`rsvp_data`, () =>
42 getRSVPData(
43 permission_token.permission_token_rights.map((pr) => pr.entity_set),
44 ),
45 );
46}
47export function usePollData() {
48 let { permission_token } = useReplicache();
49 return useSWR(`poll_data`, () =>
50 getPollData(
51 permission_token.permission_token_rights.map((pr) => pr.entity_set),
52 ),
53 );
54}
55
56let useLeafletData = () => {
57 let { permission_token } = useReplicache();
58 let staticLeafletData = useContext(StaticLeafletDataContext);
59 let res = useSWR(
60 staticLeafletData ? null : `${permission_token.id}-leaflet_data`,
61 async () =>
62 permission_token.id
63 ? (await callRPC("get_leaflet_data", { token_id: permission_token.id }))
64 ?.result.data
65 : undefined,
66 );
67 if (staticLeafletData) return { data: staticLeafletData, mutate: res.mutate };
68 return res;
69};
70export function useLeafletPublicationData() {
71 let { data, mutate } = useLeafletData();
72
73 // First check for leaflets in publications
74 let pubData = getPublicationMetadataFromLeafletData(data);
75
76 return {
77 data: pubData || null,
78 mutate,
79 };
80}
81export function useLeafletDomains() {
82 let { data, mutate } = useLeafletData();
83 return { data: data?.custom_domain_routes, mutate: mutate };
84}
85
86export function useLeafletPublicationStatus() {
87 const data = useContext(StaticLeafletDataContext);
88 if (!data) return null;
89
90 const publishedInPublication = data.leaflets_in_publications?.find(
91 (l) => l.doc,
92 );
93 const publishedStandalone = data.leaflets_to_documents?.find(
94 (l) => !!l.documents,
95 );
96
97 const documentUri =
98 publishedInPublication?.documents?.uri ?? publishedStandalone?.document;
99
100 // Compute the full post URL for sharing
101 let postShareLink: string | undefined;
102 if (publishedInPublication?.publications && publishedInPublication.documents) {
103 // Published in a publication - use publication URL + document rkey
104 const docUri = new AtUri(publishedInPublication.documents.uri);
105 postShareLink = `${getPublicationURL(publishedInPublication.publications)}/${docUri.rkey}`;
106 } else if (publishedStandalone?.document) {
107 // Standalone published post - use /p/{did}/{rkey} format
108 const docUri = new AtUri(publishedStandalone.document);
109 postShareLink = `/p/${docUri.host}/${docUri.rkey}`;
110 }
111
112 return {
113 token: data,
114 leafletId: data.root_entity,
115 shareLink: data.id,
116 // Draft state - in a publication but not yet published
117 draftInPublication:
118 data.leaflets_in_publications?.[0]?.publication ?? undefined,
119 // Published state
120 isPublished: !!(publishedInPublication || publishedStandalone),
121 publishedAt:
122 publishedInPublication?.documents?.indexed_at ??
123 publishedStandalone?.documents?.indexed_at,
124 documentUri,
125 // Full URL for sharing published posts
126 postShareLink,
127 };
128}