From 37a181a6cc357fc453851579c8d3a5003bf5e0ad Mon Sep 17 00:00:00 2001 From: Benjamin Bolte Date: Fri, 16 Aug 2024 19:20:10 -0700 Subject: [PATCH] some rendering changes, debounce markdown updating --- docker/Dockerfile | 3 - .../components/listing/ListingDescription.tsx | 119 +++++++++++++----- .../src/components/listing/ListingImages.tsx | 4 +- 3 files changed, 93 insertions(+), 33 deletions(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index d1a57da9..3c03a3cc 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -20,8 +20,5 @@ RUN pip install --no-cache-dir . # Expose the port that the application runs on. EXPOSE 8080 -# Sets environment variables. -ENV ENVIRONMENT=production - # Run the FastAPI application. CMD ["fastapi", "run", "store/app/main.py", "--port", "8080"] diff --git a/frontend/src/components/listing/ListingDescription.tsx b/frontend/src/components/listing/ListingDescription.tsx index 962f20d5..94510ceb 100644 --- a/frontend/src/components/listing/ListingDescription.tsx +++ b/frontend/src/components/listing/ListingDescription.tsx @@ -1,4 +1,4 @@ -import { useState } from "react"; +import { useEffect, useState } from "react"; import { FaFile, FaPen } from "react-icons/fa"; import Markdown from "react-markdown"; @@ -15,39 +15,89 @@ interface RenderDescriptionProps { } export const RenderDescription = ({ description }: RenderDescriptionProps) => { + const [imageModal, setImageModal] = useState<[string, string] | null>(null); + return ( -

{children}

, - ul: ({ children }) => , - ol: ({ children }) =>
    {children}
, - li: ({ children }) =>
  • {children}
  • , - table: ({ children }) => ( - {children}
    - ), - thead: ({ children }) => ( - {children} - ), - tbody: ({ children }) => {children}, - tr: ({ children }) => {children}, - th: ({ children }) => ( - {children} - ), - td: ({ children }) => ( - {children} - ), - }} - > - {description} -
    + <> +

    {children}

    , + ul: ({ children }) => , + ol: ({ children }) => ( +
      {children}
    + ), + li: ({ children }) =>
  • {children}
  • , + table: ({ children }) => ( + {children}
    + ), + thead: ({ children }) => ( + {children} + ), + tbody: ({ children }) => {children}, + tr: ({ children }) => {children}, + th: ({ children }) => ( + {children} + ), + td: ({ children }) => ( + {children} + ), + a: ({ children, href }) => ( + + {children} + + ), + h1: ({ children }) =>

    {children}

    , + h2: ({ children }) =>

    {children}

    , + h3: ({ children }) => ( +

    {children}

    + ), + h4: ({ children }) => ( +

    {children}

    + ), + img: ({ src, alt }) => ( +
    src && setImageModal([src, alt ?? ""])} + > + {alt} + {alt &&

    {alt}

    } +
    + ), + }} + > + {description} +
    + + {imageModal !== null && ( +
    setImageModal(null)} + > +
    e.stopPropagation()} + > + {imageModal[1]} +
    +
    + )} + ); }; interface Props { listingId: string; description: string | null; - // TODO: If can edit, allow the user to update the description. edit: boolean; } @@ -63,6 +113,19 @@ const ListingDescription = (props: Props) => { ); const [hasChanged, setHasChanged] = useState(false); const [submitting, setSubmitting] = useState(false); + const [debouncedDescription, setDebouncedDescription] = useState( + initialDescription ?? "", + ); + + useEffect(() => { + const handler = setTimeout(() => { + setDebouncedDescription(newDescription); + }, 300); + + return () => { + clearTimeout(handler); + }; + }, [newDescription]); const handleSave = async () => { if (!hasChanged) { @@ -109,7 +172,7 @@ const ListingDescription = (props: Props) => { className="border-b border-gray-300 dark:border-gray-700 mb-2" /> )} - + {edit && (