diff --git a/app/lish/[did]/[publication]/[rkey]/Interactions/InteractionDrawer.tsx b/app/lish/[did]/[publication]/[rkey]/Interactions/InteractionDrawer.tsx
index b2c7d0c1..f83f5dd1 100644
--- a/app/lish/[did]/[publication]/[rkey]/Interactions/InteractionDrawer.tsx
+++ b/app/lish/[did]/[publication]/[rkey]/Interactions/InteractionDrawer.tsx
@@ -13,7 +13,7 @@ export const InteractionDrawer = (props: {
comments: Comment[];
did: string;
}) => {
- let drawer = useDrawerOpen();
+ let drawer = useDrawerOpen(props.document_uri);
if (!drawer) return null;
return (
<>
@@ -36,10 +36,10 @@ export const InteractionDrawer = (props: {
);
};
-export const useDrawerOpen = () => {
+export const useDrawerOpen = (uri: string) => {
let params = useSearchParams();
let interactionDrawerSearchParam = params.get("interactionDrawer");
- let { drawerOpen: open, drawer } = useInteractionState();
+ let { drawerOpen: open, drawer } = useInteractionState(uri);
if (open === false || (open === undefined && !interactionDrawerSearchParam))
return null;
return drawer || interactionDrawerSearchParam;
diff --git a/app/lish/[did]/[publication]/[rkey]/Interactions/Interactions.tsx b/app/lish/[did]/[publication]/[rkey]/Interactions/Interactions.tsx
index 76a76e86..171037ed 100644
--- a/app/lish/[did]/[publication]/[rkey]/Interactions/Interactions.tsx
+++ b/app/lish/[did]/[publication]/[rkey]/Interactions/Interactions.tsx
@@ -8,6 +8,7 @@ import type { Comment } from "./Comments";
import { QuotePosition } from "../quotePosition";
import { useContext } from "react";
import { PostPageContext } from "../PostPageContext";
+import { scrollIntoView } from "src/utils/scrollIntoView";
type InteractionState = {
drawerOpen: undefined | boolean;
@@ -27,9 +28,9 @@ export let useInteractionStateStore = create<{
[document_uri: string]: InteractionState;
}>(() => ({}));
-export function useInteractionState(document_uri?: string) {
+export function useInteractionState(document_uri: string) {
return useInteractionStateStore((state) => {
- if (!document_uri || !state[document_uri]) {
+ if (!state[document_uri]) {
return defaultInteractionState;
}
return state[document_uri];
@@ -87,21 +88,7 @@ export function openInteractionDrawer(
flushSync(() => {
setInteractionState(document_uri, { drawerOpen: true, drawer });
});
- let el = document.getElementById("interaction-drawer");
- let isOffscreen = false;
- if (el) {
- const rect = el.getBoundingClientRect();
- const windowWidth =
- window.innerWidth || document.documentElement.clientWidth;
- isOffscreen = rect.right > windowWidth - 64;
- }
-
- if (el && isOffscreen)
- el.scrollIntoView({
- behavior: "smooth",
- block: "center",
- inline: "center",
- });
+ scrollIntoView("interaction-drawer");
}
export const Interactions = (props: {
diff --git a/app/lish/[did]/[publication]/[rkey]/PostPages.tsx b/app/lish/[did]/[publication]/[rkey]/PostPages.tsx
index 380955b8..54e14c2f 100644
--- a/app/lish/[did]/[publication]/[rkey]/PostPages.tsx
+++ b/app/lish/[did]/[publication]/[rkey]/PostPages.tsx
@@ -9,7 +9,7 @@ import { ProfileViewDetailed } from "@atproto/api/dist/client/types/app/bsky/act
import { getPublicationURL } from "app/lish/createPub/getPublicationURL";
import { SubscribeWithBluesky } from "app/lish/Subscribe";
import { EditTiny } from "components/Icons/EditTiny";
-import { Interactions, useInteractionState } from "./Interactions/Interactions";
+import { Interactions } from "./Interactions/Interactions";
import { PostContent } from "./PostContent";
import { PostHeader } from "./PostHeader/PostHeader";
import { useIdentityData } from "components/IdentityProvider";
@@ -25,21 +25,28 @@ import { PageOptionButton } from "components/Pages/PageOptions";
import { CloseTiny } from "components/Icons/CloseTiny";
import { PageWrapper } from "components/Pages/Page";
import { Fragment } from "react";
+import { flushSync } from "react-dom";
+import { scrollIntoView } from "src/utils/scrollIntoView";
export const usePostPageUIState = create(() => ({
pages: [] as string[],
}));
-export const openPage = (parent: string | undefined, page: string) =>
- usePostPageUIState.setState((state) => {
- let parentPosition = state.pages.findIndex((s) => s == parent);
- return {
- pages:
- parentPosition === -1
- ? [page]
- : [...state.pages.slice(0, parentPosition + 1), page],
- };
+export const openPage = (parent: string | undefined, page: string) => {
+ flushSync(() => {
+ usePostPageUIState.setState((state) => {
+ let parentPosition = state.pages.findIndex((s) => s == parent);
+ return {
+ pages:
+ parentPosition === -1
+ ? [page]
+ : [...state.pages.slice(0, parentPosition + 1), page],
+ };
+ });
});
+ scrollIntoView(`post-page-${page}`);
+};
+
export const closePage = (page: string) =>
usePostPageUIState.setState((state) => {
let parentPosition = state.pages.findIndex((s) => s == page);
@@ -58,7 +65,9 @@ export function PostPages({
pubRecord,
prerenderedCodeBlocks,
bskyPostData,
+ document_uri,
}: {
+ document_uri: string;
document: PostPageData;
blocks: PubLeafletPagesLinearDocument.Block[];
name: string;
@@ -70,7 +79,7 @@ export function PostPages({
preferences: { showComments?: boolean };
}) {
let { identity } = useIdentityData();
- let drawerOpen = useDrawerOpen();
+ let drawerOpen = useDrawerOpen(document_uri);
let pages = usePostPageUIState((s) => s.pages);
if (!document || !document.documents_in_publications[0].publications)
return null;
@@ -154,7 +163,7 @@ export function PostPages({
{
+ const entry = entries[0];
+
+ // If element is not sufficiently visible, scroll to it
+ if (!entry.isIntersecting || entry.intersectionRatio < threshold) {
+ const elementRect = element.getBoundingClientRect();
+ const containerRect = scrollContainer.getBoundingClientRect();
+
+ // Calculate the target scroll position
+ // We want to center the element horizontally in the container
+ const targetScrollLeft =
+ scrollContainer.scrollLeft +
+ elementRect.left -
+ containerRect.left -
+ (containerRect.width - elementRect.width) / 2;
+
+ scrollContainer.scrollTo({
+ left: targetScrollLeft,
+ behavior: "smooth",
+ });
+ }
+
+ // Disconnect after checking once
+ observer.disconnect();
+ },
+ {
+ root: scrollContainer,
+ threshold: threshold,
+ },
+ );
+
+ observer.observe(element);
+}