feature: add terminal/preview layout button

This commit is contained in:
Akhileshrangani4 2024-10-12 19:46:32 -04:00
parent f863f2f763
commit b6569550fc
2 changed files with 39 additions and 35 deletions

View File

@ -18,7 +18,7 @@ import {
ResizablePanel, ResizablePanel,
ResizablePanelGroup, ResizablePanelGroup,
} from "@/components/ui/resizable" } from "@/components/ui/resizable"
import { FileJson, Loader2, Sparkles, TerminalSquare } from "lucide-react" import { FileJson, Loader2, Sparkles, TerminalSquare, ArrowDownToLine, ArrowRightToLine } from "lucide-react"
import Tab from "../ui/tab" import Tab from "../ui/tab"
import Sidebar from "./sidebar" import Sidebar from "./sidebar"
import GenerateInput from "./generate" import GenerateInput from "./generate"
@ -145,7 +145,7 @@ export default function CodeEditor({
const generateRef = useRef<HTMLDivElement>(null) const generateRef = useRef<HTMLDivElement>(null)
const suggestionRef = useRef<HTMLDivElement>(null) const suggestionRef = useRef<HTMLDivElement>(null)
const generateWidgetRef = useRef<HTMLDivElement>(null) const generateWidgetRef = useRef<HTMLDivElement>(null)
const { previewPanelRef } = usePreview(); const { previewPanelRef } = usePreview();
const editorPanelRef = useRef<ImperativePanelHandle>(null) const editorPanelRef = useRef<ImperativePanelHandle>(null)
const previewWindowRef = useRef<{ refreshIframe: () => void }>(null) const previewWindowRef = useRef<{ refreshIframe: () => void }>(null)
@ -416,7 +416,7 @@ export default function CodeEditor({
}) })
} }
}, [generate.show]) }, [generate.show])
// Suggestion widget effect // Suggestion widget effect
useEffect(() => { useEffect(() => {
if (!suggestionRef.current || !editorRef) return if (!suggestionRef.current || !editorRef) return
@ -686,9 +686,9 @@ export default function CodeEditor({
const selectFile = (tab: TTab) => { const selectFile = (tab: TTab) => {
if (tab.id === activeFileId) return; if (tab.id === activeFileId) return;
setGenerate((prev) => ({ ...prev, show: false })); setGenerate((prev) => ({ ...prev, show: false }));
// Check if the tab already exists in the list of open tabs // Check if the tab already exists in the list of open tabs
const exists = tabs.find((t) => t.id === tab.id); const exists = tabs.find((t) => t.id === tab.id);
setTabs((prev) => { setTabs((prev) => {
@ -700,7 +700,7 @@ export default function CodeEditor({
// If the tab doesn't exist, add it to the list of tabs and make it active // If the tab doesn't exist, add it to the list of tabs and make it active
return [...prev, tab]; return [...prev, tab];
}); });
// If the file's content is already cached, set it as the active content // If the file's content is already cached, set it as the active content
if (fileContents[tab.id]) { if (fileContents[tab.id]) {
setActiveFileContent(fileContents[tab.id]); setActiveFileContent(fileContents[tab.id]);
@ -711,7 +711,7 @@ export default function CodeEditor({
setActiveFileContent(response); setActiveFileContent(response);
}); });
} }
// Set the editor language based on the file type // Set the editor language based on the file type
setEditorLanguage(processFileType(tab.name)); setEditorLanguage(processFileType(tab.name));
// Set the active file ID to the new tab // Set the active file ID to the new tab
@ -837,6 +837,12 @@ export default function CodeEditor({
} }
}; };
const [isHorizontalLayout, setIsHorizontalLayout] = useState(false);
const toggleLayout = () => {
setIsHorizontalLayout(prev => !prev);
};
// On disabled access for shared users, show un-interactable loading placeholder + info modal // On disabled access for shared users, show un-interactable loading placeholder + info modal
if (disableAccess.isDisabled) if (disableAccess.isDisabled)
return ( return (
@ -972,12 +978,12 @@ export default function CodeEditor({
/> />
{/* Shadcn resizeable panels: https://ui.shadcn.com/docs/components/resizable */} {/* Shadcn resizeable panels: https://ui.shadcn.com/docs/components/resizable */}
<ResizablePanelGroup direction="horizontal"> <ResizablePanelGroup direction={isHorizontalLayout ? "vertical" : "horizontal"}>
<ResizablePanel <ResizablePanel
className="p-2 flex flex-col" className="p-2 flex flex-col"
maxSize={80} maxSize={80}
minSize={30} minSize={30}
defaultSize={60} defaultSize={isHorizontalLayout ? 70 : 60}
ref={editorPanelRef} ref={editorPanelRef}
> >
<div className="h-10 w-full flex gap-2 overflow-auto tab-scroll"> <div className="h-10 w-full flex gap-2 overflow-auto tab-scroll">
@ -1022,7 +1028,7 @@ export default function CodeEditor({
onChange={(value) => { onChange={(value) => {
// If the new content is different from the cached content, update it // If the new content is different from the cached content, update it
if (value !== fileContents[activeFileId]) { if (value !== fileContents[activeFileId]) {
setActiveFileContent(value ?? ""); // Update the active file content setActiveFileContent(value ?? ""); // Update the active file content
// Mark the file as unsaved by setting 'saved' to false // Mark the file as unsaved by setting 'saved' to false
setTabs((prev) => setTabs((prev) =>
prev.map((tab) => prev.map((tab) =>
@ -1068,24 +1074,38 @@ export default function CodeEditor({
</div> </div>
</ResizablePanel> </ResizablePanel>
<ResizableHandle /> <ResizableHandle />
<ResizablePanel defaultSize={40}> <ResizablePanel defaultSize={isHorizontalLayout ? 30 : 40}>
<ResizablePanelGroup direction="vertical"> <ResizablePanelGroup direction={isHorizontalLayout ? "horizontal" : "vertical"}>
<ResizablePanel <ResizablePanel
ref={previewPanelRef} ref={previewPanelRef}
defaultSize={4} defaultSize={4}
collapsedSize={4} collapsedSize={isHorizontalLayout ? 20 : 4}
minSize={25} minSize={25}
collapsible collapsible
className="p-2 flex flex-col" className="p-2 flex flex-col"
onCollapse={() => setIsPreviewCollapsed(true)} onCollapse={() => setIsPreviewCollapsed(true)}
onExpand={() => setIsPreviewCollapsed(false)} onExpand={() => setIsPreviewCollapsed(false)}
> >
<PreviewWindow <div className="flex items-center justify-between">
open={togglePreviewPanel} <Button onClick={toggleLayout} size="sm" variant="ghost" className="mr-2 border">
collapsed={isPreviewCollapsed} {isHorizontalLayout ? <ArrowRightToLine className="w-4 h-4" /> : <ArrowDownToLine className="w-4 h-4" />}
src={previewURL} </Button>
ref={previewWindowRef} <PreviewWindow
/> open={togglePreviewPanel}
collapsed={isPreviewCollapsed}
src={previewURL}
ref={previewWindowRef}
/>
</div>
{!isPreviewCollapsed && (
<div className="w-full grow rounded-md overflow-hidden bg-foreground mt-2">
<iframe
width={"100%"}
height={"100%"}
src={previewURL}
/>
</div>
)}
</ResizablePanel> </ResizablePanel>
<ResizableHandle /> <ResizableHandle />
<ResizablePanel <ResizablePanel

View File

@ -33,10 +33,6 @@ ref: React.Ref<{
return ( return (
<> <>
<div
className={`${collapsed ? "h-full" : "h-10"
} select-none w-full flex gap-2`}
>
<div className="h-8 rounded-md px-3 bg-secondary flex items-center w-full justify-between"> <div className="h-8 rounded-md px-3 bg-secondary flex items-center w-full justify-between">
<div className="text-xs">Preview</div> <div className="text-xs">Preview</div>
<div className="flex space-x-1 translate-x-1"> <div className="flex space-x-1 translate-x-1">
@ -65,18 +61,6 @@ ref: React.Ref<{
)} )}
</div> </div>
</div> </div>
</div>
{collapsed ? null : (
<div className="w-full grow rounded-md overflow-hidden bg-foreground">
<iframe
key={iframeKey}
ref={frameRef}
width={"100%"}
height={"100%"}
src={src}
/>
</div>
)}
</> </>
) )
}) })