From 4e80ae0ca4cf58c82ebbe17c1f65eea45cc92a3d Mon Sep 17 00:00:00 2001 From: celine Date: Tue, 13 Jan 2026 15:12:13 -1000 Subject: [PATCH 1/6] fixed some layout with popover, now opens on tap rather than hover (#255) * fixed some layout with popover, now opens on tap rather than hover * little popover fixes --- .../p/[didOrHandle]/ProfileHeader.tsx | 92 +++++++++++-------- .../p/[didOrHandle]/ProfileTabs.tsx | 2 +- components/ProfilePopover.tsx | 60 ++++++------ 3 files changed, 90 insertions(+), 64 deletions(-) diff --git a/app/(home-pages)/p/[didOrHandle]/ProfileHeader.tsx b/app/(home-pages)/p/[didOrHandle]/ProfileHeader.tsx index 459ef99c..a0fd68e4 100644 --- a/app/(home-pages)/p/[didOrHandle]/ProfileHeader.tsx +++ b/app/(home-pages)/p/[didOrHandle]/ProfileHeader.tsx @@ -1,8 +1,6 @@ "use client"; import { Avatar } from "components/Avatar"; -import { AppBskyActorProfile, PubLeafletPublication } from "lexicons/api"; -import { blobRefToSrc } from "src/utils/blobRefToSrc"; -import type { ProfileData } from "./layout"; +import { PubLeafletPublication } from "lexicons/api"; import { usePubTheme } from "components/ThemeManager/PublicationThemeProvider"; import { colorToString } from "components/ThemeManager/useColorAttribute"; import { PubIcon } from "components/ActionBar/Publications"; @@ -25,13 +23,13 @@ export const ProfileHeader = (props: { ); const displayNameElement = ( -

+

{profileRecord.displayName ? profileRecord.displayName : `@${props.profile.handle}`} @@ -40,20 +38,21 @@ export const ProfileHeader = (props: { const handleElement = profileRecord.displayName && (
@{props.profile.handle}
); + console.log(props.profile); return (
- -
-
+ {!props.popover && } +
+
{props.popover ? ( {avatarElement} @@ -61,30 +60,22 @@ export const ProfileHeader = (props: { ) : ( avatarElement )} - {props.popover ? ( - - {displayNameElement} - - ) : ( - displayNameElement - )} - {props.popover && handleElement ? ( - - {handleElement} - - ) : ( - handleElement - )} + {displayNameElement} + + {handleElement} + + +
+            {profileRecord.description
+              ? parseDescription(profileRecord.description)
+              : null}
+          
-
-          {profileRecord.description
-            ? parseDescription(profileRecord.description)
-            : null}
-        
-
+ +
@@ -104,7 +95,7 @@ export const ProfileHeader = (props: { const ProfileLinks = (props: { handle: string }) => { return ( -
+
+ {displayText} , ); @@ -241,3 +237,27 @@ function parseDescription(description: string): ReactNode[] { return parts; } + +const KnownFollowers = (props: { + viewer: ProfileViewDetailed["viewer"]; + did: string; +}) => { + if (!props.viewer?.knownFollowers) return null; + let count = props.viewer.knownFollowers.count; + + return ( + <> + + + ); +}; diff --git a/app/(home-pages)/p/[didOrHandle]/ProfileTabs.tsx b/app/(home-pages)/p/[didOrHandle]/ProfileTabs.tsx index 4609a0a1..c5b9e3a2 100644 --- a/app/(home-pages)/p/[didOrHandle]/ProfileTabs.tsx +++ b/app/(home-pages)/p/[didOrHandle]/ProfileTabs.tsx @@ -41,7 +41,7 @@ export const ProfileTabs = (props: { didOrHandle: string }) => { const bgColor = cardBorderHidden ? "var(--bg-leaflet)" : "var(--bg-page)"; return ( -
+
{ if (hoverTimeout.current) { window.clearTimeout(hoverTimeout.current); @@ -53,7 +52,7 @@ export const ProfilePopover = (props: { }} > {props.trigger} - +
} onOpenChange={setIsOpen} > @@ -66,33 +65,40 @@ export const ProfilePopover = (props: { publications={data.publications} popover /> - + +
) : ( -
Profile not found
+
No profile found...
)} - + ); }; -let KnownFollowers = (props: { - viewer: ProfileViewDetailed["viewer"]; - did: string; -}) => { - if (!props.viewer?.knownFollowers) return null; - let count = props.viewer.knownFollowers.count; +const ProfileLinks = (props: { handle: string }) => { + let linkClassName = + "flex gap-1.5 text-tertiary items-center border border-transparent px-1 rounded-md hover:bg-[var(--accent-light)] hover:border-accent-contrast hover:text-accent-contrast no-underline hover:no-underline"; return ( - <> -
- Followed by{" "} - - {props.viewer?.knownFollowers?.followers[0]?.displayName}{" "} - {count > 1 ? `and ${count - 1} other${count > 2 ? "s" : ""}` : ""} - - +
+
+
+ + + Full profile + +
+
); }; -- 2.51.2 From 24b0ad84be38b65a1e5c447726545668ca53d716 Mon Sep 17 00:00:00 2001 From: celine Date: Tue, 13 Jan 2026 20:59:03 -0500 Subject: [PATCH 2/6] lil typos --- .../[publication]/[rkey]/Interactions/InteractionDrawer.tsx | 4 ++-- components/Pages/PublicationMetadata.tsx | 5 ++++- components/ThemeManager/Pickers/PageWidthSetter.tsx | 4 ++-- components/ThemeManager/PubPickers/PubPageWidthSetter.tsx | 4 ++-- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/app/lish/[did]/[publication]/[rkey]/Interactions/InteractionDrawer.tsx b/app/lish/[did]/[publication]/[rkey]/Interactions/InteractionDrawer.tsx index 9869f9f9..9283aa1c 100644 --- a/app/lish/[did]/[publication]/[rkey]/Interactions/InteractionDrawer.tsx +++ b/app/lish/[did]/[publication]/[rkey]/Interactions/InteractionDrawer.tsx @@ -36,10 +36,10 @@ export const InteractionDrawer = (props: { return ( <> -
+
{drawer.drawer === "quotes" ? ( diff --git a/components/Pages/PublicationMetadata.tsx b/components/Pages/PublicationMetadata.tsx index cc111575..70f5f121 100644 --- a/components/Pages/PublicationMetadata.tsx +++ b/components/Pages/PublicationMetadata.tsx @@ -118,7 +118,10 @@ export const PublicationMetadata = () => { {tags && ( <> - + {pubRecord?.preferences?.showMentions || + pubRecord?.preferences?.showComments ? ( + + ) : null} )} {pubRecord?.preferences?.showMentions && ( diff --git a/components/ThemeManager/Pickers/PageWidthSetter.tsx b/components/ThemeManager/Pickers/PageWidthSetter.tsx index e075d8ba..30eeb5d3 100644 --- a/components/ThemeManager/Pickers/PageWidthSetter.tsx +++ b/components/ThemeManager/Pickers/PageWidthSetter.tsx @@ -89,7 +89,7 @@ export const PageWidthSetter = (props: {
- default (624px) + default ({defaultPreset}px)
@@ -111,7 +111,7 @@ export const PageWidthSetter = (props: {
- wide (756px) + wide ({widePreset}px)
diff --git a/components/ThemeManager/PubPickers/PubPageWidthSetter.tsx b/components/ThemeManager/PubPickers/PubPageWidthSetter.tsx index 9143fa7b..dd28017b 100644 --- a/components/ThemeManager/PubPickers/PubPageWidthSetter.tsx +++ b/components/ThemeManager/PubPickers/PubPageWidthSetter.tsx @@ -76,7 +76,7 @@ export const PubPageWidthSetter = (props: {
- default (624px) + default ({defaultPreset}px)
@@ -98,7 +98,7 @@ export const PubPageWidthSetter = (props: {
- wide (756px) + wide ({widePreset}px)
-- 2.51.2 From 10f4e467e91235aa791b501eec448a8abe3dabe3 Mon Sep 17 00:00:00 2001 From: celine Date: Wed, 14 Jan 2026 15:53:37 -0500 Subject: [PATCH 3/6] small adjustment for better scrolling on page focus --- components/Blocks/Block.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/components/Blocks/Block.tsx b/components/Blocks/Block.tsx index 0e899749..1f7ca9bb 100644 --- a/components/Blocks/Block.tsx +++ b/components/Blocks/Block.tsx @@ -32,6 +32,7 @@ import { CodeBlock } from "./CodeBlock"; import { HorizontalRule } from "./HorizontalRule"; import { deepEquals } from "src/utils/deepEquals"; import { isTextBlock } from "src/utils/isTextBlock"; +import { focusPage } from "src/utils/focusPage"; export type Block = { factID: string; @@ -62,7 +63,7 @@ export const Block = memo(function Block( // Block handles all block level events like // mouse events, keyboard events and longPress, and setting AreYouSure state // and shared styling like padding and flex for list layouting - + let { rep } = useReplicache(); let mouseHandlers = useBlockMouseHandlers(props); let handleDrop = useHandleDrop({ parent: props.parent, @@ -87,6 +88,9 @@ export const Block = memo(function Block( let [areYouSure, setAreYouSure] = useState(false); useEffect(() => { + if (selected && rep) { + focusPage(props.parent, rep); + } if (!selected) { setAreYouSure(false); } -- 2.51.2 From 6c8a991cb6ed1a96137433e8c543e9afc8356b45 Mon Sep 17 00:00:00 2001 From: celine Date: Wed, 14 Jan 2026 17:56:16 -0500 Subject: [PATCH 4/6] reverted the last change and redid it in a not stupid way --- components/Blocks/Block.tsx | 3 --- components/Blocks/useBlockMouseHandlers.ts | 12 ++++++++++++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/components/Blocks/Block.tsx b/components/Blocks/Block.tsx index 1f7ca9bb..64efceec 100644 --- a/components/Blocks/Block.tsx +++ b/components/Blocks/Block.tsx @@ -88,9 +88,6 @@ export const Block = memo(function Block( let [areYouSure, setAreYouSure] = useState(false); useEffect(() => { - if (selected && rep) { - focusPage(props.parent, rep); - } if (!selected) { setAreYouSure(false); } diff --git a/components/Blocks/useBlockMouseHandlers.ts b/components/Blocks/useBlockMouseHandlers.ts index fd1e0188..eca3cc68 100644 --- a/components/Blocks/useBlockMouseHandlers.ts +++ b/components/Blocks/useBlockMouseHandlers.ts @@ -8,6 +8,8 @@ import { useReplicache } from "src/replicache"; import { getBlocksWithType } from "src/hooks/queries/useBlocks"; import { focusBlock } from "src/utils/focusBlock"; import { useIsMobile } from "src/hooks/isMobile"; +import { scrollIntoViewIfNeeded } from "src/utils/scrollIntoViewIfNeeded"; +import { elementId } from "src/utils/elementId"; let debounce: number | null = null; export function useBlockMouseHandlers(props: Block) { @@ -39,6 +41,16 @@ export function useBlockMouseHandlers(props: Block) { parent: props.parent, }); useUIState.getState().setSelectedBlock(props); + + // scroll to the page containing the block, if offscreen + let parentPage = elementId.page(props.parent).container; + setTimeout(() => { + scrollIntoViewIfNeeded( + document.getElementById(parentPage), + false, + "smooth", + ); + }, 50); } }, [props, entity_set.permissions.write, isMobile], -- 2.51.2 From ebc99d35cb90035d991afde51e96f2285af5bd89 Mon Sep 17 00:00:00 2001 From: celine Date: Thu, 15 Jan 2026 17:42:58 -0500 Subject: [PATCH 5/6] doing a pass to make the show mention, comment, and prev/next cleaner --- .../[did]/[publication]/[rkey]/CanvasPage.tsx | 4 +- .../[rkey]/Interactions/Interactions.tsx | 29 +++--------- .../[rkey]/LinearDocumentPage.tsx | 10 ++--- .../[rkey]/PostHeader/PostHeader.tsx | 4 +- .../[rkey]/PostPrevNextButtons.tsx | 4 +- .../[publication]/[rkey]/PostSubscribe.tsx | 45 +++++++++++++++++++ .../dashboard/PublishedPostsLists.tsx | 8 +++- .../dashboard/settings/PostOptions.tsx | 1 - app/lish/[did]/[publication]/page.tsx | 8 +++- app/lish/createPub/CreatePubForm.tsx | 2 +- components/Canvas.tsx | 4 +- components/InteractionsPreview.tsx | 8 ++-- components/PostListing.tsx | 4 +- lexicons/api/lexicons.ts | 2 +- lexicons/pub/leaflet/publication.json | 2 +- lexicons/src/publication.ts | 2 +- 16 files changed, 85 insertions(+), 52 deletions(-) create mode 100644 app/lish/[did]/[publication]/[rkey]/PostSubscribe.tsx diff --git a/app/lish/[did]/[publication]/[rkey]/CanvasPage.tsx b/app/lish/[did]/[publication]/[rkey]/CanvasPage.tsx index 1ea95dcc..4d28dcc3 100644 --- a/app/lish/[did]/[publication]/[rkey]/CanvasPage.tsx +++ b/app/lish/[did]/[publication]/[rkey]/CanvasPage.tsx @@ -216,8 +216,8 @@ const CanvasMetadata = (props: { {!props.isSubpage && ( diff --git a/app/lish/[did]/[publication]/[rkey]/Interactions/Interactions.tsx b/app/lish/[did]/[publication]/[rkey]/Interactions/Interactions.tsx index a612f7e7..6492c0f2 100644 --- a/app/lish/[did]/[publication]/[rkey]/Interactions/Interactions.tsx +++ b/app/lish/[did]/[publication]/[rkey]/Interactions/Interactions.tsx @@ -107,8 +107,8 @@ export const Interactions = (props: { quotesCount: number; commentsCount: number; className?: string; - showComments?: boolean; - showMentions?: boolean; + showComments: boolean; + showMentions: boolean; pageId?: string; }) => { const data = useContext(PostPageContext); @@ -168,8 +168,8 @@ export const ExpandedInteractions = (props: { quotesCount: number; commentsCount: number; className?: string; - showComments?: boolean; - showMentions?: boolean; + showComments: boolean; + showMentions: boolean; pageId?: string; }) => { const data = useContext(PostPageContext); @@ -210,22 +210,6 @@ export const ExpandedInteractions = (props: {
- {!subscribed && !isAuthor && publication && publication.record && ( -
-
-
-
Subscribe to {publication.name}
{" "} - to get updates in Reader, RSS, or via Bluesky Feed -
- -
-
- )} {tagCount > 0 && ( <>
@@ -242,8 +226,7 @@ export const ExpandedInteractions = (props: { ) : ( <>
- {props.quotesCount === 0 || - props.showMentions === false ? null : ( + {props.quotesCount === 0 || !props.showMentions ? null : ( )} - {props.showComments === false ? null : ( + {!props.showComments ? null : (
diff --git a/app/lish/[did]/[publication]/[rkey]/PostPrevNextButtons.tsx b/app/lish/[did]/[publication]/[rkey]/PostPrevNextButtons.tsx index 48a1a99c..403019b7 100644 --- a/app/lish/[did]/[publication]/[rkey]/PostPrevNextButtons.tsx +++ b/app/lish/[did]/[publication]/[rkey]/PostPrevNextButtons.tsx @@ -10,9 +10,7 @@ import { useContext } from "react"; import { SpeedyLink } from "components/SpeedyLink"; import { ArrowRightTiny } from "components/Icons/ArrowRightTiny"; -export const PostPrevNextButtons = (props: { - showPrevNext: boolean | undefined; -}) => { +export const PostPrevNextButtons = (props: { showPrevNext: boolean }) => { let postData = useContext(PostPageContext); let pub = postData?.documents_in_publications[0]?.publications; diff --git a/app/lish/[did]/[publication]/[rkey]/PostSubscribe.tsx b/app/lish/[did]/[publication]/[rkey]/PostSubscribe.tsx new file mode 100644 index 00000000..90b3a8ac --- /dev/null +++ b/app/lish/[did]/[publication]/[rkey]/PostSubscribe.tsx @@ -0,0 +1,45 @@ +"use client"; +import { useContext } from "react"; +import { PostPageContext } from "./PostPageContext"; +import { useIdentityData } from "components/IdentityProvider"; +import { SubscribeWithBluesky } from "app/lish/Subscribe"; +import { getPublicationURL } from "app/lish/createPub/getPublicationURL"; + +export const PostSubscribe = () => { + const data = useContext(PostPageContext); + let { identity } = useIdentityData(); + + let publication = data?.documents_in_publications[0]?.publications; + + let subscribed = + identity?.atp_did && + publication?.publication_subscriptions && + publication?.publication_subscriptions.find( + (s) => s.identity === identity.atp_did, + ); + + let isAuthor = + identity && + identity.atp_did === + data?.documents_in_publications[0]?.publications?.identity_did && + data?.leaflets_in_publications[0]; + + if (!subscribed && !isAuthor && publication && publication.record) + return ( +
+
+
+
Subscribe to {publication.name}
to + get updates in Reader, RSS, or via Bluesky Feed +
+ +
+
+ ); + else return; +}; diff --git a/app/lish/[did]/[publication]/dashboard/PublishedPostsLists.tsx b/app/lish/[did]/[publication]/dashboard/PublishedPostsLists.tsx index d8982373..29929a5b 100644 --- a/app/lish/[did]/[publication]/dashboard/PublishedPostsLists.tsx +++ b/app/lish/[did]/[publication]/dashboard/PublishedPostsLists.tsx @@ -139,8 +139,12 @@ export function PublishedPostsList(props: { quotesCount={quotes} commentsCount={comments} tags={tags} - showComments={pubRecord?.preferences?.showComments} - showMentions={pubRecord?.preferences?.showMentions} + showComments={ + pubRecord?.preferences?.showComments !== false + } + showMentions={ + pubRecord?.preferences?.showMentions !== false + } postUrl={`${getPublicationURL(publication)}/${uri.rkey}`} />
diff --git a/app/lish/[did]/[publication]/dashboard/settings/PostOptions.tsx b/app/lish/[did]/[publication]/dashboard/settings/PostOptions.tsx index 6309ca9b..d3991fc7 100644 --- a/app/lish/[did]/[publication]/dashboard/settings/PostOptions.tsx +++ b/app/lish/[did]/[publication]/dashboard/settings/PostOptions.tsx @@ -54,7 +54,6 @@ export const PostOptions = (props: { }, }); toast({ type: "success", content: Posts Updated! }); - console.log(record.preferences?.showPrevNext); props.setLoading(false); mutate("publication-data"); }} diff --git a/app/lish/[did]/[publication]/page.tsx b/app/lish/[did]/[publication]/page.tsx index 3266835d..7e579840 100644 --- a/app/lish/[did]/[publication]/page.tsx +++ b/app/lish/[did]/[publication]/page.tsx @@ -171,8 +171,12 @@ export default async function Publication(props: { commentsCount={comments} tags={tags} postUrl={`${getPublicationURL(publication)}/${uri.rkey}`} - showComments={record?.preferences?.showComments} - showMentions={record?.preferences?.showMentions} + showComments={ + record?.preferences?.showComments !== false + } + showMentions={ + record?.preferences?.showMentions !== false + } />
diff --git a/app/lish/createPub/CreatePubForm.tsx b/app/lish/createPub/CreatePubForm.tsx index 5c7c8efb..2dbe924e 100644 --- a/app/lish/createPub/CreatePubForm.tsx +++ b/app/lish/createPub/CreatePubForm.tsx @@ -57,7 +57,7 @@ export const CreatePubForm = () => { showInDiscover, showComments: true, showMentions: true, - showPrevNext: false, + showPrevNext: true, }, }); diff --git a/components/Canvas.tsx b/components/Canvas.tsx index 3b3b5903..b0274131 100644 --- a/components/Canvas.tsx +++ b/components/Canvas.tsx @@ -169,8 +169,8 @@ const CanvasMetadata = (props: { isSubpage: boolean | undefined }) => { if (!pub || !pub.publications) return null; let pubRecord = pub.publications.record as PubLeafletPublication.Record; - let showComments = pubRecord.preferences?.showComments; - let showMentions = pubRecord.preferences?.showMentions; + let showComments = pubRecord.preferences?.showComments !== false; + let showMentions = pubRecord.preferences?.showMentions !== false; return (
diff --git a/components/InteractionsPreview.tsx b/components/InteractionsPreview.tsx index 0a4f53b2..c2adf6f3 100644 --- a/components/InteractionsPreview.tsx +++ b/components/InteractionsPreview.tsx @@ -13,14 +13,14 @@ export const InteractionPreview = (props: { commentsCount: number; tags?: string[]; postUrl: string; - showComments: boolean | undefined; - showMentions: boolean | undefined; + showComments: boolean; + showMentions: boolean; share?: boolean; }) => { let smoker = useSmoker(); let interactionsAvailable = - (props.quotesCount > 0 && props.showMentions !== false) || + (props.quotesCount > 0 && props.showMentions) || (props.showComments !== false && props.commentsCount > 0); const tagsCount = props.tags?.length || 0; @@ -38,7 +38,7 @@ export const InteractionPreview = (props: { )} - {props.showMentions === false || props.quotesCount === 0 ? null : ( + {props.showMentions || props.quotesCount === 0 ? null : ( { quotesCount={quotes} commentsCount={comments} tags={tags} - showComments={pubRecord?.preferences?.showComments} - showMentions={pubRecord?.preferences?.showMentions} + showComments={pubRecord?.preferences?.showComments !== false} + showMentions={pubRecord?.preferences?.showMentions !== false} share />
diff --git a/lexicons/api/lexicons.ts b/lexicons/api/lexicons.ts index 6d0acd58..7c46a663 100644 --- a/lexicons/api/lexicons.ts +++ b/lexicons/api/lexicons.ts @@ -1816,7 +1816,7 @@ export const schemaDict = { }, showPrevNext: { type: 'boolean', - default: false, + default: true, }, }, }, diff --git a/lexicons/pub/leaflet/publication.json b/lexicons/pub/leaflet/publication.json index 3e6b5bec..0627addf 100644 --- a/lexicons/pub/leaflet/publication.json +++ b/lexicons/pub/leaflet/publication.json @@ -58,7 +58,7 @@ }, "showPrevNext": { "type": "boolean", - "default": false + "default": true } } }, diff --git a/lexicons/src/publication.ts b/lexicons/src/publication.ts index fa679b3b..57bbbef9 100644 --- a/lexicons/src/publication.ts +++ b/lexicons/src/publication.ts @@ -28,7 +28,7 @@ export const PubLeafletPublication: LexiconDoc = { showInDiscover: { type: "boolean", default: true }, showComments: { type: "boolean", default: true }, showMentions: { type: "boolean", default: true }, - showPrevNext: { type: "boolean", default: false }, + showPrevNext: { type: "boolean", default: true }, }, }, theme: { -- 2.51.2 From 0920f6390235c222296f3ea5b9263c5548cac4ca Mon Sep 17 00:00:00 2001 From: celine Date: Thu, 15 Jan 2026 17:57:54 -0500 Subject: [PATCH 6/6] fixing firfox bugs causing mentions to wrap --- app/globals.css | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/app/globals.css b/app/globals.css index b66df5e6..6a447a52 100644 --- a/app/globals.css +++ b/app/globals.css @@ -309,8 +309,6 @@ pre.shiki { .ProseMirror .didMention.ProseMirror-selectednode { @apply text-accent-contrast; @apply px-0.5; - @apply -mx-[3px]; /* extra px to account for the border*/ - @apply -my-px; /*to account for the border*/ @apply rounded-[4px]; @apply box-decoration-clone; background-color: rgba(var(--accent-contrast), 0.2); @@ -321,12 +319,12 @@ pre.shiki { @apply cursor-pointer; @apply text-accent-contrast; @apply px-0.5; - @apply -mx-[3px]; - @apply -my-px; /*to account for the border*/ @apply rounded-[4px]; @apply box-decoration-clone; background-color: rgba(var(--accent-contrast), 0.2); border: 1px solid transparent; + display: inline; + white-space: normal; } .multiselected:focus-within .selection-highlight { -- 2.51.2