70 lines
2.0 KiB
TypeScript
70 lines
2.0 KiB
TypeScript
"use client";
|
|
|
|
/**
|
|
* SharePostProvider — mounts a single global SharePostSheet that any
|
|
* component in the tree can summon via `useSharePost().openShareSheet(post)`.
|
|
*
|
|
* The sheet itself is a heavy modal/drawer that loads URLs, pre-fetches
|
|
* images for native share, etc. — we don't want every caller to mount
|
|
* its own copy. Mounting once at the root and triggering via context
|
|
* keeps state isolated and makes "Share" a one-liner anywhere downstream:
|
|
*
|
|
* const { openShareSheet } = useSharePost();
|
|
* openShareSheet(newlyCreatedPost);
|
|
*
|
|
* Used today by compose-post.tsx (toast after a successful post create
|
|
* offers a "Share" action that opens the sheet for the new post).
|
|
* Future surfaces like profile cards can call into the same hook.
|
|
*/
|
|
|
|
import {
|
|
createContext,
|
|
useCallback,
|
|
useContext,
|
|
useState,
|
|
} from "react";
|
|
import type { Post } from "@/lib/social";
|
|
import { useMediaQuery } from "@/components/selection-toolbar/shared";
|
|
import { SharePostSheet } from "./share-post-sheet";
|
|
|
|
type SharePostContextValue = {
|
|
openShareSheet: (post: Post) => void;
|
|
};
|
|
|
|
const SharePostContext = createContext<SharePostContextValue | null>(null);
|
|
|
|
export function useSharePost(): SharePostContextValue {
|
|
const v = useContext(SharePostContext);
|
|
if (!v) {
|
|
throw new Error("useSharePost must be used inside <SharePostProvider>");
|
|
}
|
|
return v;
|
|
}
|
|
|
|
export function SharePostProvider({
|
|
children,
|
|
}: {
|
|
children: React.ReactNode;
|
|
}) {
|
|
const [activePost, setActivePost] = useState<Post | null>(null);
|
|
const isMobile = useMediaQuery("(max-width: 767px)");
|
|
|
|
const openShareSheet = useCallback((post: Post) => {
|
|
setActivePost(post);
|
|
}, []);
|
|
|
|
return (
|
|
<SharePostContext.Provider value={{ openShareSheet }}>
|
|
{children}
|
|
{activePost ? (
|
|
<SharePostSheet
|
|
open={true}
|
|
onClose={() => setActivePost(null)}
|
|
post={activePost}
|
|
isMobile={isMobile}
|
|
/>
|
|
) : null}
|
|
</SharePostContext.Provider>
|
|
);
|
|
}
|