From 8da18cc360187345827ada16caa233ad234a49e1 Mon Sep 17 00:00:00 2001 From: Caspian Date: Wed, 20 Dec 2023 15:36:00 +0000 Subject: [PATCH] Enable easy linking of short-form content and ensure navigation to this content is possible when clicking on the short-form content card. --- src/components/ui/XLogShorts.tsx | 44 +++++++++--- src/markdown/embed-transformers/XLogShorts.ts | 71 ++++++++----------- 2 files changed, 63 insertions(+), 52 deletions(-) diff --git a/src/components/ui/XLogShorts.tsx b/src/components/ui/XLogShorts.tsx index 1ebb9fbf..6b1957d5 100644 --- a/src/components/ui/XLogShorts.tsx +++ b/src/components/ui/XLogShorts.tsx @@ -11,8 +11,17 @@ import { useGetSite } from "~/queries/site" import { Time } from "../common/Time" import PostCover from "../home/PostCover" import { Avatar } from "./Avatar" +import { UniLink } from "./UniLink" + +interface Props { + slug: string + handle: string + url: string +} + +const XLogShorts: FC = ({ slug, handle, url }) => { + const [isExpanded, setIsExpanded] = React.useState(false) -const XLogShorts: FC<{ slug: string; handle: string }> = ({ slug, handle }) => { const locale = useLocale() as Language // https://xlog.app/site/lca/JOoXQKAtZYYFrnzntDlJ6?content_type=shorts const site = useGetSite(handle) @@ -30,21 +39,31 @@ const XLogShorts: FC<{ slug: string; handle: string }> = ({ slug, handle }) => { .filter(Boolean) const isMobile = isMobileDevice() - const [isExpanded, setIsExpanded] = React.useState(false) + const isShort = !!page.data?.metadata?.content?.tags?.includes("short") - const toggleExpand = useCallback(() => { - setIsExpanded((prev) => !prev) - }, []) + const toggleExpand = useCallback( + (e: React.MouseEvent) => { + e.stopPropagation() + setIsExpanded((prev) => !prev) + }, + [], + ) + + const handleRedirect = useCallback(() => { + window.open(url, "_blank") + }, [url]) if (page.isLoading) return
Loading...
+ if (!isShort) return {url} + return (
= ({ slug, handle }) => { className={cn( "w-full h-full mb-2 sm:mb-0 align-middle flex items-center justify-center", isExpanded ? "sm:w-[350px]" : "sm:w-[150px]", - "transition-width duration-500 ease-in-out", + "transition-all duration-500 ease-in-out", )} > = ({ slug, handle }) => {
)}
-

+

{page.data?.metadata?.content?.content}

@@ -111,11 +134,12 @@ const XLogShorts: FC<{ slug: string; handle: string }> = ({ slug, handle }) => {
diff --git a/src/markdown/embed-transformers/XLogShorts.ts b/src/markdown/embed-transformers/XLogShorts.ts index df4b08c9..02d9d674 100644 --- a/src/markdown/embed-transformers/XLogShorts.ts +++ b/src/markdown/embed-transformers/XLogShorts.ts @@ -1,54 +1,41 @@ import { match } from "path-to-regexp" import type { Transformer } from "../rehype-embed" -import { isHostIncludes } from "./utils" + +function getParamsFromShortsURL(url: URL) { + let slug = "" + let handle = "" + + // https://caspian-3030.xlog.app/AtOAglnMV_N6xslDbfhz4?ct=shorts + let matched = match<{ slug: string }>("/:slug")(url.pathname) + + if (matched) { + slug = matched.params.slug + handle = url.host.split(".")[0] + } else { + // https://xlog.app/site/caspian-3030/AtOAglnMV_N6xslDbfhz4?ct=shorts + matched = match<{ slug: string; handle: string }>("/site/:handle/:slug")( + url.pathname, + ) + + if (!matched) return undefined + + slug = matched?.params.slug || "" + // @ts-ignore + handle = matched?.params.handle || "" + } + + return { slug, handle } +} export const XLogShortsTransformer: Transformer = { name: "XLogShorts", shouldTransform(url) { - // There are two patterns for xlog shorts url - - const { host, pathname, searchParams } = url - const hasShortsParam = searchParams.get("ct") === "shorts" - - /** - * content type param is required - * @example ?ct=shorts - * */ - if (!hasShortsParam) return false - - // https://xlog.app/site/caspian-3030/AtOAglnMV_N6xslDbfhz4?ct=shorts - if (isHostIncludes("xlog.app", host) && pathname.startsWith("/site/")) { - return true - } - - // https://caspian-3030.xlog.app/AtOAglnMV_N6xslDbfhz4?ct=shorts - return /^[a-z0-9-]+\.xlog\.app/.test(host) + return !!getParamsFromShortsURL(url) }, getHTML(url) { - let slug = "" - let handle = "" + const { slug, handle } = getParamsFromShortsURL(url)! - // import { match } from "path-to-regexp" - // https://caspian-3030.xlog.app/AtOAglnMV_N6xslDbfhz4?ct=shorts - let matched = match<{ slug: string }>("/:slug")(url.pathname) - - if (matched) { - slug = matched.params.slug - handle = url.host.split(".")[0] - } else { - // https://xlog.app/site/caspian-3030/AtOAglnMV_N6xslDbfhz4?ct=shorts - matched = match<{ slug: string; handle: string }>("/site/:handle/:slug")( - url.pathname, - ) - - if (!matched) return - - slug = matched?.params.slug || "" - // @ts-ignore - handle = matched?.params.handle || "" - } - - return `` + return `` }, }