file switching logic

This commit is contained in:
Ishaan Dey 2024-04-27 00:20:17 -04:00
parent b348f1d519
commit 39696128db
4 changed files with 61 additions and 31 deletions

View File

@ -36,7 +36,6 @@ const handshakeSchema = zod_1.z.object({
}); });
io.use((socket, next) => __awaiter(void 0, void 0, void 0, function* () { io.use((socket, next) => __awaiter(void 0, void 0, void 0, function* () {
const q = socket.handshake.query; const q = socket.handshake.query;
console.log("middleware");
const parseQuery = handshakeSchema.safeParse(q); const parseQuery = handshakeSchema.safeParse(q);
if (!parseQuery.success) { if (!parseQuery.success) {
console.log("Invalid request."); console.log("Invalid request.");
@ -46,7 +45,6 @@ io.use((socket, next) => __awaiter(void 0, void 0, void 0, function* () {
const { sandboxId, userId } = parseQuery.data; const { sandboxId, userId } = parseQuery.data;
const dbUser = yield fetch(`http://localhost:8787/api/user?id=${userId}`); const dbUser = yield fetch(`http://localhost:8787/api/user?id=${userId}`);
const dbUserJSON = (yield dbUser.json()); const dbUserJSON = (yield dbUser.json());
console.log("dbUserJSON:", dbUserJSON);
if (!dbUserJSON) { if (!dbUserJSON) {
console.log("DB error."); console.log("DB error.");
next(new Error("DB error.")); next(new Error("DB error."));
@ -68,6 +66,13 @@ io.on("connection", (socket) => __awaiter(void 0, void 0, void 0, function* () {
const data = socket.data; const data = socket.data;
const sandboxFiles = yield (0, getSandboxFiles_1.default)(data.id); const sandboxFiles = yield (0, getSandboxFiles_1.default)(data.id);
socket.emit("loaded", sandboxFiles.files); socket.emit("loaded", sandboxFiles.files);
socket.on("getFile", (fileId, callback) => {
const file = sandboxFiles.fileData.find((f) => f.id === fileId);
if (!file)
return;
// console.log("file " + file.id + ": ", file.data)
callback(file.data);
});
})); }));
httpServer.listen(port, () => { httpServer.listen(port, () => {
console.log(`Server running on port ${port}`); console.log(`Server running on port ${port}`);

View File

@ -28,9 +28,6 @@ const handshakeSchema = z.object({
io.use(async (socket, next) => { io.use(async (socket, next) => {
const q = socket.handshake.query const q = socket.handshake.query
console.log("middleware")
const parseQuery = handshakeSchema.safeParse(q) const parseQuery = handshakeSchema.safeParse(q)
if (!parseQuery.success) { if (!parseQuery.success) {
@ -40,12 +37,9 @@ io.use(async (socket, next) => {
} }
const { sandboxId, userId } = parseQuery.data const { sandboxId, userId } = parseQuery.data
const dbUser = await fetch(`http://localhost:8787/api/user?id=${userId}`) const dbUser = await fetch(`http://localhost:8787/api/user?id=${userId}`)
const dbUserJSON = (await dbUser.json()) as User const dbUserJSON = (await dbUser.json()) as User
console.log("dbUserJSON:", dbUserJSON)
if (!dbUserJSON) { if (!dbUserJSON) {
console.log("DB error.") console.log("DB error.")
next(new Error("DB error.")) next(new Error("DB error."))
@ -77,6 +71,13 @@ io.on("connection", async (socket) => {
const sandboxFiles = await getSandboxFiles(data.id) const sandboxFiles = await getSandboxFiles(data.id)
socket.emit("loaded", sandboxFiles.files) socket.emit("loaded", sandboxFiles.files)
socket.on("getFile", (fileId: string, callback) => {
const file = sandboxFiles.fileData.find((f) => f.id === fileId)
if (!file) return
// console.log("file " + file.id + ": ", file.data)
callback(file.data)
})
}) })
httpServer.listen(port, () => { httpServer.listen(port, () => {

View File

@ -19,9 +19,10 @@ import {
import Tab from "../ui/tab" import Tab from "../ui/tab"
import Sidebar from "./sidebar" import Sidebar from "./sidebar"
import { useClerk } from "@clerk/nextjs" import { useClerk } from "@clerk/nextjs"
import { TFile, TFolder } from "./sidebar/types" import { TFile, TFileData, TFolder } from "./sidebar/types"
import { io } from "socket.io-client" import { io } from "socket.io-client"
import { set } from "zod"
export default function CodeEditor({ export default function CodeEditor({
userId, userId,
@ -30,13 +31,17 @@ export default function CodeEditor({
userId: string userId: string
sandboxId: string sandboxId: string
}) { }) {
// const editorRef = useRef<null | monaco.editor.IStandaloneCodeEditor>(null) const editorRef = useRef<monaco.editor.IStandaloneCodeEditor | null>(null)
// const handleEditorMount: OnMount = (editor, monaco) => { const handleEditorMount: OnMount = (editor, monaco) => {
// editorRef.current = editor editorRef.current = editor
// } }
const [files, setFiles] = useState<(TFolder | TFile)[]>([]) const [files, setFiles] = useState<(TFolder | TFile)[]>([])
const [editorLanguage, setEditorLanguage] = useState("plaintext")
const [activeFile, setActiveFile] = useState<string | null>(null)
const [tabs, setTabs] = useState<TFile[]>([])
const [activeId, setActiveId] = useState<string | null>(null)
const socket = io( const socket = io(
`http://localhost:4000?userId=${userId}&sandboxId=${sandboxId}` `http://localhost:4000?userId=${userId}&sandboxId=${sandboxId}`
@ -44,6 +49,7 @@ export default function CodeEditor({
// connection/disconnection effect // connection/disconnection effect
useEffect(() => { useEffect(() => {
console.log("connecting")
socket.connect() socket.connect()
return () => { return () => {
@ -54,22 +60,26 @@ export default function CodeEditor({
// event listener effect // event listener effect
useEffect(() => { useEffect(() => {
function onLoadedEvent(files: (TFolder | TFile)[]) { function onLoadedEvent(files: (TFolder | TFile)[]) {
console.log("onLoadedEvent")
setFiles(files) setFiles(files)
} }
function onFileEvent() {
console.log("onFileEvent")
// setActiveFile(file)
}
socket.on("loaded", onLoadedEvent) socket.on("loaded", onLoadedEvent)
socket.on("file", onFileEvent)
return () => { return () => {
socket.off("loaded", onLoadedEvent) socket.off("loaded", onLoadedEvent)
socket.off("file", onFileEvent)
} }
}, []) }, [])
// use the dependency array!
const clerk = useClerk() const clerk = useClerk()
const [tabs, setTabs] = useState<TFile[]>([])
const [activeId, setActiveId] = useState<string | null>(null)
const selectFile = (tab: TFile) => { const selectFile = (tab: TFile) => {
setTabs((prev) => { setTabs((prev) => {
const exists = prev.find((t) => t.id === tab.id) const exists = prev.find((t) => t.id === tab.id)
@ -79,24 +89,28 @@ export default function CodeEditor({
} }
return [...prev, tab] return [...prev, tab]
}) })
socket.emit("getFile", tab.id, (response: string) => {
setActiveFile(response)
})
setEditorLanguage(tab.name.split(".").pop() ?? "plaintext")
setActiveId(tab.id) setActiveId(tab.id)
} }
const closeTab = (tab: TFile) => { const closeTab = (tab: TFile) => {
const numTabs = tabs.length const numTabs = tabs.length
const index = tabs.findIndex((t) => t.id === tab.id) const index = tabs.findIndex((t) => t.id === tab.id)
setActiveId((prev) => { const nextId =
const next = activeId === tab.id
prev === tab.id ? numTabs === 1
? numTabs === 1 ? null
? null : index < numTabs - 1
: index < numTabs - 1 ? tabs[index + 1].id
? tabs[index + 1].id : tabs[index - 1].id
: tabs[index - 1].id : activeId
: prev const nextTab = tabs.find((t) => t.id === nextId)
return next if (nextTab) selectFile(nextTab)
}) else setActiveId(null)
setTabs((prev) => prev.filter((t) => t.id !== tab.id)) setTabs((prev) => prev.filter((t) => t.id !== tab.id))
} }
@ -115,7 +129,9 @@ export default function CodeEditor({
<Tab <Tab
key={tab.id} key={tab.id}
selected={activeId === tab.id} selected={activeId === tab.id}
onClick={() => setActiveId(tab.id)} onClick={() => {
selectFile(tab)
}}
onClose={() => closeTab(tab)} onClose={() => closeTab(tab)}
> >
{tab.name} {tab.name}
@ -132,8 +148,9 @@ export default function CodeEditor({
) : clerk.loaded ? ( ) : clerk.loaded ? (
<Editor <Editor
height="100%" height="100%"
defaultLanguage="typescript" // defaultLanguage="typescript"
// onMount={handleEditorMount} language={editorLanguage}
onMount={handleEditorMount}
options={{ options={{
minimap: { minimap: {
enabled: false, enabled: false,
@ -143,8 +160,10 @@ export default function CodeEditor({
top: 4, top: 4,
}, },
scrollBeyondLastLine: false, scrollBeyondLastLine: false,
fixedOverflowWidgets: true,
}} }}
theme="vs-dark" theme="vs-dark"
value={activeFile ?? ""}
/> />
) : null} ) : null}
</div> </div>

View File

@ -10,3 +10,8 @@ export type TFile = {
type: "file" type: "file"
name: string name: string
} }
export type TFileData = {
id: string
data: string
}