From 0a71f38cd2753266f9dbd310442b65dadf440cae Mon Sep 17 00:00:00 2001 From: Aroy-Art Date: Wed, 26 Mar 2025 18:20:28 +0100 Subject: [PATCH] Add: wip post detail component --- .../src/components/partials/PostDetail.tsx | 308 ++++++++++++++++++ 1 file changed, 308 insertions(+) create mode 100644 frontend/src/components/partials/PostDetail.tsx diff --git a/frontend/src/components/partials/PostDetail.tsx b/frontend/src/components/partials/PostDetail.tsx new file mode 100644 index 0000000..407fea3 --- /dev/null +++ b/frontend/src/components/partials/PostDetail.tsx @@ -0,0 +1,308 @@ +import { useState, useRef, useEffect } from "react"; +import { Helmet } from "react-helmet-async"; +import { useNavigate } from "react-router-dom"; +import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; +import { Button } from "@/components/ui/button"; +import { ArrowLeft, ChevronDown, ChevronUp, Download } from "lucide-react"; +import { relativeTime, getFirstGrapheme } from "@/lib/utils"; +import { getFileUrl } from "@/services/api"; +import { Document, Page, pdfjs } from "react-pdf"; +import "react-pdf/dist/esm/Page/AnnotationLayer.css"; +import "react-pdf/dist/esm/Page/TextLayer.css"; + +// Import the worker as an asset with Vite +import workerSrc from "pdfjs-dist/build/pdf.worker.min.mjs?url"; +pdfjs.GlobalWorkerOptions.workerSrc = workerSrc; + +// For CMaps (if needed) +const cMapsUrl = "pdfjs-dist/cmaps/"; + +interface PostDetailProps { + post: { + post_id: string; + mature: boolean; + title: { + [key: string]: string; + }; + description: { + [key: string]: string; + }; + creator: { + [key: string]: string; + }; + source_site: { + name: string; + }; + date: { + [key: string]: string; + }; + tags: string[]; + media: Array<{ + type: string; + mimetype: string; + hash: string; + }>; + }; +} + +// Media Renderer component to render different media types +const MediaRenderer = ({ item, index, alt }) => { + const [numPages, setNumPages] = useState(null); + const [pageNumber, setPageNumber] = useState(1); + const [pdfError, setPdfError] = useState(false); + const containerRef = useRef(null); + const [width, setWidth] = useState(null); + + // Update container width when it changes + const updateWidth = () => { + if (containerRef.current) { + setWidth(containerRef.current.clientWidth); + } + }; + + // Setup resize listener + useEffect(() => { + updateWidth(); // Initial width + window.addEventListener('resize', updateWidth); + return () => window.removeEventListener('resize', updateWidth); + }, []); + + // Event handlers for react-pdf + const onDocumentLoadSuccess = ({ numPages }) => { + setNumPages(numPages); + updateWidth(); // Update width after document loads + }; + + const onDocumentLoadError = (error) => { + console.error("Error loading PDF:", error); + setPdfError(true); + }; + + const changePage = (offset) => { + const newPage = pageNumber + offset; + if (newPage >= 1 && newPage <= numPages) { + setPageNumber(newPage); + } + }; + + switch (item.type) { + case "image": + return ( + {alt} + ); + case "video": + return ( +