From 7354d462d0d926722edeec6cba810e6160f3ce26 Mon Sep 17 00:00:00 2001 From: dotslashf <38921923+dotslashf@users.noreply.github.com> Date: Thu, 3 Oct 2024 01:17:27 +0700 Subject: [PATCH 1/2] feat: wip custom tweet component --- bun.lockb | Bin 293060 -> 318774 bytes package.json | 1 + src/app/_components/CreateCopyPastaPage.tsx | 29 ++++- src/app/_components/TweetPage.tsx | 37 ++++++ src/app/api/tweet/[id]/route.tsx | 24 ++++ .../Collection/CardCollectionDescription.tsx | 2 +- src/components/CopyPasta/CardById.tsx | 2 +- src/components/CopyPasta/CardMinimal.tsx | 2 +- src/components/EmptyState.tsx | 2 +- src/components/NavbarDropDown.tsx | 2 +- src/components/Tweet/CustomTweet.tsx | 106 ++++++++++++++++++ src/components/Tweet/QuotedTweet.tsx | 70 ++++++++++++ src/components/Tweet/SkeletonTweet.tsx | 29 +++++ src/components/UserProfileCard.tsx | 2 +- src/components/ui/avatar-image.tsx | 26 +++++ src/components/ui/avatar.tsx | 70 ++++++++---- src/lib/utils.ts | 9 ++ 17 files changed, 378 insertions(+), 35 deletions(-) create mode 100644 src/app/_components/TweetPage.tsx create mode 100644 src/app/api/tweet/[id]/route.tsx create mode 100644 src/components/Tweet/CustomTweet.tsx create mode 100644 src/components/Tweet/QuotedTweet.tsx create mode 100644 src/components/Tweet/SkeletonTweet.tsx create mode 100644 src/components/ui/avatar-image.tsx diff --git a/bun.lockb b/bun.lockb index eb93b50d0ab9ad3af1f6e98afdc4ee0d18eaaf2d..a8575b4ed5378871e5acc1a924ccf9d3506b9b17 100755 GIT binary patch delta 74446 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 diff --git a/package.json b/package.json index 6ea8447..f96ec8a 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,7 @@ "@next/third-parties": "^14.2.5", "@prisma/client": "^5.14.0", "@radix-ui/react-accordion": "^1.2.0", + "@radix-ui/react-avatar": "^1.1.1", "@radix-ui/react-checkbox": "^1.1.1", "@radix-ui/react-dialog": "^1.1.1", "@radix-ui/react-dropdown-menu": "^2.1.1", diff --git a/src/app/_components/CreateCopyPastaPage.tsx b/src/app/_components/CreateCopyPastaPage.tsx index 006aa43..b493564 100644 --- a/src/app/_components/CreateCopyPastaPage.tsx +++ b/src/app/_components/CreateCopyPastaPage.tsx @@ -35,7 +35,7 @@ import { createCopyPastaFormClient } from "../../server/form/copyPasta"; import { type z } from "zod"; import useToast from "~/components/ui/use-react-hot-toast"; import { usePathname, useRouter } from "next/navigation"; -import { useEffect, useState } from "react"; +import { Suspense, useEffect, useState } from "react"; import MultipleSelector, { type Option, } from "~/components/ui/multiple-selector"; @@ -45,11 +45,13 @@ import { id } from "date-fns/locale"; import { DAYS, parseErrorMessages } from "~/lib/constant"; import BreadCrumbs from "~/components/BreadCrumbs"; import Link from "next/link"; -import { Tweet } from "react-tweet"; +import { enrichTweet, Tweet, TweetSkeleton } from "react-tweet"; import { type Tweet as TweetInterface } from "react-tweet/api"; import { parseISO } from "date-fns"; import { useToBlob } from "@hugocxl/react-to-image"; import he from "he"; +import TweetPage from "./TweetPage"; +import EmptyState from "~/components/EmptyState"; export default function CreateCopyPasta() { const [tags] = api.tag.list.useSuspenseQuery(undefined, { @@ -208,9 +210,18 @@ export default function CreateCopyPasta() { try { const response = await fetch(url, {}); const { data } = (await response.json()) as { data: TweetInterface }; + const tweet = enrichTweet(data); - form.setValue("content", he.decode(data.text)); - form.setValue("postedAt", parseISO(data.created_at)); + void toast({ + type: "success", + message: tweet.entities.map((e) => e.text).join(" "), + }); + + form.setValue( + "content", + he.decode(tweet.entities.map((e) => e.text).join(" ")), + ); + form.setValue("postedAt", parseISO(tweet.created_at)); } catch (error) { console.error("Error fetching tweet data:", error); } @@ -422,13 +433,19 @@ export default function CreateCopyPasta() { /> )} - {fetchedTweetId && ( + Tweet akan muncul dibawah 👇 + {fetchedTweetId ? (
- +
+ ) : ( + )}
diff --git a/src/app/_components/TweetPage.tsx b/src/app/_components/TweetPage.tsx new file mode 100644 index 0000000..3086b33 --- /dev/null +++ b/src/app/_components/TweetPage.tsx @@ -0,0 +1,37 @@ +import React, { useState, useEffect } from "react"; +import { TweetNotFound } from "react-tweet"; +import { type Tweet } from "react-tweet/api"; +import CustomTweet from "~/components/Tweet/CustomTweet"; +import SkeletonTweet from "~/components/Tweet/SkeletonTweet"; + +export default function TweetPage({ id }: { id: string }) { + const [tweet, setTweet] = useState(null); + const [error, setError] = useState(null); + const [isLoading, setIsLoading] = useState(false); + + useEffect(() => { + const fetchTweet = async () => { + try { + setIsLoading(true); + const response = await fetch(`/api/tweet/${id}`); + if (!response.ok) { + throw new Error("Failed to fetch tweet"); + } + const { tweet }: { tweet: Tweet } = await response.json(); + setTweet(tweet); + } catch (err) { + console.error(err); + setError(err instanceof Error ? err : new Error("An error occurred")); + } finally { + setIsLoading(false); + } + }; + + void fetchTweet(); + }, [id]); + + if (error) return ; + if (!tweet || isLoading) return ; + + return ; +} diff --git a/src/app/api/tweet/[id]/route.tsx b/src/app/api/tweet/[id]/route.tsx new file mode 100644 index 0000000..c1a07b3 --- /dev/null +++ b/src/app/api/tweet/[id]/route.tsx @@ -0,0 +1,24 @@ +import { unstable_cache } from "next/cache"; +import { NextResponse, type NextRequest } from "next/server"; +import { getTweet as _getTweet } from "react-tweet/api"; + +const getTweet = unstable_cache( + async (id: string) => _getTweet(id), + ["tweet"], + { revalidate: 3600 * 24 }, +); + +export async function GET( + _: NextRequest, + { params }: { params: { id: string } }, +) { + try { + const tweet = await getTweet(params.id); + return NextResponse.json({ + tweet, + }); + } catch (error) { + console.error(error); + return NextResponse.json({ error: "Failed to fetch tweet" }); + } +} diff --git a/src/components/Collection/CardCollectionDescription.tsx b/src/components/Collection/CardCollectionDescription.tsx index 2256321..b932ecc 100644 --- a/src/components/Collection/CardCollectionDescription.tsx +++ b/src/components/Collection/CardCollectionDescription.tsx @@ -1,6 +1,6 @@ import { CalendarDays, Check, ChevronRight, Pencil, Trash } from "lucide-react"; import { formatDateToHuman, cn } from "~/lib/utils"; -import Avatar from "../ui/avatar"; +import Avatar from "../ui/avatar-image"; import { Badge, badgeVariants } from "../ui/badge"; import { Card, diff --git a/src/components/CopyPasta/CardById.tsx b/src/components/CopyPasta/CardById.tsx index 9ef61ce..6074e3d 100644 --- a/src/components/CopyPasta/CardById.tsx +++ b/src/components/CopyPasta/CardById.tsx @@ -35,7 +35,7 @@ import { type CardProps } from "~/lib/interface"; import { Badge, badgeVariants } from "../ui/badge"; import { api } from "~/trpc/react"; import { trackEvent } from "~/lib/track"; -import Avatar from "../ui/avatar"; +import Avatar from "../ui/avatar-image"; import { useState } from "react"; import DialogImage from "./DialogImage"; diff --git a/src/components/CopyPasta/CardMinimal.tsx b/src/components/CopyPasta/CardMinimal.tsx index 30384aa..bbb2b6e 100644 --- a/src/components/CopyPasta/CardMinimal.tsx +++ b/src/components/CopyPasta/CardMinimal.tsx @@ -22,7 +22,7 @@ import { type Tag as TagType } from "@prisma/client"; import Tag from "../ui/tags"; import useToast from "../ui/use-react-hot-toast"; import { trackEvent } from "~/lib/track"; -import Avatar from "../ui/avatar"; +import Avatar from "../ui/avatar-image"; import { badgeVariants } from "../ui/badge"; import { useState } from "react"; import DialogImage from "./DialogImage"; diff --git a/src/components/EmptyState.tsx b/src/components/EmptyState.tsx index c887ad6..788f955 100644 --- a/src/components/EmptyState.tsx +++ b/src/components/EmptyState.tsx @@ -14,7 +14,7 @@ export default function EmptyState({
{message} diff --git a/src/components/NavbarDropDown.tsx b/src/components/NavbarDropDown.tsx index d040929..d591375 100644 --- a/src/components/NavbarDropDown.tsx +++ b/src/components/NavbarDropDown.tsx @@ -29,7 +29,7 @@ import { useMediaQuery } from "@uidotdev/usehooks"; import { trackEvent } from "~/lib/track"; import { ANALYTICS_EVENT } from "~/lib/constant"; import { type Session } from "next-auth"; -import Avatar from "./ui/avatar"; +import Avatar from "./ui/avatar-image"; import { signOut } from "next-auth/react"; interface NavbarDropDownProps { diff --git a/src/components/Tweet/CustomTweet.tsx b/src/components/Tweet/CustomTweet.tsx new file mode 100644 index 0000000..00d3c52 --- /dev/null +++ b/src/components/Tweet/CustomTweet.tsx @@ -0,0 +1,106 @@ +import { enrichTweet, formatNumber, TweetBody, TweetMedia } from "react-tweet"; +import { Card, CardContent, CardFooter, CardHeader } from "../ui/card"; +import { type Tweet } from "react-tweet/api"; +import { Heart, Link2, MessageCircle } from "lucide-react"; +import Link from "next/link"; +import { AvatarImage, AvatarFallback, Avatar } from "../ui/avatar"; +import { parseISO } from "date-fns"; +import { formatDateToHuman, cn } from "~/lib/utils"; +import { buttonVariants } from "../ui/button"; +import QuotedTweet from "./QuotedTweet"; + +type CustomTweetProps = { + tweet: Tweet; +}; +export default function CustomTweet({ tweet: t }: CustomTweetProps) { + const tweet = enrichTweet(t); + return ( + + {tweet.parent && ( + +
+ + Replying to + + @{tweet.parent.user.screen_name} + +
+

{tweet.parent.text}

+
+ )} + + + + {tweet.user.name.charAt(0)} + +
+
+ {tweet.user.name} + {(tweet.user.verified || tweet.user.is_blue_verified) && ( + + + + )} +
+
@{tweet.user.screen_name}
+
+
+ + {/* */} + {/* */} + {tweet.entities.map((e) => e.text).join(" ")} + {tweet.mediaDetails?.length ? : null} + {t.quoted_tweet && ( + + + + )} + + +
+ + + {formatNumber(tweet.conversation_count)} + + + + {formatNumber(tweet.favorite_count)} + + + + Cek Tweet + +
+
+ {formatDateToHuman(parseISO(tweet.created_at), "hh:mm PPP")} +
+
+
+ ); +} diff --git a/src/components/Tweet/QuotedTweet.tsx b/src/components/Tweet/QuotedTweet.tsx new file mode 100644 index 0000000..d571b79 --- /dev/null +++ b/src/components/Tweet/QuotedTweet.tsx @@ -0,0 +1,70 @@ +import { enrichTweet, formatNumber, TweetBody, TweetMedia } from "react-tweet"; +import { Card, CardContent, CardFooter, CardHeader } from "../ui/card"; +import { type QuotedTweet } from "react-tweet/api"; +import { Heart, Link2, MessageCircle, Repeat2 } from "lucide-react"; +import Link from "next/link"; +import { AvatarImage, AvatarFallback, Avatar } from "../ui/avatar"; +import { parseISO } from "date-fns"; +import { formatDateToHuman, cn } from "~/lib/utils"; +import { buttonVariants } from "../ui/button"; + +type CustomTweetProps = { + tweet: QuotedTweet; +}; +export default function QuotedTweet({ tweet: t }: CustomTweetProps) { + const tweet = enrichTweet({ + __typename: "Tweet", + conversation_count: 0, + news_action_type: "conversation", + ...t, + }); + return ( + + + + + {tweet.user.name.charAt(0)} + +
+
+ {tweet.user.name} + {(tweet.user.verified || tweet.user.is_blue_verified) && ( + + + + )} +
+
@{tweet.user.screen_name}
+
+
+ + + {tweet.mediaDetails?.length ? : null} + + +
+ + + {formatNumber(t.reply_count)} + + + + {formatNumber(t.retweet_count)} + + + + {formatNumber(t.favorite_count)} + +
+
{formatDateToHuman(parseISO(tweet.created_at), "hh:mm PPP")}
+
+
+ ); +} diff --git a/src/components/Tweet/SkeletonTweet.tsx b/src/components/Tweet/SkeletonTweet.tsx new file mode 100644 index 0000000..1c28df3 --- /dev/null +++ b/src/components/Tweet/SkeletonTweet.tsx @@ -0,0 +1,29 @@ +import { + Card, + CardContent, + CardFooter, + CardHeader, +} from "~/components/ui/card"; +import { Skeleton } from "~/components/ui/skeleton"; +import { Button } from "~/components/ui/button"; +import { MessageCircle, Repeat2, Heart, Share } from "lucide-react"; + +export default function SkeletonTweet() { + return ( + + + +
+ + +
+
+ + + + + + +
+ ); +} diff --git a/src/components/UserProfileCard.tsx b/src/components/UserProfileCard.tsx index aa07590..d2d780f 100644 --- a/src/components/UserProfileCard.tsx +++ b/src/components/UserProfileCard.tsx @@ -17,7 +17,7 @@ import ReactionSummaryProfile from "./ReactionSummaryProfile"; import { v4 as uuidv4 } from "uuid"; import { editProfile } from "~/server/form/user"; import { Label } from "./ui/label"; -import Avatar from "./ui/avatar"; +import Avatar from "./ui/avatar-image"; import Tag from "./ui/tags"; import { type Tag as TagType } from "@prisma/client"; import { useRouter } from "next/navigation"; diff --git a/src/components/ui/avatar-image.tsx b/src/components/ui/avatar-image.tsx new file mode 100644 index 0000000..f1d5115 --- /dev/null +++ b/src/components/ui/avatar-image.tsx @@ -0,0 +1,26 @@ +import useAvatar from "~/hooks/useAvatar"; +import { v4 as uuidv4 } from "uuid"; +import Image from "next/image"; + +interface AvatarProps { + seed?: string; + zoom?: number; + size?: { + width: number; + height: number; + }; +} + +export default function Avatar({ seed, zoom, size }: AvatarProps) { + const avatarSeed = seed ?? uuidv4(); + const avatar = useAvatar(avatarSeed, zoom ?? 100); + + return ( + Avatar + ); +} diff --git a/src/components/ui/avatar.tsx b/src/components/ui/avatar.tsx index f1d5115..05e961c 100644 --- a/src/components/ui/avatar.tsx +++ b/src/components/ui/avatar.tsx @@ -1,26 +1,50 @@ -import useAvatar from "~/hooks/useAvatar"; -import { v4 as uuidv4 } from "uuid"; -import Image from "next/image"; +"use client" -interface AvatarProps { - seed?: string; - zoom?: number; - size?: { - width: number; - height: number; - }; -} +import * as React from "react" +import * as AvatarPrimitive from "@radix-ui/react-avatar" -export default function Avatar({ seed, zoom, size }: AvatarProps) { - const avatarSeed = seed ?? uuidv4(); - const avatar = useAvatar(avatarSeed, zoom ?? 100); +import { cn } from "~/lib/utils" - return ( - Avatar - ); -} +const Avatar = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +Avatar.displayName = AvatarPrimitive.Root.displayName + +const AvatarImage = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +AvatarImage.displayName = AvatarPrimitive.Image.displayName + +const AvatarFallback = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName + +export { Avatar, AvatarImage, AvatarFallback } diff --git a/src/lib/utils.ts b/src/lib/utils.ts index 69e4888..6f7e883 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -256,3 +256,12 @@ export function parseEngagementLogs(log: EngagementActionDataDb) { action: `link`, }; } + +export function formatNumber(number: number) { + return Intl.NumberFormat("en-US", { + style: "decimal", + useGrouping: true, + notation: "compact", + compactDisplay: "short", + }).format(number); +} From 71461f79e81883cccdaa038bed5227e03483df5d Mon Sep 17 00:00:00 2001 From: dotslashf <38921923+dotslashf@users.noreply.github.com> Date: Thu, 3 Oct 2024 21:54:34 +0700 Subject: [PATCH 2/2] feat: custom tweet component --- src/app/_components/CreateCopyPastaPage.tsx | 62 +++++++++++---------- src/app/_components/RankingPage.tsx | 2 +- src/app/_components/TweetPage.tsx | 37 +++++++++++- src/app/api/email/preview/route.tsx | 2 +- src/app/api/tweet/[id]/route.tsx | 21 ++++++- src/components/EmptyState.tsx | 2 +- src/components/Tweet/CustomTweet.tsx | 60 ++++++++++++++------ src/components/Tweet/CustomTweetBody.tsx | 39 +++++++++++++ src/components/Tweet/QuotedTweet.tsx | 6 +- src/components/Tweet/SkeletonTweet.tsx | 9 +-- src/lib/utils.ts | 23 ++++++++ 11 files changed, 200 insertions(+), 63 deletions(-) create mode 100644 src/components/Tweet/CustomTweetBody.tsx diff --git a/src/app/_components/CreateCopyPastaPage.tsx b/src/app/_components/CreateCopyPastaPage.tsx index b493564..7bd2dea 100644 --- a/src/app/_components/CreateCopyPastaPage.tsx +++ b/src/app/_components/CreateCopyPastaPage.tsx @@ -35,7 +35,7 @@ import { createCopyPastaFormClient } from "../../server/form/copyPasta"; import { type z } from "zod"; import useToast from "~/components/ui/use-react-hot-toast"; import { usePathname, useRouter } from "next/navigation"; -import { Suspense, useEffect, useState } from "react"; +import { useEffect, useMemo, useState } from "react"; import MultipleSelector, { type Option, } from "~/components/ui/multiple-selector"; @@ -45,11 +45,7 @@ import { id } from "date-fns/locale"; import { DAYS, parseErrorMessages } from "~/lib/constant"; import BreadCrumbs from "~/components/BreadCrumbs"; import Link from "next/link"; -import { enrichTweet, Tweet, TweetSkeleton } from "react-tweet"; -import { type Tweet as TweetInterface } from "react-tweet/api"; -import { parseISO } from "date-fns"; import { useToBlob } from "@hugocxl/react-to-image"; -import he from "he"; import TweetPage from "./TweetPage"; import EmptyState from "~/components/EmptyState"; @@ -104,6 +100,19 @@ export default function CreateCopyPasta() { } }; + const shouldRunEffect = useMemo(() => modeCreate === "auto", [modeCreate]); + + useEffect(() => { + if (shouldRunEffect) { + if (Object.values(form.formState.errors).length > 0) { + form.setError("sourceUrl", { + message: "Isi tweet terlalu pendek untuk dijadikan template", + }); + } + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [form.formState.errors.content, shouldRunEffect]); + async function onSubmit(values: z.infer) { try { if ( @@ -205,26 +214,17 @@ export default function CreateCopyPasta() { const tweetId = getTweetId(form.getValues("sourceUrl") ?? ""); if (!tweetId) return null; setFetchedTweetId(tweetId); - const url = `https://react-tweet.vercel.app/api/tweet/${tweetId}`; - - try { - const response = await fetch(url, {}); - const { data } = (await response.json()) as { data: TweetInterface }; - const tweet = enrichTweet(data); - - void toast({ - type: "success", - message: tweet.entities.map((e) => e.text).join(" "), - }); + } - form.setValue( - "content", - he.decode(tweet.entities.map((e) => e.text).join(" ")), - ); - form.setValue("postedAt", parseISO(tweet.created_at)); - } catch (error) { - console.error("Error fetching tweet data:", error); - } + function handleTweetDataFetched({ + content, + postedAt, + }: { + content: string; + postedAt: Date; + }) { + form.setValue("postedAt", postedAt); + form.setValue("content", content); } // eslint-disable-next-line @typescript-eslint/no-unused-vars @@ -433,15 +433,21 @@ export default function CreateCopyPasta() { />
)} - Tweet akan muncul dibawah 👇 - {fetchedTweetId ? ( + {modeCreate === "auto" && ( + Tweet akan muncul dibawah 👇 + )} + {fetchedTweetId && (
- +
- ) : ( + )} + {modeCreate === "auto" && !fetchedTweetId && ( void; +} +export default function TweetPage({ id, onTweetLoaded }: TweetPageProps) { const [tweet, setTweet] = useState(null); const [error, setError] = useState(null); const [isLoading, setIsLoading] = useState(false); useEffect(() => { const fetchTweet = async () => { + setError(null); try { setIsLoading(true); const response = await fetch(`/api/tweet/${id}`); @@ -19,6 +34,11 @@ export default function TweetPage({ id }: { id: string }) { } const { tweet }: { tweet: Tweet } = await response.json(); setTweet(tweet); + const enrich = enrichTweet(tweet); + onTweetLoaded({ + content: sanitizeTweetEnrich(enrich), + postedAt: parseISO(tweet.created_at), + }); } catch (err) { console.error(err); setError(err instanceof Error ? err : new Error("An error occurred")); @@ -28,9 +48,20 @@ export default function TweetPage({ id }: { id: string }) { }; void fetchTweet(); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [id]); - if (error) return ; + if (error) + return ( + + Tweet tidak ditemukan + + } + /> + ); if (!tweet || isLoading) return ; return ; diff --git a/src/app/api/email/preview/route.tsx b/src/app/api/email/preview/route.tsx index b79aab0..6c4fc87 100644 --- a/src/app/api/email/preview/route.tsx +++ b/src/app/api/email/preview/route.tsx @@ -37,7 +37,7 @@ export async function GET(request: Request) { break; } - const html = render(templateComponent); + const html = await render(templateComponent); const response = new NextResponse(html); response.headers.set("Content-Type", "text/html; charset=utf-8"); return response; diff --git a/src/app/api/tweet/[id]/route.tsx b/src/app/api/tweet/[id]/route.tsx index c1a07b3..17f8b15 100644 --- a/src/app/api/tweet/[id]/route.tsx +++ b/src/app/api/tweet/[id]/route.tsx @@ -14,11 +14,30 @@ export async function GET( ) { try { const tweet = await getTweet(params.id); + if (!tweet) { + return NextResponse.json( + { error: "Failed to fetch tweet" }, + { + status: 404, + headers: { + "content-type": "application/json", + }, + }, + ); + } return NextResponse.json({ tweet, }); } catch (error) { console.error(error); - return NextResponse.json({ error: "Failed to fetch tweet" }); + return NextResponse.json( + { error: "Failed to fetch tweet" }, + { + status: 404, + headers: { + "content-type": "application/json", + }, + }, + ); } } diff --git a/src/components/EmptyState.tsx b/src/components/EmptyState.tsx index 788f955..f0adcd8 100644 --- a/src/components/EmptyState.tsx +++ b/src/components/EmptyState.tsx @@ -2,7 +2,7 @@ import { type ReactElement, type HTMLAttributes } from "react"; import { cn } from "~/lib/utils"; interface EmptyStateProps extends HTMLAttributes { - message?: string; + message?: string | ReactElement; action?: ReactElement; } export default function EmptyState({ diff --git a/src/components/Tweet/CustomTweet.tsx b/src/components/Tweet/CustomTweet.tsx index 00d3c52..c0e4a5d 100644 --- a/src/components/Tweet/CustomTweet.tsx +++ b/src/components/Tweet/CustomTweet.tsx @@ -1,13 +1,14 @@ -import { enrichTweet, formatNumber, TweetBody, TweetMedia } from "react-tweet"; +import { enrichTweet, formatNumber, TweetMedia } from "react-tweet"; import { Card, CardContent, CardFooter, CardHeader } from "../ui/card"; import { type Tweet } from "react-tweet/api"; -import { Heart, Link2, MessageCircle } from "lucide-react"; +import { Heart, Link2, MessageCircle, Repeat2 } from "lucide-react"; import Link from "next/link"; import { AvatarImage, AvatarFallback, Avatar } from "../ui/avatar"; import { parseISO } from "date-fns"; -import { formatDateToHuman, cn } from "~/lib/utils"; +import { formatDateToHuman, cn, sanitizeTweet } from "~/lib/utils"; import { buttonVariants } from "../ui/button"; import QuotedTweet from "./QuotedTweet"; +import CustomTweetBody from "./CustomTweetBody"; type CustomTweetProps = { tweet: Tweet; @@ -17,18 +18,51 @@ export default function CustomTweet({ tweet: t }: CustomTweetProps) { return ( {tweet.parent && ( - +
- Replying to - @{tweet.parent.user.screen_name} + @{tweet.parent.user.screen_name}{" "} + {(tweet.parent.user.verified || + tweet.parent.user.is_blue_verified) && ( + + + + )}
-

{tweet.parent.text}

+

+ {sanitizeTweet(tweet.parent.text)} +

+
+
+ + + {formatNumber(tweet.parent.reply_count)} + + + + {formatNumber(tweet.parent.retweet_count)} + + + + {formatNumber(tweet.parent.favorite_count)} + +
+

+ {formatDateToHuman( + parseISO(tweet.parent.created_at), + "hh:mm PPP", + )} +

+
)} @@ -56,13 +90,7 @@ export default function CustomTweet({ tweet: t }: CustomTweetProps) {
- {/* */} - {/* */} - {tweet.entities.map((e) => e.text).join(" ")} + {tweet.mediaDetails?.length ? : null} {t.quoted_tweet && ( diff --git a/src/components/Tweet/CustomTweetBody.tsx b/src/components/Tweet/CustomTweetBody.tsx new file mode 100644 index 0000000..b1b73fb --- /dev/null +++ b/src/components/Tweet/CustomTweetBody.tsx @@ -0,0 +1,39 @@ +import Link from "next/link"; +import { type EnrichedTweet } from "react-tweet"; + +interface CustomTweetBodyProps { + tweet: EnrichedTweet; +} +export default function CustomTweetBody({ tweet }: CustomTweetBodyProps) { + const results = tweet.entities.map((e, i) => { + switch (e.type) { + case "hashtag": + case "mention": + case "url": + case "symbol": + return ( + + {e.text} + + ); + case "media": + return null; + default: + return ( + + ); + } + }); + + return

{results}

; +} diff --git a/src/components/Tweet/QuotedTweet.tsx b/src/components/Tweet/QuotedTweet.tsx index d571b79..e62a0a5 100644 --- a/src/components/Tweet/QuotedTweet.tsx +++ b/src/components/Tweet/QuotedTweet.tsx @@ -1,12 +1,10 @@ import { enrichTweet, formatNumber, TweetBody, TweetMedia } from "react-tweet"; import { Card, CardContent, CardFooter, CardHeader } from "../ui/card"; import { type QuotedTweet } from "react-tweet/api"; -import { Heart, Link2, MessageCircle, Repeat2 } from "lucide-react"; -import Link from "next/link"; +import { Heart, MessageCircle, Repeat2 } from "lucide-react"; import { AvatarImage, AvatarFallback, Avatar } from "../ui/avatar"; import { parseISO } from "date-fns"; -import { formatDateToHuman, cn } from "~/lib/utils"; -import { buttonVariants } from "../ui/button"; +import { formatDateToHuman } from "~/lib/utils"; type CustomTweetProps = { tweet: QuotedTweet; diff --git a/src/components/Tweet/SkeletonTweet.tsx b/src/components/Tweet/SkeletonTweet.tsx index 1c28df3..16b4429 100644 --- a/src/components/Tweet/SkeletonTweet.tsx +++ b/src/components/Tweet/SkeletonTweet.tsx @@ -1,12 +1,5 @@ -import { - Card, - CardContent, - CardFooter, - CardHeader, -} from "~/components/ui/card"; +import { Card, CardContent, CardHeader } from "~/components/ui/card"; import { Skeleton } from "~/components/ui/skeleton"; -import { Button } from "~/components/ui/button"; -import { MessageCircle, Repeat2, Heart, Share } from "lucide-react"; export default function SkeletonTweet() { return ( diff --git a/src/lib/utils.ts b/src/lib/utils.ts index 6f7e883..7c12770 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -18,6 +18,8 @@ import { type SearchAction, } from "schema-dts"; import { baseUrl, TIMEZONE } from "./constant"; +import he from "he"; +import { type EnrichedTweet } from "react-tweet"; export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs)); @@ -43,6 +45,27 @@ export function getJakartaDateString(date: Date = new Date()): string { return formatTz(getJakartaDate(date), "yyyy-MM-dd", { timeZone: TIMEZONE }); } +export function sanitizeTweet(text: string) { + return he.decode(text); +} + +export function sanitizeTweetEnrich(tweet: EnrichedTweet) { + return tweet.entities + .map((e) => { + switch (e.type) { + case "hashtag": + case "media": + case "mention": + case "symbol": + case "url": + return; + default: + return e.text; + } + }) + .join(" "); +} + export function trimContent(content: string, length = 255) { if (!content) { return "😱😱😱";