From 96ed3674fad91fe15926f4b417f1fe7521b2f5c3 Mon Sep 17 00:00:00 2001 From: Jared Pereira Date: Mon, 12 Jan 2026 21:25:33 -0500 Subject: [PATCH] Feature/post options (#254) * added showMention and showPrevNext props to the lexicon * wired up post options to update record * added new preferences to props everywhere * added prev next buttons * added a check for mentions everywhere relavent * little corner tweak for the interaction drawer * removed show comments from update pub form * little issues with the help text in post options --------- Co-authored-by: celine --- app/[leaflet_id]/actions/PublishButton.tsx | 4 +- .../[did]/[publication]/[rkey]/CanvasPage.tsx | 7 +- .../[rkey]/Interactions/Comments/index.tsx | 5 +- .../[rkey]/Interactions/InteractionDrawer.tsx | 3 +- .../[rkey]/Interactions/Interactions.tsx | 112 +++++++++++------- .../[rkey]/LinearDocumentPage.tsx | 9 +- .../[rkey]/PostHeader/PostHeader.tsx | 3 +- .../[did]/[publication]/[rkey]/PostPages.tsx | 26 +++- .../[rkey]/PostPrevNextButtons.tsx | 58 +++++++++ .../[publication]/[rkey]/QuoteHandler.tsx | 5 +- .../[publication]/[rkey]/getPostPageData.ts | 59 ++++++++- .../dashboard/PublishedPostsLists.tsx | 1 + .../dashboard/settings/PostOptions.tsx | 56 +++++---- .../settings/PublicationSettings.tsx | 4 +- app/lish/[did]/[publication]/page.tsx | 1 + app/lish/createPub/CreatePubForm.tsx | 11 +- app/lish/createPub/UpdatePubForm.tsx | 33 +++--- app/lish/createPub/updatePublication.ts | 4 +- components/Canvas.tsx | 9 +- components/InteractionsPreview.tsx | 6 +- components/Pages/PublicationMetadata.tsx | 8 +- components/PostListing.tsx | 1 + lexicons/api/lexicons.ts | 8 ++ lexicons/api/types/pub/leaflet/publication.ts | 2 + lexicons/pub/leaflet/publication.json | 8 ++ lexicons/src/publication.ts | 2 + 26 files changed, 333 insertions(+), 112 deletions(-) create mode 100644 app/lish/[did]/[publication]/[rkey]/PostPrevNextButtons.tsx diff --git a/app/[leaflet_id]/actions/PublishButton.tsx b/app/[leaflet_id]/actions/PublishButton.tsx index 4b665775..f0140132 100644 --- a/app/[leaflet_id]/actions/PublishButton.tsx +++ b/app/[leaflet_id]/actions/PublishButton.tsx @@ -136,8 +136,8 @@ const UpdateButton = () => { content: (
{pub.doc ? "Updated! " : "Published! "} - - See Post + + See Published Post
), diff --git a/app/lish/[did]/[publication]/[rkey]/CanvasPage.tsx b/app/lish/[did]/[publication]/[rkey]/CanvasPage.tsx index 402e72b2..1ea95dcc 100644 --- a/app/lish/[did]/[publication]/[rkey]/CanvasPage.tsx +++ b/app/lish/[did]/[publication]/[rkey]/CanvasPage.tsx @@ -202,7 +202,11 @@ const CanvasMetadata = (props: { isSubpage: boolean | undefined; data: PostPageData; profile: ProfileViewDetailed; - preferences: { showComments?: boolean }; + preferences: { + showComments?: boolean; + showMentions?: boolean; + showPrevNext?: boolean; + }; quotesCount: number | undefined; commentsCount: number | undefined; }) => { @@ -213,6 +217,7 @@ const CanvasMetadata = (props: { quotesCount={props.quotesCount || 0} commentsCount={props.commentsCount || 0} showComments={props.preferences.showComments} + showMentions={props.preferences.showMentions} pageId={props.pageId} /> {!props.isSubpage && ( diff --git a/app/lish/[did]/[publication]/[rkey]/Interactions/Comments/index.tsx b/app/lish/[did]/[publication]/[rkey]/Interactions/Comments/index.tsx index 4e27693e..fea07562 100644 --- a/app/lish/[did]/[publication]/[rkey]/Interactions/Comments/index.tsx +++ b/app/lish/[did]/[publication]/[rkey]/Interactions/Comments/index.tsx @@ -51,7 +51,10 @@ export function Comments(props: { }, []); return ( -
+
Comments - )} - {props.showComments === false ? null : ( - )} - - )} -
+ {props.showComments === false ? null : ( + + )} +
+ + )} + {subscribed && publication && ( - + diff --git a/app/lish/[did]/[publication]/[rkey]/PostHeader/PostHeader.tsx b/app/lish/[did]/[publication]/[rkey]/PostHeader/PostHeader.tsx index 63c6896b..364dfac5 100644 --- a/app/lish/[did]/[publication]/[rkey]/PostHeader/PostHeader.tsx +++ b/app/lish/[did]/[publication]/[rkey]/PostHeader/PostHeader.tsx @@ -23,7 +23,7 @@ import { ProfilePopover } from "components/ProfilePopover"; export function PostHeader(props: { data: PostPageData; profile: ProfileViewDetailed; - preferences: { showComments?: boolean }; + preferences: { showComments?: boolean; showMentions?: boolean }; }) { let { identity } = useIdentityData(); let document = props.data; @@ -91,6 +91,7 @@ export function PostHeader(props: {
diff --git a/app/lish/[did]/[publication]/[rkey]/PostPages.tsx b/app/lish/[did]/[publication]/[rkey]/PostPages.tsx index 76e689c4..d60b23c9 100644 --- a/app/lish/[did]/[publication]/[rkey]/PostPages.tsx +++ b/app/lish/[did]/[publication]/[rkey]/PostPages.tsx @@ -147,7 +147,11 @@ export type SharedPageProps = { document: PostPageData; did: string; profile: ProfileViewDetailed; - preferences: { showComments?: boolean }; + preferences: { + showComments?: boolean; + showMentions?: boolean; + showPrevNext?: boolean; + }; pubRecord?: PubLeafletPublication.Record; theme?: PubLeafletPublication.Theme | null; prerenderedCodeBlocks?: Map; @@ -206,7 +210,11 @@ export function PostPages({ did: string; prerenderedCodeBlocks?: Map; bskyPostData: AppBskyFeedDefs.PostView[]; - preferences: { showComments?: boolean }; + preferences: { + showComments?: boolean; + showMentions?: boolean; + showPrevNext?: boolean; + }; pollData: PollData[]; }) { let drawer = useDrawerOpen(document_uri); @@ -261,13 +269,18 @@ export function PostPages({ {drawer && !drawer.pageId && ( )} @@ -347,6 +360,7 @@ export function PostPages({ /> {drawer && drawer.pageId === page.id && ( )} diff --git a/app/lish/[did]/[publication]/[rkey]/PostPrevNextButtons.tsx b/app/lish/[did]/[publication]/[rkey]/PostPrevNextButtons.tsx new file mode 100644 index 00000000..48a1a99c --- /dev/null +++ b/app/lish/[did]/[publication]/[rkey]/PostPrevNextButtons.tsx @@ -0,0 +1,58 @@ +"use client"; +import { PubLeafletDocument } from "lexicons/api"; +import { usePublicationData } from "../dashboard/PublicationSWRProvider"; +import { getPublicationURL } from "app/lish/createPub/getPublicationURL"; +import { AtUri } from "@atproto/api"; +import { useParams } from "next/navigation"; +import { getPostPageData } from "./getPostPageData"; +import { PostPageContext } from "./PostPageContext"; +import { useContext } from "react"; +import { SpeedyLink } from "components/SpeedyLink"; +import { ArrowRightTiny } from "components/Icons/ArrowRightTiny"; + +export const PostPrevNextButtons = (props: { + showPrevNext: boolean | undefined; +}) => { + let postData = useContext(PostPageContext); + let pub = postData?.documents_in_publications[0]?.publications; + + if (!props.showPrevNext || !pub || !postData) return; + + function getPostLink(uri: string) { + return pub && uri + ? `${getPublicationURL(pub)}/${new AtUri(uri).rkey}` + : "leaflet.pub/not-found"; + } + let prevPost = postData?.prevNext?.prev; + let nextPost = postData?.prevNext?.next; + + return ( +
+ {/*
*/} +
+ {nextPost ? ( + + +
{nextPost.title}
+
+ ) : ( +
+ )} + {prevPost ? ( + +
{prevPost.title}
+ +
+ ) : ( +
+ )} +
+
+ ); +}; diff --git a/app/lish/[did]/[publication]/[rkey]/QuoteHandler.tsx b/app/lish/[did]/[publication]/[rkey]/QuoteHandler.tsx index 742602c8..beb835e3 100644 --- a/app/lish/[did]/[publication]/[rkey]/QuoteHandler.tsx +++ b/app/lish/[did]/[publication]/[rkey]/QuoteHandler.tsx @@ -186,7 +186,7 @@ export const QuoteOptionButtons = (props: { position: string }) => { Bluesky - + {pubRecord?.preferences?.showComments !== false && identity?.atp_did && ( <> - + +
diff --git a/app/lish/[did]/[publication]/dashboard/settings/PostOptions.tsx b/app/lish/[did]/[publication]/dashboard/settings/PostOptions.tsx index 1307a9f5..6309ca9b 100644 --- a/app/lish/[did]/[publication]/dashboard/settings/PostOptions.tsx +++ b/app/lish/[did]/[publication]/dashboard/settings/PostOptions.tsx @@ -22,29 +22,41 @@ export const PostOptions = (props: { ? true : record.preferences.showComments, ); - let [showMentions, setShowMentions] = useState(true); - let [showPrevNext, setShowPrevNext] = useState(true); + let [showMentions, setShowMentions] = useState( + record?.preferences?.showMentions === undefined + ? true + : record.preferences.showMentions, + ); + let [showPrevNext, setShowPrevNext] = useState( + record?.preferences?.showPrevNext === undefined + ? true + : record.preferences.showPrevNext, + ); let toast = useToaster(); return (
{ - // if (!pubData) return; - // e.preventDefault(); - // props.setLoading(true); - // let data = await updatePublication({ - // uri: pubData.uri, - // name: nameValue, - // description: descriptionValue, - // iconFile: iconFile, - // preferences: { - // showInDiscover: showInDiscover, - // showComments: showComments, - // }, - // }); - // toast({ type: "success", content: "Posts Updated!" }); - // props.setLoading(false); - // mutate("publication-data"); + if (!pubData) return; + e.preventDefault(); + props.setLoading(true); + let data = await updatePublication({ + name: record.name, + uri: pubData.uri, + preferences: { + showInDiscover: + record?.preferences?.showInDiscover === undefined + ? true + : record.preferences.showInDiscover, + showComments: showComments, + showMentions: showMentions, + showPrevNext: showPrevNext, + }, + }); + toast({ type: "success", content: Posts Updated! }); + console.log(record.preferences?.showPrevNext); + props.setLoading(false); + mutate("publication-data"); }} className="text-primary flex flex-col" > @@ -57,19 +69,13 @@ export const PostOptions = (props: { Post Options

Layout

- {/*
Max Post Width
*/} { setShowPrevNext(!showPrevNext); }} > -
-
Show Prev/Next Buttons
-
- Show buttons that navigate to the previous and next posts -
-
+
Show Prev/Next Buttons

Interactions

diff --git a/app/lish/[did]/[publication]/dashboard/settings/PublicationSettings.tsx b/app/lish/[did]/[publication]/dashboard/settings/PublicationSettings.tsx index 88ed1c27..0b85e548 100644 --- a/app/lish/[did]/[publication]/dashboard/settings/PublicationSettings.tsx +++ b/app/lish/[did]/[publication]/dashboard/settings/PublicationSettings.tsx @@ -103,14 +103,14 @@ const PubSettingsMenu = (props: { Theme and Layout - {/**/} +
); }; diff --git a/app/lish/[did]/[publication]/page.tsx b/app/lish/[did]/[publication]/page.tsx index 4b19b1d4..3266835d 100644 --- a/app/lish/[did]/[publication]/page.tsx +++ b/app/lish/[did]/[publication]/page.tsx @@ -172,6 +172,7 @@ export default async function Publication(props: { tags={tags} postUrl={`${getPublicationURL(publication)}/${uri.rkey}`} showComments={record?.preferences?.showComments} + showMentions={record?.preferences?.showMentions} /> diff --git a/app/lish/createPub/CreatePubForm.tsx b/app/lish/createPub/CreatePubForm.tsx index 2d3f6655..5c7c8efb 100644 --- a/app/lish/createPub/CreatePubForm.tsx +++ b/app/lish/createPub/CreatePubForm.tsx @@ -53,7 +53,12 @@ export const CreatePubForm = () => { description: descriptionValue, iconFile: logoFile, subdomain: domainValue, - preferences: { showInDiscover, showComments: true }, + preferences: { + showInDiscover, + showComments: true, + showMentions: true, + showPrevNext: false, + }, }); if (!result.success) { @@ -68,7 +73,9 @@ export const CreatePubForm = () => { setTimeout(() => { setFormState("normal"); if (result.publication) - router.push(`${getBasePublicationURL(result.publication)}/dashboard`); + router.push( + `${getBasePublicationURL(result.publication)}/dashboard`, + ); }, 500); }} > diff --git a/app/lish/createPub/UpdatePubForm.tsx b/app/lish/createPub/UpdatePubForm.tsx index 6855ae85..90843f90 100644 --- a/app/lish/createPub/UpdatePubForm.tsx +++ b/app/lish/createPub/UpdatePubForm.tsx @@ -21,6 +21,7 @@ import Link from "next/link"; import { Checkbox } from "components/Checkbox"; import type { GetDomainConfigResponseBody } from "@vercel/sdk/esm/models/getdomainconfigop"; import { PubSettingsHeader } from "../[did]/[publication]/dashboard/settings/PublicationSettings"; +import { Toggle } from "components/Toggle"; export const EditPubForm = (props: { backToMenuAction: () => void; @@ -43,6 +44,15 @@ export const EditPubForm = (props: { ? true : record.preferences.showComments, ); + let showMentions = + record?.preferences?.showMentions === undefined + ? true + : record.preferences.showMentions; + let showPrevNext = + record?.preferences?.showPrevNext === undefined + ? true + : record.preferences.showPrevNext; + let [descriptionValue, setDescriptionValue] = useState( record?.description || "", ); @@ -74,6 +84,8 @@ export const EditPubForm = (props: { preferences: { showInDiscover: showInDiscover, showComments: showComments, + showMentions: showMentions, + showPrevNext: showPrevNext, }, }); toast({ type: "success", content: "Updated!" }); @@ -90,7 +102,7 @@ export const EditPubForm = (props: { General Settings
-
+

Logo (optional)

@@ -160,11 +172,11 @@ export const EditPubForm = (props: {
- setShowInDiscover(e.target.checked)} + setShowInDiscover(!showInDiscover)} > - ); diff --git a/app/lish/createPub/updatePublication.ts b/app/lish/createPub/updatePublication.ts index a1e79b3c..6881ac03 100644 --- a/app/lish/createPub/updatePublication.ts +++ b/app/lish/createPub/updatePublication.ts @@ -25,8 +25,8 @@ export async function updatePublication({ }: { uri: string; name: string; - description: string; - iconFile: File | null; + description?: string; + iconFile?: File | null; preferences?: Omit; }): Promise { let identity = await getIdentityData(); diff --git a/components/Canvas.tsx b/components/Canvas.tsx index 6f5b1af8..3b3b5903 100644 --- a/components/Canvas.tsx +++ b/components/Canvas.tsx @@ -170,6 +170,7 @@ const CanvasMetadata = (props: { isSubpage: boolean | undefined }) => { let pubRecord = pub.publications.record as PubLeafletPublication.Record; let showComments = pubRecord.preferences?.showComments; + let showMentions = pubRecord.preferences?.showMentions; return (
@@ -178,9 +179,11 @@ const CanvasMetadata = (props: { isSubpage: boolean | undefined }) => { —
)} -
- — -
+ {showComments && ( +
+ — +
+ )} {!props.isSubpage && ( <> diff --git a/components/InteractionsPreview.tsx b/components/InteractionsPreview.tsx index a0cd1476..0a4f53b2 100644 --- a/components/InteractionsPreview.tsx +++ b/components/InteractionsPreview.tsx @@ -14,11 +14,13 @@ export const InteractionPreview = (props: { tags?: string[]; postUrl: string; showComments: boolean | undefined; + showMentions: boolean | undefined; + share?: boolean; }) => { let smoker = useSmoker(); let interactionsAvailable = - props.quotesCount > 0 || + (props.quotesCount > 0 && props.showMentions !== false) || (props.showComments !== false && props.commentsCount > 0); const tagsCount = props.tags?.length || 0; @@ -36,7 +38,7 @@ export const InteractionPreview = (props: { )} - {props.quotesCount === 0 ? null : ( + {props.showMentions === false || props.quotesCount === 0 ? null : ( { )} -
- — -
+ {pubRecord?.preferences?.showMentions && ( +
+ — +
+ )} {pubRecord?.preferences?.showComments && (
— diff --git a/components/PostListing.tsx b/components/PostListing.tsx index 417357ad..4e0eff39 100644 --- a/components/PostListing.tsx +++ b/components/PostListing.tsx @@ -97,6 +97,7 @@ export const PostListing = (props: Post) => { commentsCount={comments} tags={tags} showComments={pubRecord?.preferences?.showComments} + showMentions={pubRecord?.preferences?.showMentions} share />
diff --git a/lexicons/api/lexicons.ts b/lexicons/api/lexicons.ts index e4dd9245..6d0acd58 100644 --- a/lexicons/api/lexicons.ts +++ b/lexicons/api/lexicons.ts @@ -1810,6 +1810,14 @@ export const schemaDict = { type: 'boolean', default: true, }, + showMentions: { + type: 'boolean', + default: true, + }, + showPrevNext: { + type: 'boolean', + default: false, + }, }, }, theme: { diff --git a/lexicons/api/types/pub/leaflet/publication.ts b/lexicons/api/types/pub/leaflet/publication.ts index 1a7e9abd..88314a28 100644 --- a/lexicons/api/types/pub/leaflet/publication.ts +++ b/lexicons/api/types/pub/leaflet/publication.ts @@ -37,6 +37,8 @@ export interface Preferences { $type?: 'pub.leaflet.publication#preferences' showInDiscover: boolean showComments: boolean + showMentions: boolean + showPrevNext: boolean } const hashPreferences = 'preferences' diff --git a/lexicons/pub/leaflet/publication.json b/lexicons/pub/leaflet/publication.json index 707854bd..3e6b5bec 100644 --- a/lexicons/pub/leaflet/publication.json +++ b/lexicons/pub/leaflet/publication.json @@ -51,6 +51,14 @@ "showComments": { "type": "boolean", "default": true + }, + "showMentions": { + "type": "boolean", + "default": true + }, + "showPrevNext": { + "type": "boolean", + "default": false } } }, diff --git a/lexicons/src/publication.ts b/lexicons/src/publication.ts index 0da97aa6..fa679b3b 100644 --- a/lexicons/src/publication.ts +++ b/lexicons/src/publication.ts @@ -27,6 +27,8 @@ export const PubLeafletPublication: LexiconDoc = { properties: { showInDiscover: { type: "boolean", default: true }, showComments: { type: "boolean", default: true }, + showMentions: { type: "boolean", default: true }, + showPrevNext: { type: "boolean", default: false }, }, }, theme: { -- 2.51.2