14 lines
1.9 KiB
TypeScript
14 lines
1.9 KiB
TypeScript
import Link from "next/link";
|
|
import { notFound } from "next/navigation";
|
|
import { db } from "@/lib/db";
|
|
import { PostCard, type PublicPost } from "@/app/components/post-card";
|
|
import { getSession } from "@/lib/auth";
|
|
|
|
export const dynamic = "force-dynamic";
|
|
export default async function SourcePage({ params }: { params: Promise<{ id: string }> }) {
|
|
const { id: rawId } = await params; const id = Number(rawId); const source = db.prepare("SELECT id,name,base_url,remote_display_name,remote_avatar_url FROM sources WHERE id=?").get(id) as { id: number; name: string; base_url: string; remote_display_name: string | null; remote_avatar_url: string | null } | undefined; if (!source) notFound();
|
|
const posts = db.prepare("SELECT p.*,u.username,s.name,s.remote_user,s.remote_display_name,s.base_url AS source_base_url,(SELECT count(*) FROM comments c WHERE c.post_id=p.id AND c.hidden=0) comment_count,(SELECT count(*) FROM reactions r WHERE r.post_id=p.id) reaction_count FROM posts p JOIN users u ON u.id=p.author_id LEFT JOIN sources s ON s.id=p.source_id WHERE p.source_id=? AND p.visibility='PUBLIC' AND p.hidden=0 ORDER BY COALESCE(p.remote_created_at,p.created_at) DESC LIMIT 100").all(id) as PublicPost[];
|
|
const user = await getSession(); const member = Boolean(user && db.prepare("SELECT 1 FROM source_members WHERE source_id=? AND user_id=?").get(id, user.id));
|
|
return <><p><Link href="/">← 探索</Link></p><h1>{source.name}</h1><p className="meta">{source.remote_avatar_url && <img className="avatar" src={source.remote_avatar_url} alt="" />} {source.remote_display_name || "Memos"}<br />{source.base_url} · {posts.length} 篇公開貼文</p>{member && <p className="row"><a href={`/api/export/sources/${id}?format=json`}>匯出來源 JSON</a><a href={`/api/export/sources/${id}?format=markdown`}>匯出來源 Markdown</a></p>}{posts.map((post) => <PostCard key={post.id} post={post} />)}</>;
|
|
}
|