Skip to content

Commit 0ecbfce

Browse files
authored
Merge pull request #75 from CS3219-AY2425S1/revert-74-main
Revert "Collab Service"
2 parents 7286534 + 4b01fb3 commit 0ecbfce

File tree

10 files changed

+72
-250
lines changed

10 files changed

+72
-250
lines changed

backend/user-service/services/tokenService.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { UnauthorisedError } from "../utils/httpErrors.js";
77
class TokenService {
88
static generateAccessToken(user) {
99
const accessToken = jwt.sign(
10-
{ id: user.id, isAdmin: user.isAdmin, username: user.username },
10+
{ id: user.id, isAdmin: user.isAdmin },
1111
jwtConfig.accessTokenSecret,
1212
jwtConfig.accessTokenOptions
1313
);
@@ -16,7 +16,7 @@ class TokenService {
1616

1717
static generateRefreshToken(user) {
1818
const refreshToken = jwt.sign(
19-
{ id: user.id, jti: uuidv4(), username: user.username },
19+
{ id: user.id, jti: uuidv4() },
2020
jwtConfig.refreshTokenSecret,
2121
jwtConfig.refreshTokenOptions
2222
);

frontend/src/domain/context/CollaborationContext.tsx

Lines changed: 43 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { createContext, useState, useContext, ReactNode, useEffect, useMemo, useCallback } from "react";
1+
import React, { createContext, useState, useContext, ReactNode, useEffect, useMemo } from "react";
22
import * as Y from "yjs";
33
import * as monaco from "monaco-editor";
44
import { MonacoBinding } from "y-monaco";
@@ -20,7 +20,6 @@ interface CollaborationContextType {
2020
execResult: CodeExecResult | null;
2121
setRoomId: (roomId: string) => void;
2222
connectedUsers: string[];
23-
disconnect: () => void;
2423
}
2524

2625
const CollaborationContext = createContext<CollaborationContextType | undefined>(undefined);
@@ -42,81 +41,86 @@ export const CollaborationProvider: React.FC<{ children: ReactNode }> = ({ child
4241
const ymap: Y.Map<any> = useMemo(() => ydoc.getMap("sharedMap"), [ydoc]);
4342

4443
const [roomId, setRoomId] = useState<string | null>(null);
44+
4545
const [languages, setLanguages] = useState<Language[]>([]);
4646
const [execResult, setExecResult] = useState<CodeExecResult | null>(null);
4747
const [isExecuting, setIsExecuting] = useState<boolean>(false);
4848
const [connectedUsers, setConnectedUsers] = useState<string[]>([]);
49+
4950
const [editor, setEditor] = useState<monaco.editor.IStandaloneCodeEditor | null>(null);
5051
const [provider, setProvider] = useState<WebsocketProvider | null>(null);
5152
const [binding, setBinding] = useState<MonacoBinding | null>(null);
5253

53-
const disconnect = useCallback(() => {
54-
binding?.destroy();
55-
provider?.destroy();
56-
ydoc?.destroy();
57-
setConnectedUsers([]);
58-
setProvider(null);
59-
setBinding(null);
60-
setRoomId(null);
61-
}, [binding, provider, ydoc]);
62-
54+
// This effect manages the lifetime of the yjs doc and the provider
6355
useEffect(() => {
64-
if (!roomId) return;
65-
66-
const newProvider = new WebsocketProvider("ws://localhost:1234", roomId, ydoc);
67-
setProvider(newProvider);
68-
69-
newProvider.awareness.setLocalStateField(USERNAME, username);
70-
newProvider.awareness.on("change", () => {
71-
const users = Array.from(newProvider.awareness.getStates().values());
72-
const uniqueUsers = new Set(users.map((user) => user[USERNAME])); // Use Set for uniqueness
73-
setConnectedUsers(Array.from(uniqueUsers)); // Convert Set back to Array
56+
if (roomId == null) {
57+
return;
58+
}
59+
const provider = new WebsocketProvider("ws://localhost:1234", roomId, ydoc);
60+
setProvider(provider);
61+
62+
provider.awareness.setLocalStateField(USERNAME, username);
63+
provider.awareness.on("change", (update: any) => {
64+
const users = Array.from(provider.awareness.getStates().values());
65+
setConnectedUsers(users.map((user) => user[USERNAME]));
66+
// TODO: Some UI feedback about connection status of the other user
7467
});
7568

7669
return () => {
77-
disconnect();
70+
provider?.destroy();
71+
ydoc?.destroy();
7872
};
79-
}, [ydoc, roomId, username, USERNAME, disconnect]);
73+
}, [ydoc, roomId]);
8074

75+
// This effect manages the lifetime of the editor binding
8176
useEffect(() => {
82-
if (!provider || !editor?.getModel()) return;
77+
if (provider == null || editor == null || editor.getModel() == null) {
78+
return;
79+
}
8380

84-
const newBinding = new MonacoBinding(
81+
const binding = new MonacoBinding(
8582
ydoc.getText("monaco"),
8683
editor.getModel()!,
8784
new Set([editor]),
88-
provider.awareness
85+
provider?.awareness
8986
);
90-
setBinding(newBinding);
87+
88+
setBinding(binding);
9189

9290
ymap.observe((event) => {
9391
event.changes.keys.forEach((change, key) => {
9492
if (key === SELECTED_LANGUAGE) {
9593
const language: Language = ymap.get(SELECTED_LANGUAGE);
9694
setSelectedLanguage(language);
97-
monaco.editor.setModelLanguage(editor.getModel()!, language.language);
95+
const model = editor.getModel();
96+
monaco.editor.setModelLanguage(model!, language.language);
9897
}
9998
});
10099
});
101100

101+
// Set the editor's language
102102
const language: Language = ymap.get(SELECTED_LANGUAGE);
103-
monaco.editor.setModelLanguage(editor.getModel()!, language?.language ?? "javascript");
103+
const model = editor.getModel();
104+
monaco.editor.setModelLanguage(model!, language?.language ?? "javascript");
104105

105-
return () => newBinding.destroy();
106-
}, [ydoc, provider, editor, ymap, SELECTED_LANGUAGE]);
106+
return () => {
107+
binding.destroy();
108+
};
109+
}, [ydoc, provider, editor, ymap]);
107110

108111
useEffect(() => {
109112
initialiseLanguages();
110113
}, []);
111114

112115
const initialiseLanguages = async () => {
116+
// Initialise language dropdown
113117
const allLanguages = monaco.languages.getLanguages();
114118
const pistonLanguageVersions = await PistonClient.getLanguageVersions();
115119
setLanguages(
116120
allLanguages
117121
.filter((lang) => pistonLanguageVersions.some((pistonLang: any) => pistonLang.language === lang.id))
118122
.map((lang) => ({
119-
alias: lang.aliases?.[0] || lang.id,
123+
alias: lang.aliases && lang.aliases.length > 0 ? lang.aliases[0] : lang.id,
120124
language: lang.id,
121125
version: pistonLanguageVersions.find((pistonLang: any) => pistonLang.language === lang.id)?.version
122126
}))
@@ -131,9 +135,11 @@ export const CollaborationProvider: React.FC<{ children: ReactNode }> = ({ child
131135
try {
132136
setIsExecuting(true);
133137
const sourceCode = editor?.getValue();
134-
if (!sourceCode) return;
135-
136-
const output = await PistonClient.executeCode(selectedLanguage, sourceCode);
138+
if (!sourceCode) {
139+
// TODO
140+
return;
141+
}
142+
const output: CodeExecResult = await PistonClient.executeCode(selectedLanguage, sourceCode);
137143
setExecResult(output);
138144
} catch (e) {
139145
toast.error("There was an issue running the code");
@@ -157,8 +163,7 @@ export const CollaborationProvider: React.FC<{ children: ReactNode }> = ({ child
157163
handleExecuteCode,
158164
isExecuting,
159165
execResult,
160-
connectedUsers,
161-
disconnect
166+
connectedUsers
162167
}}
163168
>
164169
{children}
Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,12 @@
11
.submitButton {
2-
background-color: #ffa500 !important;
3-
color: black !important;
4-
font-weight: bold !important;
2+
background-color: #ffa500;
53
}
64

75
.runButton {
8-
background-color: #1a1a1a !important;
9-
color: white !important;
10-
}
11-
12-
.runButton:hover {
13-
background-color: #333 !important;
14-
}
15-
16-
.submitButton:hover {
17-
background-color: #ffb52e !important;
6+
background-color: black;
7+
color: white;
188
}
199

2010
button {
2111
width: fit-content;
22-
}
12+
}

frontend/src/presentation/components/CodeEditor/CodeEditor.tsx

Lines changed: 9 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import React, { useState, useEffect, useRef } from "react";
1+
import React, { useState } from "react";
22
import styles from "./CodeEditor.module.css";
3-
import Editor from "@monaco-editor/react";
3+
import Editor, { Monaco } from "@monaco-editor/react";
44
import { Button, Spin } from "antd";
55
import { useCollaboration } from "domain/context/CollaborationContext";
66
import * as monaco from "monaco-editor";
@@ -15,47 +15,22 @@ interface CodeEditorProps {
1515
const CodeEditor: React.FC<CodeEditorProps> = ({ roomId }) => {
1616
const { onEditorIsMounted, isExecuting, setRoomId, connectedUsers } = useCollaboration();
1717
const [theme, setTheme] = useState("vs-light");
18-
const editorRef = useRef<monaco.editor.IStandaloneCodeEditor | null>(null);
19-
const containerRef = useRef<HTMLDivElement>(null);
20-
21-
useEffect(() => {
22-
let resizeObserver: ResizeObserver | null = null;
23-
let resizeTimeout: NodeJS.Timeout;
24-
25-
if (containerRef.current && editorRef.current) {
26-
resizeObserver = new ResizeObserver((entries) => {
27-
// Debounce resize events
28-
clearTimeout(resizeTimeout);
29-
resizeTimeout = setTimeout(() => {
30-
if (editorRef.current) {
31-
editorRef.current.layout();
32-
}
33-
}, 100);
34-
});
35-
36-
resizeObserver.observe(containerRef.current);
37-
}
38-
39-
return () => {
40-
if (resizeObserver) {
41-
resizeObserver.disconnect();
42-
}
43-
clearTimeout(resizeTimeout);
44-
};
45-
}, []);
4618

4719
const handleEditorDidMount = (editor: monaco.editor.IStandaloneCodeEditor) => {
48-
editorRef.current = editor;
4920
onEditorIsMounted(editor);
5021
setRoomId(roomId);
5122
};
5223

5324
const handleToggleTheme = () => {
54-
setTheme(theme === "vs-light" ? "vs-dark" : "vs-light");
25+
if (theme === "vs-light") {
26+
setTheme("vs-dark");
27+
} else {
28+
setTheme("vs-light");
29+
}
5530
};
5631

5732
return (
58-
<div className={styles.container} ref={containerRef}>
33+
<div className={styles.container}>
5934
<div className={styles.toolbar}>
6035
<div className={styles.toolbarLeft}>
6136
<LanguageSelector />
@@ -94,8 +69,7 @@ const CodeEditor: React.FC<CodeEditorProps> = ({ roomId }) => {
9469
options={{
9570
minimap: { enabled: false },
9671
scrollbar: { verticalScrollbarSize: 4 },
97-
formatOnPaste: true,
98-
automaticLayout: false // Disable automatic layout
72+
formatOnPaste: true
9973
}}
10074
/>
10175
</div>

frontend/src/presentation/components/buttons/ToggleButton.module.css

Lines changed: 0 additions & 47 deletions
This file was deleted.

frontend/src/presentation/components/buttons/ToggleButton.tsx

Lines changed: 0 additions & 25 deletions
This file was deleted.

frontend/src/presentation/components/iframe/ChatFrame.module.css

Lines changed: 0 additions & 17 deletions
This file was deleted.

frontend/src/presentation/components/iframe/ChatFrame.tsx

Lines changed: 0 additions & 24 deletions
This file was deleted.

0 commit comments

Comments
 (0)