Spaces:
Running
Running
File size: 4,832 Bytes
bcb0fad e29580c bcb0fad 6692511 8e92e61 bcb0fad b573489 bcb0fad b573489 bcb0fad e29580c bcb0fad e29580c 93f259b e29580c 6692511 bcb0fad e29580c 50e5742 e29580c bcb0fad de9adca ccdf544 de9adca e29580c de9adca ccdf544 a3ba9ae ccdf544 de9adca bcb0fad |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
import classNames from "classnames";
import { useRef, useState } from "react";
import { FaLaptopCode } from "react-icons/fa6";
import { FaMobileAlt } from "react-icons/fa";
import { TbReload } from "react-icons/tb";
import { toast } from "react-toastify";
import { defaultHTML } from "../../../utils/consts";
function Preview({
html,
isResizing,
isAiWorking,
setView,
ref,
}: {
html: string;
isResizing: boolean;
isAiWorking: boolean;
setView: React.Dispatch<React.SetStateAction<"editor" | "preview">>;
ref: React.RefObject<HTMLDivElement | null>;
}) {
const [device, setDevice] = useState<"desktop" | "mobile">("desktop");
const iframeRef = useRef<HTMLIFrameElement | null>(null);
const handleRefreshIframe = () => {
if (iframeRef.current) {
const iframe = iframeRef.current;
const content = iframe.srcdoc;
iframe.srcdoc = "";
setTimeout(() => {
iframe.srcdoc = content;
}, 10);
}
};
return (
<div
ref={ref}
className={classNames(
"w-full border-l border-gray-900 bg-white h-[calc(100dvh-49px)] lg:h-[calc(100dvh-53px)] relative transition-all duration-200",
{
"flex items-center justify-center": device === "mobile",
}
)}
onClick={(e) => {
if (isAiWorking) {
e.preventDefault();
e.stopPropagation();
toast.warn("Please wait for the AI to finish working.");
}
}}
>
<iframe
ref={iframeRef}
title="output"
className={classNames(
"w-full select-none transition-all duration-200",
{
"pointer-events-none": isResizing || isAiWorking,
"max-w-md mx-auto h-[80dvh] rounded-[64px] border-[8px] border-black shadow-2xl":
device === "mobile",
"h-full": device === "desktop",
}
)}
srcDoc={html}
/>
<div className="flex items-center justify-start gap-3 absolute bottom-3 lg:bottom-5 max-lg:left-3 lg:right-5">
<button
className="lg:hidden bg-gray-950 shadow-md text-white text-xs lg:text-sm font-medium py-2 px-3 lg:px-4 rounded-lg flex items-center gap-2 border border-gray-900 hover:brightness-150 transition-all duration-100 cursor-pointer"
onClick={() => setView("editor")}
>
<FaLaptopCode className="text-sm" />
Hide preview
</button>
{html === defaultHTML && (
<a
href="https://huggingface.co/spaces/victor/deepsite-gallery"
target="_blank"
className="bg-gray-200 text-gray-950 text-xs lg:text-sm font-medium py-2 px-3 lg:px-4 rounded-lg flex items-center gap-2 border border-gray-200 hover:bg-gray-300 transition-all duration-100 cursor-pointer"
>
🖼️ <span>DeepSite Gallery</span>
</a>
)}
{html !== defaultHTML && !isAiWorking && (
<div className="flex items-center rounded-lg p-1 bg-gray-200 relative overflow-hidden z-0 max-lg:hidden">
<div
className={classNames(
"absolute left-1 top-1 rounded-md bg-black w-10 h-8 -z-[1] transition-all duration-200",
{
"translate-x-full": device === "mobile",
}
)}
/>
<button
className={classNames(
"rounded-md text-gray-500 w-10 h-8 flex items-center justify-center cursor-pointer",
{
"!text-white": device === "desktop",
"hover:bg-gray-300/60": device !== "desktop",
}
)}
onClick={() => setDevice("desktop")}
>
<FaLaptopCode className="text-sm" />
</button>
<button
className={classNames(
"rounded-md text-gray-500 w-10 h-8 flex items-center justify-center cursor-pointer",
{
"!text-white": device === "mobile",
"hover:bg-gray-300/60": device !== "mobile",
}
)}
onClick={() => setDevice("mobile")}
>
<FaMobileAlt className="text-sm" />
</button>
</div>
)}
{!isAiWorking && (
<button
className="bg-white lg:bg-gray-950 shadow-md text-gray-950 lg:text-white text-xs lg:text-sm font-medium py-2 px-3 lg:px-4 rounded-lg flex items-center gap-2 border border-gray-100 lg:border-gray-900 hover:brightness-150 transition-all duration-100 cursor-pointer"
onClick={handleRefreshIframe}
>
<TbReload className="text-sm" />
Refresh Preview
</button>
)}
</div>
</div>
);
}
export default Preview;
|