diff --git a/app/atom.xml/route.ts b/app/atom.xml/route.ts index 465a009..cefc868 100644 --- a/app/atom.xml/route.ts +++ b/app/atom.xml/route.ts @@ -2,7 +2,7 @@ import { db } from "@/lib/db"; const escapeXml = (value: string) => value.replace(/[<>&'\"]/g, (char) => ({ "<": "<", ">": ">", "&": "&", "'": "'", '"': """ }[char] || char)); export async function GET() { - const origin = (process.env.NEXT_PUBLIC_APP_URL || "http://localhost:8088").replace(/\/$/, ""); const posts = db.prepare("SELECT p.id,p.content,p.created_at,u.username FROM posts p JOIN users u ON u.id=p.author_id WHERE p.visibility='PUBLIC' AND p.hidden=0 ORDER BY COALESCE(p.remote_created_at,p.created_at) DESC LIMIT 50").all() as { id: number; content: string; created_at: string; username: string }[]; const updated = posts[0] ? new Date(posts[0].created_at + "Z").toISOString() : new Date().toISOString(); - const entries = posts.map((post) => `${origin}/posts/${post.id}${escapeXml(`@${post.username} 的貼文`)}${new Date(post.created_at + "Z").toISOString()}${escapeXml(post.content)}`).join(""); + const origin = (process.env.NEXT_PUBLIC_APP_URL || "http://localhost:8088").replace(/\/$/, ""); const posts = db.prepare("SELECT p.id,p.content,COALESCE(p.remote_created_at,p.created_at) AS published_at,u.username FROM posts p JOIN users u ON u.id=p.author_id WHERE p.visibility='PUBLIC' AND p.hidden=0 ORDER BY COALESCE(p.remote_created_at,p.created_at) DESC LIMIT 50").all() as { id: number; content: string; published_at: string; username: string }[]; const updated = posts[0] ? new Date(posts[0].published_at).toISOString() : new Date().toISOString(); + const entries = posts.map((post) => `${origin}/posts/${post.id}${escapeXml(`@${post.username} 的貼文`)}${new Date(post.published_at).toISOString()}${escapeXml(post.content)}`).join(""); return new Response(`Mebbling${origin}${updated}${entries}`, { headers: { "Content-Type": "application/atom+xml; charset=utf-8", "Cache-Control": "public, max-age=300" } }); } diff --git a/app/components/post-card.tsx b/app/components/post-card.tsx index f4150b8..a404be2 100644 --- a/app/components/post-card.tsx +++ b/app/components/post-card.tsx @@ -3,9 +3,9 @@ import { Attachments } from "./attachments"; import { Markdown } from "./markdown"; import { canonicalTags } from "@/lib/tags"; -export type PublicPost = { id: number; source_id: number | null; content: string; tags_json: string; attachments_json: string; created_at: string; username: string; name: string | null; source_base_url: string | null; comment_count: number; reaction_count: number }; +export type PublicPost = { id: number; source_id: number | null; content: string; tags_json: string; attachments_json: string; created_at: string; remote_created_at?: string | null; username: string; name: string | null; source_base_url: string | null; comment_count: number; reaction_count: number }; export function PostCard({ post }: { post: PublicPost }) { let tags: string[] = []; try { tags = canonicalTags(JSON.parse(post.tags_json)); } catch { /* Ignore malformed legacy tags. */ } - return
@{post.username}{post.name ? ` · ${post.name}` : ""}{new Date(post.created_at).toLocaleString("zh-TW")}
{tags.map((tag) => #{tag})}{post.source_id && 來源}閱讀全文 · 💬 {post.comment_count} 🙂 {post.reaction_count}
; + const publishedAt = post.remote_created_at || post.created_at; return
@{post.username}{post.name ? ` · ${post.name}` : ""}{new Date(publishedAt).toLocaleString("zh-TW")}
{tags.map((tag) => #{tag})}{post.source_id && 來源}閱讀全文 · 💬 {post.comment_count} 🙂 {post.reaction_count}
; } diff --git a/app/posts/[id]/page.tsx b/app/posts/[id]/page.tsx index b410d34..af40cd6 100644 --- a/app/posts/[id]/page.tsx +++ b/app/posts/[id]/page.tsx @@ -23,7 +23,7 @@ export default async function PostPage({ params, searchParams }: { params: Promi const bookmark = user ? db.prepare("SELECT kind FROM bookmarks WHERE user_id=? AND post_id=?").get(user.id, id) as { kind: string } | undefined : undefined; const comments = db.prepare("SELECT c.*,u.username FROM comments c JOIN users u ON u.id=c.author_id WHERE c.post_id=? AND c.hidden=0 ORDER BY c.created_at").all(id) as any[]; const reactions = db.prepare("SELECT emoji,count(*) count FROM reactions WHERE post_id=? GROUP BY emoji").all(id) as any[]; - let tags: string[] = []; try { tags = canonicalTags(JSON.parse(post.tags_json)); } catch {} return

@{post.username} · {post.remote_display_name || post.name || "Hub"} · {new Date(post.created_at).toLocaleString("zh-TW")}{post.remote_url && <> · 在 Memos 開啟}

+ let tags: string[] = []; try { tags = canonicalTags(JSON.parse(post.tags_json)); } catch {} const publishedAt = post.remote_created_at || post.created_at; return

@{post.username} · {post.remote_display_name || post.name || "Hub"} · {new Date(publishedAt).toLocaleString("zh-TW")}{post.remote_url && <> · 在 Memos 開啟}

{reactions.map((reaction: any) => {reaction.emoji} {reaction.count})}{user && <>
}{user && ["👍", "❤️", "🎉", "🤔"].map((emoji) =>
)}

留言

{user ? <>