From 3edf43af7c3343fba1d439ff124687dc3de6063d Mon Sep 17 00:00:00 2001 From: DIYgod Date: Sun, 14 Jan 2024 11:32:03 +0800 Subject: [PATCH] Revert "feat: remove tweet embeding" This reverts commit 7fcb61fd5fbeb78057ed5d1ff57b4832f0a0d2ca. --- src/app/api/tweet/route.ts | 26 ++++++++++++++++++++++++ src/components/ui/Tweet.tsx | 24 ++++++++++++++++++++++ src/markdown/embed-transformers/Tweet.ts | 19 +++++++++++++++++ src/markdown/embed-transformers/index.ts | 2 ++ src/markdown/index.ts | 2 ++ 5 files changed, 73 insertions(+) create mode 100644 src/app/api/tweet/route.ts create mode 100644 src/components/ui/Tweet.tsx create mode 100644 src/markdown/embed-transformers/Tweet.ts diff --git a/src/app/api/tweet/route.ts b/src/app/api/tweet/route.ts new file mode 100644 index 00000000..5553b156 --- /dev/null +++ b/src/app/api/tweet/route.ts @@ -0,0 +1,26 @@ +import { getTweet, Tweet } from "react-tweet/api" + +import { cacheGet } from "~/lib/redis.server" +import { getQuery, NextServerResponse } from "~/lib/server-helper" + +export async function GET(req: Request): Promise { + let { id: tweetId } = getQuery(req) + const res = new NextServerResponse() + + if (!tweetId) { + return res.status(400).json({ error: "Bad request." }) + } + + try { + const tweet = (await cacheGet({ + key: `tweet/${tweetId}`, + noUpdate: true, + expireTime: 60 * 60 * 24 * 3, + getValueFun: async () => await getTweet(tweetId), + })) as Tweet | undefined + return res.status(tweet ? 200 : 404).json({ data: tweet ?? null }) + } catch (error: any) { + console.error(error) + return res.status(400).json({ error: error?.message ?? "Bad request." }) + } +} diff --git a/src/components/ui/Tweet.tsx b/src/components/ui/Tweet.tsx new file mode 100644 index 00000000..e5e15d7d --- /dev/null +++ b/src/components/ui/Tweet.tsx @@ -0,0 +1,24 @@ +import dynamic from "next/dynamic" +import Image from "next/image" +import type { TwitterComponents } from "react-tweet" + +import { SITE_URL } from "~/lib/env" + +const ReactTweet = dynamic(async () => (await import("react-tweet")).Tweet) + +const components: TwitterComponents = { + AvatarImg: (props) => avatar, + MediaImg: (props) => tweet-media, +} + +export default function Tweet({ id }: { id: string }) { + return ( +
+ +
+ ) +} diff --git a/src/markdown/embed-transformers/Tweet.ts b/src/markdown/embed-transformers/Tweet.ts new file mode 100644 index 00000000..3108e21d --- /dev/null +++ b/src/markdown/embed-transformers/Tweet.ts @@ -0,0 +1,19 @@ +import { match } from "path-to-regexp" + +import type { Transformer } from "../rehype-embed" +import { isHostIncludes } from "./utils" + +export const TweetTransformer: Transformer = { + name: "Tweet", + shouldTransform(url) { + const { host, pathname } = url + + return isHostIncludes("twitter.com", host) && pathname.includes("/status/") + }, + getHTML(url) { + const { pathname } = url + const matched = match<{ id: string }>("/:user/status/:id")(pathname) + if (!matched) return + return `` + }, +} diff --git a/src/markdown/embed-transformers/index.ts b/src/markdown/embed-transformers/index.ts index f01ed95b..0816d7a8 100644 --- a/src/markdown/embed-transformers/index.ts +++ b/src/markdown/embed-transformers/index.ts @@ -4,11 +4,13 @@ import { CodeSandboxTransformer } from "./CodeSandBox" import { GitHubRepoTransformer } from "./GitHub" import { NetEaseMusicTransformer } from "./NetEaseMusic" import { SpotifyTransformer } from "./Spotify" +import { TweetTransformer } from "./Tweet" import { XLogPostTransformer } from "./XLogPost" import { YouTubeTransformer } from "./YouTube" export const transformers: Transformer[] = [ CodeSandboxTransformer, + TweetTransformer, GitHubRepoTransformer, YouTubeTransformer, XLogPostTransformer, diff --git a/src/markdown/index.ts b/src/markdown/index.ts index 8845764c..e584f7b8 100644 --- a/src/markdown/index.ts +++ b/src/markdown/index.ts @@ -56,6 +56,7 @@ import sanitizeScheme from "./sanitize-schema" const Style = dynamic(() => import("~/components/common/Style")) const Mention = dynamic(() => import("~/components/ui/Mention")) const Mermaid = dynamic(() => import("~/components/ui/Mermaid")) +const Tweet = dynamic(() => import("~/components/ui/Tweet")) const GithubRepo = dynamic(() => import("~/components/ui/GithubRepo")) const XLogPost = dynamic(() => import("~/components/ui/XLogPost")) const APlayer = dynamic(() => import("~/components/ui/APlayer")) @@ -233,6 +234,7 @@ export const renderPageContent = ( mermaid: Mermaid, audio: APlayer, video: DPlayer, + tweet: Tweet, "github-repo": GithubRepo, "xlog-post": XLogPost, style: Style,