{comment.authorName}
{formatBangkok(comment.createdAt)} น.
{comment.body}
import Image from "next/image"; import Link from "next/link"; import { notFound } from "next/navigation"; import { asc, count, desc, eq } from "drizzle-orm"; import { getServerSession } from "next-auth"; import { db } from "@/db"; import { shareComments, shareTexts } from "@/db/schema"; import { CommentComposer, CopyShareActions, DeleteCommentButton, DeleteShareButton, } from "@/app/share/[id]/client"; import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "@/components/ui/card"; import { Pagination, PaginationContent, PaginationItem, PaginationNext, PaginationPrevious, } from "@/components/ui/pagination"; import { Separator } from "@/components/ui/separator"; import { authOptions } from "@/lib/auth/auth-options"; import { getAdminDiscordIds, getSessionDiscordId } from "@/lib/auth/auth"; import { cdnUrl } from "@/lib/cdn-images"; import { getDiscordMemberProfile } from "@/lib/discord/discord"; export const dynamic = "force-dynamic"; const COMMENTS_PER_PAGE = 50; function formatBangkok(date: Date) { return new Intl.DateTimeFormat("th-TH", { dateStyle: "medium", timeStyle: "short", timeZone: "Asia/Bangkok", }).format(date); } function initials(name: string) { return name.trim().slice(0, 2).toUpperCase() || "?"; } function commentsHref(id: string, sort: "oldest" | "newest", page: number) { const params = new URLSearchParams(); if (sort === "newest") params.set("comments", "newest"); if (page > 1) params.set("page", String(page)); const query = params.toString(); return `/share/${id}${query ? `?${query}` : ""}#comments`; } export default async function SharedTextPage({ params, searchParams, }: { params: Promise<{ id: string }>; searchParams: Promise<{ comments?: string | string[]; page?: string | string[]; }>; }) { const [{ id }, query, session] = await Promise.all([ params, searchParams, getServerSession(authOptions), ]); if (!/^[a-z0-9]{8}$/.test(id)) notFound(); const [share] = await db .select() .from(shareTexts) .where(eq(shareTexts.id, id)) .limit(1); if (!share) notFound(); const authorProfile = await getDiscordMemberProfile( share.authorDiscordId, ); const authorAvatarUrl = authorProfile?.avatarUrl || share.authorAvatarUrl; const requestedSort = Array.isArray(query.comments) ? query.comments[0] : query.comments; const sort = requestedSort === "newest" ? "newest" : "oldest"; const requestedPage = Number( Array.isArray(query.page) ? query.page[0] : query.page ); const [{ total }] = await db .select({ total: count() }) .from(shareComments) .where(eq(shareComments.shareId, id)); const totalPages = Math.max(1, Math.ceil(total / COMMENTS_PER_PAGE)); const page = Math.min( totalPages, Number.isInteger(requestedPage) && requestedPage > 0 ? requestedPage : 1 ); const direction = sort === "newest" ? desc : asc; const comments = await db .select() .from(shareComments) .where(eq(shareComments.shareId, id)) .orderBy(direction(shareComments.createdAt), direction(shareComments.id)) .limit(COMMENTS_PER_PAGE) .offset((page - 1) * COMMENTS_PER_PAGE); const discordId = getSessionDiscordId(session); const isAdmin = Boolean( discordId && getAdminDiscordIds().includes(discordId) ); const canDeleteShare = Boolean( discordId && (isAdmin || discordId === share.authorDiscordId) ); return (
{share.description}
)} {share.imageCdnId && ({share.content}
ยังไม่มีความคิดเห็น เริ่มบทสนทนาได้เลย
) : ({comment.authorName}
{formatBangkok(comment.createdAt)} น.
{comment.body}