file switching logic
This commit is contained in:
parent
b348f1d519
commit
39696128db
9
backend/server/dist/index.js
vendored
9
backend/server/dist/index.js
vendored
@ -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}`);
|
||||||
|
@ -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, () => {
|
||||||
|
@ -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>
|
||||||
|
@ -10,3 +10,8 @@ export type TFile = {
|
|||||||
type: "file"
|
type: "file"
|
||||||
name: string
|
name: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type TFileData = {
|
||||||
|
id: string
|
||||||
|
data: string
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user