Reload the live preview when the app is restarted.

This commit is contained in:
James Murdza 2024-08-01 10:56:39 -07:00
parent aac602d9db
commit d4c65ad1a3
3 changed files with 30 additions and 17 deletions

View File

@ -106,6 +106,13 @@ export default function CodeEditor({
// Preview state // Preview state
const [previewURL, setPreviewURL] = useState<string>(""); const [previewURL, setPreviewURL] = useState<string>("");
const loadPreviewURL = (url: string) => {
// This will cause a reload if previewURL changed.
setPreviewURL(url);
// If the URL didn't change, still reload the preview.
previewWindowRef.current?.refreshIframe();
}
const isOwner = sandboxData.userId === userData.id const isOwner = sandboxData.userId === userData.id
const clerk = useClerk() const clerk = useClerk()
@ -131,6 +138,7 @@ export default function CodeEditor({
const generateWidgetRef = useRef<HTMLDivElement>(null) const generateWidgetRef = useRef<HTMLDivElement>(null)
const previewPanelRef = useRef<ImperativePanelHandle>(null) const previewPanelRef = useRef<ImperativePanelHandle>(null)
const editorPanelRef = useRef<ImperativePanelHandle>(null) const editorPanelRef = useRef<ImperativePanelHandle>(null)
const previewWindowRef = useRef<{ refreshIframe: () => void }>(null)
// Pre-mount editor keybindings // Pre-mount editor keybindings
const handleEditorWillMount: BeforeMount = (monaco) => { const handleEditorWillMount: BeforeMount = (monaco) => {
@ -467,7 +475,7 @@ export default function CodeEditor({
socketRef.current?.on("error", onError) socketRef.current?.on("error", onError)
socketRef.current?.on("terminalResponse", onTerminalResponse) socketRef.current?.on("terminalResponse", onTerminalResponse)
socketRef.current?.on("disableAccess", onDisableAccess) socketRef.current?.on("disableAccess", onDisableAccess)
socketRef.current?.on("previewURL", setPreviewURL) socketRef.current?.on("previewURL", loadPreviewURL)
return () => { return () => {
socketRef.current?.off("connect", onConnect) socketRef.current?.off("connect", onConnect)
@ -476,7 +484,7 @@ export default function CodeEditor({
socketRef.current?.off("error", onError) socketRef.current?.off("error", onError)
socketRef.current?.off("terminalResponse", onTerminalResponse) socketRef.current?.off("terminalResponse", onTerminalResponse)
socketRef.current?.off("disableAccess", onDisableAccess) socketRef.current?.off("disableAccess", onDisableAccess)
socketRef.current?.off("previewURL", setPreviewURL) socketRef.current?.off("previewURL", loadPreviewURL)
} }
// }, []); // }, []);
}, [terminals]) }, [terminals])
@ -824,7 +832,7 @@ export default function CodeEditor({
open={() => { open={() => {
usePreview().previewPanelRef.current?.expand() usePreview().previewPanelRef.current?.expand()
setIsPreviewCollapsed(false) setIsPreviewCollapsed(false)
} } collapsed={isPreviewCollapsed} src={previewURL}/> } } collapsed={isPreviewCollapsed} src={previewURL} ref={previewWindowRef} />
</ResizablePanel> </ResizablePanel>
<ResizableHandle /> <ResizableHandle />
<ResizablePanel <ResizablePanel

View File

@ -37,6 +37,8 @@ export default function RunButtonModal({
if (terminals.length < 4) { if (terminals.length < 4) {
createNewTerminal("yarn install && yarn start"); createNewTerminal("yarn install && yarn start");
// For testing:
//createNewTerminal("echo http://localhost:3000");
} else { } else {
toast.error("You reached the maximum # of terminals."); toast.error("You reached the maximum # of terminals.");
console.error('Maximum number of terminals reached.'); console.error('Maximum number of terminals reached.');

View File

@ -5,10 +5,10 @@ import {
RotateCw, RotateCw,
TerminalSquare, TerminalSquare,
} from "lucide-react" } from "lucide-react"
import { useRef, useState } from "react" import { useEffect, useRef, useState, useImperativeHandle, forwardRef } from "react"
import { toast } from "sonner" import { toast } from "sonner"
export default function PreviewWindow({ export default forwardRef(function PreviewWindow({
collapsed, collapsed,
open, open,
src src
@ -16,9 +16,19 @@ export default function PreviewWindow({
collapsed: boolean collapsed: boolean
open: () => void open: () => void
src: string src: string
}) { },
const ref = useRef<HTMLIFrameElement>(null) ref: React.Ref<{
refreshIframe: () => void
}>) {
const frameRef = useRef<HTMLIFrameElement>(null)
const [iframeKey, setIframeKey] = useState(0) const [iframeKey, setIframeKey] = useState(0)
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 }))
return ( return (
<> <>
@ -49,14 +59,7 @@ export default function PreviewWindow({
> >
<Link className="w-4 h-4" /> <Link className="w-4 h-4" />
</PreviewButton> </PreviewButton>
<PreviewButton <PreviewButton onClick={refreshIframe}>
onClick={() => {
// if (ref.current) {
// ref.current.contentWindow?.location.reload();
// }
setIframeKey((prev) => prev + 1)
}}
>
<RotateCw className="w-3 h-3" /> <RotateCw className="w-3 h-3" />
</PreviewButton> </PreviewButton>
</> </>
@ -68,7 +71,7 @@ export default function PreviewWindow({
<div className="w-full grow rounded-md overflow-hidden bg-foreground"> <div className="w-full grow rounded-md overflow-hidden bg-foreground">
<iframe <iframe
key={iframeKey} key={iframeKey}
ref={ref} ref={frameRef}
width={"100%"} width={"100%"}
height={"100%"} height={"100%"}
src={src} src={src}
@ -77,7 +80,7 @@ export default function PreviewWindow({
)} )}
</> </>
) )
} })
function PreviewButton({ function PreviewButton({
children, children,