fix: aichat and preview/terminal layout

This commit is contained in:
Akhileshrangani4 2024-10-14 13:51:17 -04:00
parent 1365fecb08
commit bfc687a3e6

View File

@ -970,7 +970,6 @@ export default function CodeEditor({
/> />
) : null} ) : null}
</div> </div>
{/* Main editor components */} {/* Main editor components */}
<Sidebar <Sidebar
sandboxData={sandboxData} sandboxData={sandboxData}
@ -984,158 +983,172 @@ export default function CodeEditor({
addNew={(name, type) => addNew(name, type, setFiles, sandboxData)} addNew={(name, type) => addNew(name, type, setFiles, sandboxData)}
deletingFolderId={deletingFolderId} deletingFolderId={deletingFolderId}
/> />
{/* Outer ResizablePanelGroup for main layout */}
{/* Shadcn resizeable panels: https://ui.shadcn.com/docs/components/resizable */} <ResizablePanelGroup direction="horizontal">
<ResizablePanelGroup direction={isHorizontalLayout ? "vertical" : "horizontal"}> {/* Left side: Editor and Preview/Terminal */}
<ResizablePanel <ResizablePanel defaultSize={isAIChatOpen ? 80 : 100} minSize={50}>
className="p-2 flex flex-col" <ResizablePanelGroup direction={isHorizontalLayout ? "vertical" : "horizontal"}>
maxSize={80} <ResizablePanel
minSize={30} className="p-2 flex flex-col"
defaultSize={isHorizontalLayout ? 70 : 60} maxSize={80}
ref={editorPanelRef} minSize={30}
> defaultSize={70}
<div className="h-10 w-full flex gap-2 overflow-auto tab-scroll"> ref={editorPanelRef}
{/* File tabs */} >
{tabs.map((tab) => ( <div className="h-10 w-full flex gap-2 overflow-auto tab-scroll">
<Tab {/* File tabs */}
key={tab.id} {tabs.map((tab) => (
saved={tab.saved} <Tab
selected={activeFileId === tab.id} key={tab.id}
onClick={(e) => { saved={tab.saved}
selectFile(tab) selected={activeFileId === tab.id}
}} onClick={(e) => {
onClose={() => closeTab(tab.id)} selectFile(tab)
>
{tab.name}
</Tab>
))}
</div>
{/* Monaco editor */}
<div
ref={editorContainerRef}
className="grow w-full overflow-hidden rounded-md relative"
>
{!activeFileId ? (
<>
<div className="w-full h-full flex items-center justify-center text-xl font-medium text-muted-foreground/50 select-none">
<FileJson className="w-6 h-6 mr-3" />
No file selected.
</div>
</>
) : // Note clerk.loaded is required here due to a bug: https://github.com/clerk/javascript/issues/1643
clerk.loaded ? (
<>
{provider && userInfo ? (
<Cursors yProvider={provider} userInfo={userInfo} />
) : null}
<Editor
height="100%"
language={editorLanguage}
beforeMount={handleEditorWillMount}
onMount={handleEditorMount}
onChange={(value) => {
// If the new content is different from the cached content, update it
if (value !== fileContents[activeFileId]) {
setActiveFileContent(value ?? ""); // Update the active file content
// Mark the file as unsaved by setting 'saved' to false
setTabs((prev) =>
prev.map((tab) =>
tab.id === activeFileId
? { ...tab, saved: false }
: tab
)
)
} else {
// If the content matches the cached content, mark the file as saved
setTabs((prev) =>
prev.map((tab) =>
tab.id === activeFileId
? { ...tab, saved: true }
: tab
)
)
}
}} }}
options={{ onClose={() => closeTab(tab.id)}
tabSize: 2, >
minimap: { {tab.name}
enabled: false, </Tab>
}, ))}
padding: { </div>
bottom: 4, {/* Monaco editor */}
top: 4, <div
}, ref={editorContainerRef}
scrollBeyondLastLine: false, className="grow w-full overflow-hidden rounded-md relative"
fixedOverflowWidgets: true,
fontFamily: "var(--font-geist-mono)",
}}
theme="vs-dark"
value={activeFileContent}
/>
</>
) : (
<div className="w-full h-full flex items-center justify-center text-xl font-medium text-muted-foreground/50 select-none">
<Loader2 className="animate-spin w-6 h-6 mr-3" />
Waiting for Clerk to load...
</div>
)}
</div>
</ResizablePanel>
<ResizableHandle />
<ResizablePanel defaultSize={isHorizontalLayout ? 30 : 30}>
{isAIChatOpen ? (
<AIChat />
) : (
<ResizablePanelGroup direction={isHorizontalLayout ? "horizontal" : "vertical"}>
<ResizablePanel
ref={previewPanelRef}
defaultSize={4}
collapsedSize={isHorizontalLayout ? 20 : 4}
minSize={25}
collapsible
className="p-2 flex flex-col"
onCollapse={() => setIsPreviewCollapsed(true)}
onExpand={() => setIsPreviewCollapsed(false)}
> >
<div className="flex items-center justify-between"> {!activeFileId ? (
<Button onClick={toggleLayout} size="sm" variant="ghost" className="mr-2 border"> <>
{isHorizontalLayout ? <ArrowRightToLine className="w-4 h-4" /> : <ArrowDownToLine className="w-4 h-4" />} <div className="w-full h-full flex items-center justify-center text-xl font-medium text-muted-foreground/50 select-none">
</Button> <FileJson className="w-6 h-6 mr-3" />
<PreviewWindow No file selected.
open={togglePreviewPanel} </div>
collapsed={isPreviewCollapsed} </>
src={previewURL} ) : // Note clerk.loaded is required here due to a bug: https://github.com/clerk/javascript/issues/1643
ref={previewWindowRef} clerk.loaded ? (
/> <>
</div> {provider && userInfo ? (
{!isPreviewCollapsed && ( <Cursors yProvider={provider} userInfo={userInfo} />
<div className="w-full grow rounded-md overflow-hidden bg-foreground mt-2"> ) : null}
<iframe <Editor
width={"100%"} height="100%"
height={"100%"} language={editorLanguage}
beforeMount={handleEditorWillMount}
onMount={handleEditorMount}
onChange={(value) => {
// If the new content is different from the cached content, update it
if (value !== fileContents[activeFileId]) {
setActiveFileContent(value ?? ""); // Update the active file content
// Mark the file as unsaved by setting 'saved' to false
setTabs((prev) =>
prev.map((tab) =>
tab.id === activeFileId
? { ...tab, saved: false }
: tab
)
)
} else {
// If the content matches the cached content, mark the file as saved
setTabs((prev) =>
prev.map((tab) =>
tab.id === activeFileId
? { ...tab, saved: true }
: tab
)
)
}
}}
options={{
tabSize: 2,
minimap: {
enabled: false,
},
padding: {
bottom: 4,
top: 4,
},
scrollBeyondLastLine: false,
fixedOverflowWidgets: true,
fontFamily: "var(--font-geist-mono)",
}}
theme="vs-dark"
value={activeFileContent}
/>
</>
) : (
<div className="w-full h-full flex items-center justify-center text-xl font-medium text-muted-foreground/50 select-none">
<Loader2 className="animate-spin w-6 h-6 mr-3" />
Waiting for Clerk to load...
</div>
)}
</div>
</ResizablePanel>
<ResizableHandle />
<ResizablePanel defaultSize={30}>
<ResizablePanelGroup direction={
isAIChatOpen && isHorizontalLayout ? "horizontal" :
isAIChatOpen ? "vertical" :
isHorizontalLayout ? "horizontal" :
"vertical"
}>
<ResizablePanel
ref={previewPanelRef}
defaultSize={isPreviewCollapsed ? 4 : 20}
minSize={25}
collapsedSize={isHorizontalLayout ? 20 : 4}
className="p-2 flex flex-col"
collapsible
onCollapse={() => setIsPreviewCollapsed(true)}
onExpand={() => setIsPreviewCollapsed(false)}
>
<div className="flex items-center justify-between">
<Button onClick={toggleLayout} size="sm" variant="ghost" className="mr-2 border">
{isHorizontalLayout ? <ArrowRightToLine className="w-4 h-4" /> : <ArrowDownToLine className="w-4 h-4" />}
</Button>
<PreviewWindow
open={togglePreviewPanel}
collapsed={isPreviewCollapsed}
src={previewURL} src={previewURL}
ref={previewWindowRef}
/> />
</div> </div>
)} {!isPreviewCollapsed && (
</ResizablePanel> <div className="w-full grow rounded-md overflow-hidden bg-foreground mt-2">
<ResizableHandle /> <iframe
<ResizablePanel width={"100%"}
defaultSize={50} height={"100%"}
minSize={20} src={previewURL}
className="p-2 flex flex-col" />
> </div>
{isOwner ? ( )}
<Terminals /> </ResizablePanel>
) : ( <ResizableHandle />
<div className="w-full h-full flex items-center justify-center text-lg font-medium text-muted-foreground/50 select-none"> <ResizablePanel
<TerminalSquare className="w-4 h-4 mr-2" /> defaultSize={50}
No terminal access. minSize={20}
</div> className="p-2 flex flex-col"
)} >
</ResizablePanel> {isOwner ? (
</ResizablePanelGroup> <Terminals />
)} ) : (
<div className="w-full h-full flex items-center justify-center text-lg font-medium text-muted-foreground/50 select-none">
<TerminalSquare className="w-4 h-4 mr-2" />
No terminal access.
</div>
)}
</ResizablePanel>
</ResizablePanelGroup>
</ResizablePanel>
</ResizablePanelGroup>
</ResizablePanel> </ResizablePanel>
{/* Right side: AIChat (if open) */}
{isAIChatOpen && (
<>
<ResizableHandle />
<ResizablePanel defaultSize={30} minSize={15}>
<AIChat />
</ResizablePanel>
</>
)}
</ResizablePanelGroup> </ResizablePanelGroup>
</PreviewProvider> </PreviewProvider>
</> </>