File size: 4,172 Bytes
18e5e63 cfbfdc3 18e5e63 ee5bd94 18e5e63 cfbfdc3 49a7080 18e5e63 d6eda94 18e5e63 d6eda94 18e5e63 d6eda94 18e5e63 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
"use client"
import { useEffect, useState, useTransition } from "react"
import { Post } from "@/types"
import { cn } from "@/lib/utils"
import { actionman } from "@/lib/fonts"
import { useSearchParams } from "next/navigation"
import { Button } from "@/components/ui/button"
import { Delete } from "./delete"
import Link from "next/link"
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip"
import { getLatestPosts } from "@/app/server/actions/community"
const defaultLimit = 200
export default function FirehosePage() {
const searchParams = useSearchParams()
const [_isPending, startTransition] = useTransition()
const [posts, setPosts] = useState<Post[]>([])
const moderationKey = searchParams ? ((searchParams.get("moderationKey") as string) || "") : ""
const limit = searchParams ? (Number((searchParams.get("limit") as string) || defaultLimit)) : defaultLimit
const [toDelete, setToDelete] = useState<Post>()
useEffect(() => {
startTransition(async () => {
const newPosts = await getLatestPosts({
maxNbPosts: isNaN(limit) || !isFinite(limit) ? defaultLimit : limit,
shuffle: false,
})
setPosts(newPosts)
})
}, [])
const handleOnDelete = ({ postId }: Post) => {
setPosts(posts.filter(post => post.postId !== postId))
setToDelete(undefined)
}
return (
<TooltipProvider delayDuration={100}>
<div className={cn(
`light fixed w-full h-full flex flex-col items-center bg-slate-300 text-slate-800`,
``,
actionman.className
)}>
<div className="w-full flex flex-col items-center overflow-y-scroll">
<div className="flex flex-col space-y-2 pt-18 mb-6">
<h1 className="text-4xl md:text-6xl lg:text-[70px] xl:text-[100px] text-cyan-700">AI Clip Factory</h1>
</div>
<div className="w-full grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 gap-x-4 gap-y-6 px-12">
{posts.map(post => (
<Link
key={post.postId}
href={`/?postId=${post.postId}`}
target="_blank">
<div
key={post.postId}
className="group flex flex-col cursor-pointer"
>
<div className="w-full h-32">
<video
muted
autoPlay={false}
loop
src={post.assetUrl}
className={cn(
`w-full h-32 rounded-xl overflow-hidden object-cover`,
`border border-zinc-900/70`,
// `group-hover:brightness-105`
)}
/>
</div>
<Tooltip>
<TooltipTrigger asChild>
<div
className="text-base text-stone-900/80 truncate w-full group-hover:underline underline-offset-2"
>{post.prompt}</div>
</TooltipTrigger>
<TooltipContent>
<p className="w-full max-w-xl">{post.prompt}</p>
</TooltipContent>
</Tooltip>
<div
className="text-sm text-stone-700/70 w-full group-hover:underline underline-offset-2"
>{new Date(Date.parse(post.createdAt)).toLocaleString()}</div>
{moderationKey ? <div className="">
<Button
className="z-40 bg-red-200 text-red-700 hover:bg-red-300 hover:text-red-800 text-2xs px-2 h-7"
onClick={(e) => {
e.preventDefault()
setToDelete(post)
return false
}}>Delete</Button>
</div> : null}
</div>
</Link>
))}
</div>
</div>
<Delete post={toDelete} moderationKey={moderationKey} onDelete={handleOnDelete} />
</div>
</TooltipProvider>
)
} |