diff --git a/src/app/page.tsx b/src/app/page.tsx index 4061a5a..b811ed2 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -3,6 +3,7 @@ import * as React from "react"; import { ClipboardImage } from "@components/ClipboardImage"; import { ActionPanel } from "@components/ActionsPanel"; +import { HistoryPanel } from "@components/HistoryPanel"; import { defaultSettings } from "@config/defaults"; import { cn } from "@utils/cn"; import { useSettings } from "@hooks/useSettings"; @@ -30,36 +31,57 @@ export default function Home() { setBackgroundColor, } = useSettings(defaultSettings); + // TODO: Move this to a custom hook + // imagesHistoryUrl = ["blob:http://localhost:3000/73c51e5e...", "..."] + // selectedImageUrl = "blob:http://localhost:3000/73c51e5e..." + const [imagesHistoryUrl, setImagesHistoryUrl] = React.useState([]); + const [selectedImageUrl, setSelectedImageUrl] = React.useState("") + return (
-
-
-
- + {/* Editing container */} +
+ {/* Clipboard image panel */} +
+
+
+ +
+ {/* Clipboard images history panel */} +
+ {/* Sidebar container */}
diff --git a/src/components/ClipboardImage.tsx b/src/components/ClipboardImage.tsx index 053698a..5464653 100644 --- a/src/components/ClipboardImage.tsx +++ b/src/components/ClipboardImage.tsx @@ -15,6 +15,10 @@ export const ClipboardImage = ({ insetPadding, setInsetColor, setInsetPadding, + setImagesHistoryUrl, + imagesHistoryUrl, + selectedImageUrl, + setSelectedImageUrl, }: { insetColor: string; scale: number, @@ -23,6 +27,10 @@ export const ClipboardImage = ({ insetPadding: number; setInsetColor: (input: string) => void; setInsetPadding: (input: number) => void; + setImagesHistoryUrl: React.Dispatch> + imagesHistoryUrl: string[] + selectedImageUrl: string + setSelectedImageUrl: React.Dispatch> }) => { const { toast } = useToast(); const imageRef = React.useRef(null); @@ -49,6 +57,15 @@ export const ClipboardImage = ({ currentImage.onclick = async () => { const result = await pasteImage(currentImage); if (result === "SUCCESS") { + // TODO: Extract this to a custom hook + // Adds the images to the shared history state, only if there are less than 10. + if (imagesHistoryUrl.length < 10) { + setImagesHistoryUrl((prevUrl) => [currentImage.src, ...prevUrl]) + // TODO: Fix redundant code, pasteImage and setSelectedImage are + // both setting the current image to be displayed + setSelectedImageUrl(currentImage.src) + } + toast({ title: ( @@ -70,7 +87,13 @@ export const ClipboardImage = ({ }); }; } - }, [toast]); + // Checks if there are selected images from the shared state + if (imageRef.current && selectedImageUrl) { + // If there are, set the "src" of the ref to the selected image + const currentImage = imageRef.current; + currentImage.src = selectedImageUrl; + } + }, [toast, setImagesHistoryUrl, selectedImageUrl, imagesHistoryUrl.length, setSelectedImageUrl]); return ( > + setImagesHistoryUrl: React.Dispatch> +}) => { + + const handleSelectFromHistory = (url: string) => { + // Updates the state with the current selected image from the panel + setSelectedImageUrl(url); + } + + const handleDeleteFromHistory = (url: string) => { + // Filter out the URL to delete the image selected from the panel + setImagesHistoryUrl((prevUrl) => { + // Length has to be subtracted by one to stay accurate + // because the last operation is going to remove one item + if ((prevUrl.length - 1) === 0) { + // If the length is zero, then no images are left. Set the default placeholder. + setSelectedImageUrl(placeholder.src); + return [] + } + + return ( + prevUrl.filter((value, index) => { + + // If we match the current image being deleted with the one being displayed + // And there are more than one images remaining in history then... + if (value === url && (prevUrl.length - 1) > 0) { + // Check if we have entries on the positive side + prevUrl[index + 1] ? ( + // If there are, change the current image to the next positive index + setSelectedImageUrl((prevUrl[index + 1])) + ) : ( + // Else, change the current image to the next negative index + setSelectedImageUrl((prevUrl[index - 1])) + ); + } + + return (value !== url) + }) + ); + }); + } + + return ( + /* History panel container */ +
+
+ {imagesHistoryUrl.length > 0 ? ( + imagesHistoryUrl.map((url, index) => { + return ( + /* History image container */ +
+ {/* History image delete button */} + + {/* History image */} + Image handleSelectFromHistory(url)} + className="rounded-lg object-cover" + /> +
+ ) + }) + ) : ( + /* No history placeholder text */ +

Clipboard images history (empty)

+ )} +
+
+ ) +} \ No newline at end of file