2024-05-26 17:28:52 -07:00
|
|
|
"use client"
|
2024-05-08 23:52:08 -07:00
|
|
|
|
|
|
|
import {
|
2024-05-13 14:38:14 -07:00
|
|
|
Link,
|
2024-05-08 23:52:08 -07:00
|
|
|
RotateCw,
|
|
|
|
TerminalSquare,
|
2024-10-12 17:55:49 -04:00
|
|
|
UnfoldVertical,
|
2024-05-26 17:28:52 -07:00
|
|
|
} from "lucide-react"
|
2024-08-01 10:56:39 -07:00
|
|
|
import { useEffect, useRef, useState, useImperativeHandle, forwardRef } from "react"
|
2024-05-26 17:28:52 -07:00
|
|
|
import { toast } from "sonner"
|
2024-05-08 23:52:08 -07:00
|
|
|
|
2024-08-01 10:56:39 -07:00
|
|
|
export default forwardRef(function PreviewWindow({
|
2024-05-09 22:16:56 -07:00
|
|
|
collapsed,
|
|
|
|
open,
|
2024-06-15 21:04:33 -04:00
|
|
|
src
|
2024-05-09 22:16:56 -07:00
|
|
|
}: {
|
2024-05-26 17:28:52 -07:00
|
|
|
collapsed: boolean
|
|
|
|
open: () => void
|
2024-06-15 21:04:33 -04:00
|
|
|
src: string
|
2024-08-01 10:56:39 -07:00
|
|
|
},
|
|
|
|
ref: React.Ref<{
|
|
|
|
refreshIframe: () => void
|
|
|
|
}>) {
|
|
|
|
const frameRef = useRef<HTMLIFrameElement>(null)
|
2024-05-26 17:28:52 -07:00
|
|
|
const [iframeKey, setIframeKey] = useState(0)
|
2024-08-01 10:56:39 -07:00
|
|
|
const refreshIframe = () => {
|
|
|
|
setIframeKey(prev => prev + 1)
|
|
|
|
}
|
|
|
|
// Refresh the preview when the URL changes.
|
|
|
|
useEffect(refreshIframe, [src])
|
|
|
|
// Expose refreshIframe method to the parent.
|
|
|
|
useImperativeHandle(ref, () => ({ refreshIframe }))
|
2024-05-13 14:38:14 -07:00
|
|
|
|
2024-05-08 23:52:08 -07:00
|
|
|
return (
|
|
|
|
<>
|
2024-05-11 19:28:37 -07:00
|
|
|
<div className="h-8 rounded-md px-3 bg-secondary flex items-center w-full justify-between">
|
2024-05-26 17:28:52 -07:00
|
|
|
<div className="text-xs">Preview</div>
|
2024-05-08 23:52:08 -07:00
|
|
|
<div className="flex space-x-1 translate-x-1">
|
2024-05-09 22:16:56 -07:00
|
|
|
{collapsed ? (
|
2024-10-12 17:55:49 -04:00
|
|
|
<PreviewButton onClick={open}>
|
|
|
|
<UnfoldVertical className="w-4 h-4" />
|
2024-05-09 22:16:56 -07:00
|
|
|
</PreviewButton>
|
|
|
|
) : (
|
|
|
|
<>
|
2024-07-23 17:30:35 -04:00
|
|
|
<PreviewButton onClick={open}>
|
|
|
|
<UnfoldVertical className="w-4 h-4" />
|
2024-10-12 17:55:49 -04:00
|
|
|
</PreviewButton>
|
2024-05-13 14:38:14 -07:00
|
|
|
|
|
|
|
<PreviewButton
|
|
|
|
onClick={() => {
|
2024-06-15 21:04:33 -04:00
|
|
|
navigator.clipboard.writeText(src)
|
2024-05-26 17:28:52 -07:00
|
|
|
toast.info("Copied preview link to clipboard")
|
2024-05-13 14:38:14 -07:00
|
|
|
}}
|
|
|
|
>
|
|
|
|
<Link className="w-4 h-4" />
|
2024-05-09 22:16:56 -07:00
|
|
|
</PreviewButton>
|
2024-08-01 10:56:39 -07:00
|
|
|
<PreviewButton onClick={refreshIframe}>
|
2024-05-09 22:16:56 -07:00
|
|
|
<RotateCw className="w-3 h-3" />
|
|
|
|
</PreviewButton>
|
|
|
|
</>
|
|
|
|
)}
|
2024-05-08 23:52:08 -07:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</>
|
2024-05-26 17:28:52 -07:00
|
|
|
)
|
2024-08-01 10:56:39 -07:00
|
|
|
})
|
2024-05-09 22:16:56 -07:00
|
|
|
|
|
|
|
function PreviewButton({
|
|
|
|
children,
|
2024-05-13 14:38:14 -07:00
|
|
|
disabled = false,
|
2024-05-09 22:16:56 -07:00
|
|
|
onClick,
|
|
|
|
}: {
|
2024-05-26 17:28:52 -07:00
|
|
|
children: React.ReactNode
|
|
|
|
disabled?: boolean
|
|
|
|
onClick: () => void
|
2024-05-09 22:16:56 -07:00
|
|
|
}) {
|
|
|
|
return (
|
|
|
|
<div
|
2024-07-23 17:30:35 -04:00
|
|
|
className={`${disabled ? "pointer-events-none opacity-50" : ""
|
|
|
|
} p-0.5 h-5 w-5 ml-0.5 flex items-center justify-center transition-colors bg-transparent hover:bg-muted-foreground/25 cursor-pointer rounded-sm`}
|
2024-05-09 22:16:56 -07:00
|
|
|
onClick={onClick}
|
|
|
|
>
|
|
|
|
{children}
|
|
|
|
</div>
|
2024-05-26 17:28:52 -07:00
|
|
|
)
|
2024-05-09 22:16:56 -07:00
|
|
|
}
|