chore: format frontend code
This commit is contained in:
@ -1,18 +1,18 @@
|
||||
"use client";
|
||||
"use client"
|
||||
|
||||
import Image from "next/image";
|
||||
import { getIconForFile } from "vscode-icons-js";
|
||||
import { TFile, TTab } from "@/lib/types";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import {
|
||||
ContextMenu,
|
||||
ContextMenuContent,
|
||||
ContextMenuItem,
|
||||
ContextMenuTrigger,
|
||||
} from "@/components/ui/context-menu";
|
||||
import { Loader2, Pencil, Trash2 } from "lucide-react";
|
||||
} from "@/components/ui/context-menu"
|
||||
import { TFile, TTab } from "@/lib/types"
|
||||
import { Loader2, Pencil, Trash2 } from "lucide-react"
|
||||
import Image from "next/image"
|
||||
import { useEffect, useRef, useState } from "react"
|
||||
import { getIconForFile } from "vscode-icons-js"
|
||||
|
||||
import { draggable } from "@atlaskit/pragmatic-drag-and-drop/element/adapter";
|
||||
import { draggable } from "@atlaskit/pragmatic-drag-and-drop/element/adapter"
|
||||
|
||||
export default function SidebarFile({
|
||||
data,
|
||||
@ -22,36 +22,36 @@ export default function SidebarFile({
|
||||
movingId,
|
||||
deletingFolderId,
|
||||
}: {
|
||||
data: TFile;
|
||||
selectFile: (file: TTab) => void;
|
||||
data: TFile
|
||||
selectFile: (file: TTab) => void
|
||||
handleRename: (
|
||||
id: string,
|
||||
newName: string,
|
||||
oldName: string,
|
||||
type: "file" | "folder"
|
||||
) => boolean;
|
||||
handleDeleteFile: (file: TFile) => void;
|
||||
movingId: string;
|
||||
deletingFolderId: string;
|
||||
) => boolean
|
||||
handleDeleteFile: (file: TFile) => void
|
||||
movingId: string
|
||||
deletingFolderId: string
|
||||
}) {
|
||||
const isMoving = movingId === data.id;
|
||||
const isMoving = movingId === data.id
|
||||
const isDeleting =
|
||||
deletingFolderId.length > 0 && data.id.startsWith(deletingFolderId);
|
||||
deletingFolderId.length > 0 && data.id.startsWith(deletingFolderId)
|
||||
|
||||
const ref = useRef(null); // for draggable
|
||||
const [dragging, setDragging] = useState(false);
|
||||
const ref = useRef(null) // for draggable
|
||||
const [dragging, setDragging] = useState(false)
|
||||
|
||||
const inputRef = useRef<HTMLInputElement>(null);
|
||||
const [imgSrc, setImgSrc] = useState(`/icons/${getIconForFile(data.name)}`);
|
||||
const [editing, setEditing] = useState(false);
|
||||
const [pendingDelete, setPendingDelete] = useState(isDeleting);
|
||||
const inputRef = useRef<HTMLInputElement>(null)
|
||||
const [imgSrc, setImgSrc] = useState(`/icons/${getIconForFile(data.name)}`)
|
||||
const [editing, setEditing] = useState(false)
|
||||
const [pendingDelete, setPendingDelete] = useState(isDeleting)
|
||||
|
||||
useEffect(() => {
|
||||
setPendingDelete(isDeleting);
|
||||
}, [isDeleting]);
|
||||
setPendingDelete(isDeleting)
|
||||
}, [isDeleting])
|
||||
|
||||
useEffect(() => {
|
||||
const el = ref.current;
|
||||
const el = ref.current
|
||||
|
||||
if (el)
|
||||
return draggable({
|
||||
@ -59,14 +59,14 @@ export default function SidebarFile({
|
||||
onDragStart: () => setDragging(true),
|
||||
onDrop: () => setDragging(false),
|
||||
getInitialData: () => ({ id: data.id }),
|
||||
});
|
||||
}, []);
|
||||
})
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
if (editing) {
|
||||
setTimeout(() => inputRef.current?.focus(), 0);
|
||||
setTimeout(() => inputRef.current?.focus(), 0)
|
||||
}
|
||||
}, [editing, inputRef.current]);
|
||||
}, [editing, inputRef.current])
|
||||
|
||||
const renameFile = () => {
|
||||
const renamed = handleRename(
|
||||
@ -74,12 +74,12 @@ export default function SidebarFile({
|
||||
inputRef.current?.value ?? data.name,
|
||||
data.name,
|
||||
"file"
|
||||
);
|
||||
)
|
||||
if (!renamed && inputRef.current) {
|
||||
inputRef.current.value = data.name;
|
||||
inputRef.current.value = data.name
|
||||
}
|
||||
setEditing(false);
|
||||
};
|
||||
setEditing(false)
|
||||
}
|
||||
|
||||
return (
|
||||
<ContextMenu>
|
||||
@ -88,7 +88,7 @@ export default function SidebarFile({
|
||||
disabled={pendingDelete || dragging || isMoving}
|
||||
onClick={() => {
|
||||
if (!editing && !pendingDelete && !isMoving)
|
||||
selectFile({ ...data, saved: true });
|
||||
selectFile({ ...data, saved: true })
|
||||
}}
|
||||
onDoubleClick={() => {
|
||||
setEditing(true)
|
||||
@ -119,8 +119,8 @@ export default function SidebarFile({
|
||||
) : (
|
||||
<form
|
||||
onSubmit={(e) => {
|
||||
e.preventDefault();
|
||||
renameFile();
|
||||
e.preventDefault()
|
||||
renameFile()
|
||||
}}
|
||||
>
|
||||
<input
|
||||
@ -138,8 +138,8 @@ export default function SidebarFile({
|
||||
<ContextMenuContent>
|
||||
<ContextMenuItem
|
||||
onClick={() => {
|
||||
console.log("rename");
|
||||
setEditing(true);
|
||||
console.log("rename")
|
||||
setEditing(true)
|
||||
}}
|
||||
>
|
||||
<Pencil className="w-4 h-4 mr-2" />
|
||||
@ -148,9 +148,9 @@ export default function SidebarFile({
|
||||
<ContextMenuItem
|
||||
disabled={pendingDelete}
|
||||
onClick={() => {
|
||||
console.log("delete");
|
||||
setPendingDelete(true);
|
||||
handleDeleteFile(data);
|
||||
console.log("delete")
|
||||
setPendingDelete(true)
|
||||
handleDeleteFile(data)
|
||||
}}
|
||||
>
|
||||
<Trash2 className="w-4 h-4 mr-2" />
|
||||
@ -158,5 +158,5 @@ export default function SidebarFile({
|
||||
</ContextMenuItem>
|
||||
</ContextMenuContent>
|
||||
</ContextMenu>
|
||||
);
|
||||
)
|
||||
}
|
||||
|
@ -1,20 +1,20 @@
|
||||
"use client"
|
||||
|
||||
import Image from "next/image"
|
||||
import { useEffect, useRef, useState } from "react"
|
||||
import { getIconForFolder, getIconForOpenFolder } from "vscode-icons-js"
|
||||
import { TFile, TFolder, TTab } from "@/lib/types"
|
||||
import SidebarFile from "./file"
|
||||
import {
|
||||
ContextMenu,
|
||||
ContextMenuContent,
|
||||
ContextMenuItem,
|
||||
ContextMenuTrigger,
|
||||
} from "@/components/ui/context-menu"
|
||||
import { ChevronRight, Loader2, Pencil, Trash2 } from "lucide-react"
|
||||
import { dropTargetForElements } from "@atlaskit/pragmatic-drag-and-drop/element/adapter"
|
||||
import { TFile, TFolder, TTab } from "@/lib/types"
|
||||
import { cn } from "@/lib/utils"
|
||||
import { motion, AnimatePresence } from "framer-motion"
|
||||
import { dropTargetForElements } from "@atlaskit/pragmatic-drag-and-drop/element/adapter"
|
||||
import { AnimatePresence, motion } from "framer-motion"
|
||||
import { ChevronRight, Pencil, Trash2 } from "lucide-react"
|
||||
import Image from "next/image"
|
||||
import { useEffect, useRef, useState } from "react"
|
||||
import { getIconForFolder, getIconForOpenFolder } from "vscode-icons-js"
|
||||
import SidebarFile from "./file"
|
||||
|
||||
// Note: Renaming has not been implemented in the backend yet, so UI relating to renaming is commented out
|
||||
|
||||
|
@ -1,25 +1,25 @@
|
||||
"use client";
|
||||
"use client"
|
||||
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { Sandbox, TFile, TFolder, TTab } from "@/lib/types"
|
||||
import {
|
||||
FilePlus,
|
||||
FolderPlus,
|
||||
Loader2,
|
||||
Sparkles,
|
||||
MessageSquareMore,
|
||||
} from "lucide-react";
|
||||
import SidebarFile from "./file";
|
||||
import SidebarFolder from "./folder";
|
||||
import { Sandbox, TFile, TFolder, TTab } from "@/lib/types";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import New from "./new";
|
||||
import { Socket } from "socket.io-client";
|
||||
import { Button } from "@/components/ui/button";
|
||||
Sparkles,
|
||||
} from "lucide-react"
|
||||
import { useEffect, useRef, useState } from "react"
|
||||
import { Socket } from "socket.io-client"
|
||||
import SidebarFile from "./file"
|
||||
import SidebarFolder from "./folder"
|
||||
import New from "./new"
|
||||
|
||||
import {
|
||||
dropTargetForElements,
|
||||
monitorForElements,
|
||||
} from "@atlaskit/pragmatic-drag-and-drop/element/adapter";
|
||||
|
||||
} from "@atlaskit/pragmatic-drag-and-drop/element/adapter"
|
||||
|
||||
export default function Sidebar({
|
||||
sandboxData,
|
||||
files,
|
||||
@ -32,75 +32,73 @@ export default function Sidebar({
|
||||
addNew,
|
||||
deletingFolderId,
|
||||
}: {
|
||||
sandboxData: Sandbox;
|
||||
files: (TFile | TFolder)[];
|
||||
selectFile: (tab: TTab) => void;
|
||||
sandboxData: Sandbox
|
||||
files: (TFile | TFolder)[]
|
||||
selectFile: (tab: TTab) => void
|
||||
handleRename: (
|
||||
id: string,
|
||||
newName: string,
|
||||
oldName: string,
|
||||
type: "file" | "folder"
|
||||
) => boolean;
|
||||
handleDeleteFile: (file: TFile) => void;
|
||||
handleDeleteFolder: (folder: TFolder) => void;
|
||||
socket: Socket;
|
||||
setFiles: (files: (TFile | TFolder)[]) => void;
|
||||
addNew: (name: string, type: "file" | "folder") => void;
|
||||
deletingFolderId: string;
|
||||
) => boolean
|
||||
handleDeleteFile: (file: TFile) => void
|
||||
handleDeleteFolder: (folder: TFolder) => void
|
||||
socket: Socket
|
||||
setFiles: (files: (TFile | TFolder)[]) => void
|
||||
addNew: (name: string, type: "file" | "folder") => void
|
||||
deletingFolderId: string
|
||||
}) {
|
||||
const ref = useRef(null); // drop target
|
||||
const ref = useRef(null) // drop target
|
||||
|
||||
const [creatingNew, setCreatingNew] = useState<"file" | "folder" | null>(
|
||||
null
|
||||
);
|
||||
const [movingId, setMovingId] = useState("");
|
||||
const [creatingNew, setCreatingNew] = useState<"file" | "folder" | null>(null)
|
||||
const [movingId, setMovingId] = useState("")
|
||||
|
||||
useEffect(() => {
|
||||
const el = ref.current;
|
||||
const el = ref.current
|
||||
|
||||
if (el) {
|
||||
return dropTargetForElements({
|
||||
element: el,
|
||||
getData: () => ({ id: `projects/${sandboxData.id}` }),
|
||||
canDrop: ({ source }) => {
|
||||
const file = files.find((child) => child.id === source.data.id);
|
||||
return !file;
|
||||
const file = files.find((child) => child.id === source.data.id)
|
||||
return !file
|
||||
},
|
||||
});
|
||||
})
|
||||
}
|
||||
}, [files]);
|
||||
}, [files])
|
||||
|
||||
useEffect(() => {
|
||||
return monitorForElements({
|
||||
onDrop({ source, location }) {
|
||||
const destination = location.current.dropTargets[0];
|
||||
const destination = location.current.dropTargets[0]
|
||||
if (!destination) {
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
const fileId = source.data.id as string;
|
||||
const folderId = destination.data.id as string;
|
||||
const fileId = source.data.id as string
|
||||
const folderId = destination.data.id as string
|
||||
|
||||
const fileFolder = fileId.split("/").slice(0, -1).join("/");
|
||||
const fileFolder = fileId.split("/").slice(0, -1).join("/")
|
||||
if (fileFolder === folderId) {
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
console.log("move file", fileId, "to folder", folderId);
|
||||
console.log("move file", fileId, "to folder", folderId)
|
||||
|
||||
setMovingId(fileId);
|
||||
setMovingId(fileId)
|
||||
socket.emit(
|
||||
"moveFile",
|
||||
fileId,
|
||||
folderId,
|
||||
(response: (TFolder | TFile)[]) => {
|
||||
setFiles(response);
|
||||
setMovingId("");
|
||||
setFiles(response)
|
||||
setMovingId("")
|
||||
}
|
||||
);
|
||||
)
|
||||
},
|
||||
});
|
||||
}, []);
|
||||
})
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div className="h-full w-56 select-none flex flex-col text-sm">
|
||||
@ -170,7 +168,7 @@ export default function Sidebar({
|
||||
socket={socket}
|
||||
type={creatingNew}
|
||||
stopEditing={() => {
|
||||
setCreatingNew(null);
|
||||
setCreatingNew(null)
|
||||
}}
|
||||
addNew={addNew}
|
||||
/>
|
||||
@ -180,7 +178,13 @@ export default function Sidebar({
|
||||
</div>
|
||||
</div>
|
||||
<div className="fixed bottom-0 w-48 flex flex-col p-2 bg-background">
|
||||
<Button variant="ghost" className="w-full justify-start text-sm text-muted-foreground font-normal h-8 px-2 mb-2" disabled aria-disabled="true" style={{ opacity: 1}}>
|
||||
<Button
|
||||
variant="ghost"
|
||||
className="w-full justify-start text-sm text-muted-foreground font-normal h-8 px-2 mb-2"
|
||||
disabled
|
||||
aria-disabled="true"
|
||||
style={{ opacity: 1 }}
|
||||
>
|
||||
<Sparkles className="h-4 w-4 mr-2 text-indigo-500 opacity-70" />
|
||||
Copilot
|
||||
<div className="ml-auto">
|
||||
@ -189,16 +193,22 @@ export default function Sidebar({
|
||||
</kbd>
|
||||
</div>
|
||||
</Button>
|
||||
<Button variant="ghost" className="w-full justify-start text-sm text-muted-foreground font-normal h-8 px-2 mb-2" disabled aria-disabled="true" style={{ opacity: 1 }}>
|
||||
<Button
|
||||
variant="ghost"
|
||||
className="w-full justify-start text-sm text-muted-foreground font-normal h-8 px-2 mb-2"
|
||||
disabled
|
||||
aria-disabled="true"
|
||||
style={{ opacity: 1 }}
|
||||
>
|
||||
<MessageSquareMore className="h-4 w-4 mr-2 text-indigo-500 opacity-70" />
|
||||
AI Chat
|
||||
AI Chat
|
||||
<div className="ml-auto">
|
||||
<kbd className="pointer-events-none inline-flex h-5 select-none items-center gap-1 rounded border bg-muted px-1.5 font-mono text-[10px] font-medium text-muted-foreground">
|
||||
<span className="text-xs">⌘</span>L
|
||||
</kbd>
|
||||
</kbd>
|
||||
</div>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
)
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
"use client";
|
||||
"use client"
|
||||
|
||||
import { validateName } from "@/lib/utils";
|
||||
import Image from "next/image";
|
||||
import { useEffect, useRef } from "react";
|
||||
import { Socket } from "socket.io-client";
|
||||
import { validateName } from "@/lib/utils"
|
||||
import Image from "next/image"
|
||||
import { useEffect, useRef } from "react"
|
||||
import { Socket } from "socket.io-client"
|
||||
|
||||
export default function New({
|
||||
socket,
|
||||
@ -11,18 +11,18 @@ export default function New({
|
||||
stopEditing,
|
||||
addNew,
|
||||
}: {
|
||||
socket: Socket;
|
||||
type: "file" | "folder";
|
||||
stopEditing: () => void;
|
||||
addNew: (name: string, type: "file" | "folder") => void;
|
||||
socket: Socket
|
||||
type: "file" | "folder"
|
||||
stopEditing: () => void
|
||||
addNew: (name: string, type: "file" | "folder") => void
|
||||
}) {
|
||||
const inputRef = useRef<HTMLInputElement>(null);
|
||||
const inputRef = useRef<HTMLInputElement>(null)
|
||||
|
||||
function createNew() {
|
||||
const name = inputRef.current?.value;
|
||||
const name = inputRef.current?.value
|
||||
|
||||
if (name) {
|
||||
const valid = validateName(name, "", type);
|
||||
const valid = validateName(name, "", type)
|
||||
if (valid.status) {
|
||||
if (type === "file") {
|
||||
socket.emit(
|
||||
@ -30,23 +30,23 @@ export default function New({
|
||||
name,
|
||||
({ success }: { success: boolean }) => {
|
||||
if (success) {
|
||||
addNew(name, type);
|
||||
addNew(name, type)
|
||||
}
|
||||
}
|
||||
);
|
||||
)
|
||||
} else {
|
||||
socket.emit("createFolder", name, () => {
|
||||
addNew(name, type);
|
||||
});
|
||||
addNew(name, type)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
stopEditing();
|
||||
stopEditing()
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
inputRef.current?.focus();
|
||||
}, []);
|
||||
inputRef.current?.focus()
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div className="w-full flex items-center h-7 px-1 hover:bg-secondary rounded-sm cursor-pointer transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring">
|
||||
@ -63,8 +63,8 @@ export default function New({
|
||||
/>
|
||||
<form
|
||||
onSubmit={(e) => {
|
||||
e.preventDefault();
|
||||
createNew();
|
||||
e.preventDefault()
|
||||
createNew()
|
||||
}}
|
||||
>
|
||||
<input
|
||||
@ -74,5 +74,5 @@ export default function New({
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
)
|
||||
}
|
||||
|
Reference in New Issue
Block a user