import { useEffect, useLayoutEffect, useRef, useState, } from "@wordpress/element"; import { __, sprintf } from "@wordpress/i18n"; import { API_URL } from "../config"; import { importImage } from "../lib/wp"; import { useGlobalState } from "../state/global"; import type { ExternalImage, ImageLike, WpImage } from "../types"; import { Modal } from "./Modal"; import { ToolbarControls, type ToolbarControlsProps } from "./ToolbarControls"; type LoaderProps = { attributes: ImageLike; setAttributes: (attributes: ImageLike) => void; clientId?: string; CurrentMenuItems?: React.ComponentType; toolbarProps?: ToolbarControlsProps; }; export const Loader = ({ attributes, setAttributes, clientId, CurrentMenuItems, toolbarProps, }: LoaderProps) => { const [showModal, setShowModal] = useState(false); const { imageSize, importing, setImporting, setLoading } = useGlobalState(); const timerRef = useRef(0); const rafRef = useRef(0); useEffect(() => { const namespace = "kevinbatdorf/unlimited-photos-open"; const open = (event: CustomEvent<{ clientId: string }>) => { if (event?.detail?.clientId !== clientId) return; setShowModal(true); }; window.addEventListener(namespace, open as (e: Event) => void); return () => { window.removeEventListener(namespace, open as (e: Event) => void); }; }, [clientId]); // TODO: if the user has an image set, warn them we may replace it // attributes?.id const setImage = async (image: ExternalImage) => { if (importing) return; const caption = image?.user?.username && image?.user?.name ? sprintf( __("Photo by %1$s on %2$s", "unlimited-photos"), `${image.user.name}`, 'Unsplash', ) : ""; // Record download to Unsplash await fetch(`${API_URL}/api/download`, { method: "POST", headers: { "Content-Type": "multipart/form-data" }, body: image?.links?.download_location, }); // If the user cannot import large images, lower the quality const imageSizeChecked = // @ts-expect-error-next-line Number(window?.unlimitedPhotosConfig?.maxUploadSize) < 3 ? "regular" : imageSize; const url = image.urls[imageSizeChecked]; const newImage: WpImage | undefined = await importImage(url, { alt: "", filename: `up-${image.id}.jpg`, caption, }); if (!newImage) return; const getHref = (dest: string) => { if (dest === "media") return newImage?.source_url; if (dest === "attachment") return newImage?.link; return attributes?.href; }; setAttributes({ id: newImage.id, caption: newImage.caption.raw, linkDestination: attributes?.linkDestination ?? "", linkTarget: attributes?.linkTarget ?? "", linkClass: attributes?.linkClass ?? "", rel: attributes?.rel ?? "", href: getHref(attributes?.linkDestination ?? ""), url: newImage.source_url, alt: newImage.alt_text, }); setImporting(__("Done!", "unlimited-photos")); timerRef.current = window.setTimeout(() => { rafRef.current = window.requestAnimationFrame(() => { setShowModal(false); }); }, 1000); }; useLayoutEffect(() => { if (showModal) { setLoading(false); setImporting(false); } window.clearTimeout(timerRef.current); window.clearTimeout(rafRef.current); }, [showModal, setImporting, setLoading]); return ( <> setShowModal(true)} /> setShowModal(false)} /> ); };