import React from "npm:react"; import DOMPurify from "npm:dompurify"; // thanks to gemini 2.5 for this slop. // Helper function to format Unix timestamp (seconds) function formatTimestamp(unixTimestamp) { if (!unixTimestamp) return "Invalid Date"; try { const date = new Date(unixTimestamp * 1000); // Simple format, adjust as needed (e.g., locale, relative time) return date.toLocaleString(); // Example: "4/10/2025, 10:01:10 PM" } catch (e) { console.error("Error formatting timestamp:", unixTimestamp, e); return "Invalid Date"; } } // Helper function to format file size function formatFileSize(bytes) { if (bytes === null || typeof bytes !== "number" || isNaN(bytes) || bytes < 0) return ""; if (bytes === 0) return "0 Bytes"; const k = 1024; const sizes = ["Bytes", "KB", "MB", "GB", "TB"]; const i = Math.floor(Math.log(bytes) / Math.log(k)); return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i]; } function FormatComment({ text }) { if (!text) { return null; } let p = DOMPurify.sanitize(text); return ; } // --- The Main Post Component --- export function Post({ postData }) { // Destructure with default values for safety const { post_num, thread_num, thread_title = null, // Only present if it's the OP row from the join is_op = 0, timestamp = null, name = "Anonymous", trip = null, capcode = null, comment = "", media_filename = null, media_w = null, media_h = null, media_size = null, media_hash = null, // MD5 hash media_link = null, // Direct link (may need construction) thumb_link = null, // Thumbnail link (may need construction) media_spoiler = 0, // Treat as boolean/int } = postData || {}; // Handle case where postData might be null/undefined if (!post_num) { return
Error: Invalid post data provided.
; } const isOp = !!is_op; // Convert 0/1 to boolean const postClass = `post ${isOp ? "op" : "reply"}`; const postId = `p${post_num}`; const postInfoId = `pi${post_num}`; const messageId = `m${post_num}`; const fileId = `f${post_num}`; const hasMedia = !!media_filename; // Construct media links if they are null but filename/hash exists (example for 4cdn) // Adjust logic based on how links were stored or need to be generated const effectiveMediaLink = media_link || (hasMedia ? `https://i.4cdn.org/vg/${media_filename}` : null); // Example construction const effectiveThumbLink = thumb_link || (hasMedia ? `https://i.4cdn.org/vg/${media_filename.replace(/(\.\w+)$/, "s$1")}` : null); // Example construction for 's' thumbnail return (
{/* Post Info Bar */}
{name} {trip && {trip}} {capcode && capcode !== "N" && ( ## {capcode} )}{" "} {formatTimestamp(timestamp)} {/* Display formatted date/time */} No. {post_num}
{/* File/Media Section */} {hasMedia && (
File:{" "} {media_filename} {" ("} {formatFileSize(media_size)} {media_w && media_h && `, ${media_w}x${media_h}`} {")"}
{/* Basic spoiler handling: maybe blur or hide image based on state */} {formatFileSize(media_size)}
)} {/* Post Message/Comment */}
); }