Skip to content

Commit 6a86ff6

Browse files
committed
PEER-234: Add functioning collab UI
Signed-off-by: SeeuSim <[email protected]>
1 parent 0a386ac commit 6a86ff6

File tree

8 files changed

+141
-56
lines changed

8 files changed

+141
-56
lines changed

docker-compose.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,8 @@ services:
169169
environment:
170170
- VITE_USER_SERVICE=http://${USER_SERVICE_NAME}:${USER_EXPRESS_PORT}
171171
- VITE_QUESTION_SERVICE=http://${QUESTION_SERVICE_NAME}:${QUESTION_EXPRESS_PORT}
172+
- VITE_COLLAB_SERVICE=http://${COLLAB_SERVICE_NAME}:${COLLAB_EXPRESS_PORT}
173+
- VITE_COLLAB_WS=ws://${COLLAB_SERVICE_NAME}:${COLLAB_EXPRESS_PORT}
172174
- VITE_MATCHING_SERVICE=http://${MATCHING_SERVICE_NAME}:${MATCHING_EXPRESS_PORT}
173175
- FRONTEND_PORT=${FRONTEND_PORT}
174176
depends_on:

frontend/entrypoint.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#!/bin/sh
22

3-
envsubst '${FRONTEND_PORT} ${VITE_USER_SERVICE} ${VITE_QUESTION_SERVICE} ${VITE_COLLAB_SERVICE}' < /etc/nginx/nginx.conf.template > /etc/nginx/conf.d/default.conf
3+
envsubst '${FRONTEND_PORT} ${VITE_USER_SERVICE} ${VITE_QUESTION_SERVICE} ${VITE_COLLAB_SERVICE} ${VITE_COLLAB_WS}' < /etc/nginx/nginx.conf.template > /etc/nginx/conf.d/default.conf
44

55
nginx -g 'daemon off;'

frontend/nginx.conf.template

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,17 @@ server {
3434
proxy_set_header X-Forwarded-Proto $scheme;
3535
}
3636

37+
location /collab-ws {
38+
proxy_pass ${VITE_COLLAB_WS};
39+
proxy_http_version 1.1;
40+
proxy_set_header Upgrade $http_upgrade;
41+
proxy_set_header Connection "upgrade";
42+
proxy_set_header Host $host;
43+
proxy_set_header X-Real-IP $remote_addr;
44+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
45+
proxy_set_header X-Forwarded-Proto $scheme;
46+
}
47+
3748
access_log /var/log/nginx/access.log;
3849
error_log /var/log/nginx/error.log;
3950
}

frontend/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,9 @@
4949
"remark-math": "^6.0.0",
5050
"tailwind-merge": "^2.5.2",
5151
"tailwindcss-animate": "^1.0.7",
52+
"ws": "^8.18.0",
5253
"y-codemirror.next": "^0.3.5",
53-
"y-socket.io": "^1.1.3",
54+
"y-websocket": "^2.0.4",
5455
"yjs": "^13.6.20",
5556
"zod": "^3.23.8"
5657
},
@@ -61,6 +62,7 @@
6162
"@types/node": "^22.5.5",
6263
"@types/react": "^18.3.3",
6364
"@types/react-dom": "^18.3.0",
65+
"@types/ws": "^8.5.12",
6466
"@vitejs/plugin-react-swc": "^3.5.0",
6567
"autoprefixer": "^10.4.20",
6668
"eslint": "^9.9.0",

frontend/src/lib/hooks/use-collab.ts

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ import type { LanguageName } from '@uiw/codemirror-extensions-langs';
22
import type { Extension, ReactCodeMirrorRef } from '@uiw/react-codemirror';
33
import { useEffect, useMemo, useRef, useState } from 'react';
44
import { yCollab } from 'y-codemirror.next';
5-
import { SocketIOProvider } from 'y-socket.io';
5+
import { WebsocketProvider } from 'y-websocket';
66
import * as Y from 'yjs';
77

88
import { extensions as baseExtensions, getLanguage } from '@/lib/editor/extensions';
9-
import { COLLAB_SERVICE } from '@/services/api-clients';
9+
import { COLLAB_WS } from '@/services/api-clients';
1010

1111
// credit: https://github.com/yjs/y-websocket
1212
const usercolors = [
@@ -39,7 +39,7 @@ export const useCollab = (roomId: string) => {
3939
const doc = new Y.Doc();
4040
let provider = null;
4141
try {
42-
provider = new SocketIOProvider(COLLAB_SERVICE, roomId, doc, {});
42+
provider = new WebsocketProvider(COLLAB_WS, roomId, doc);
4343
} catch (err) {
4444
const { name, message } = err as Error;
4545
console.error(
@@ -50,9 +50,20 @@ export const useCollab = (roomId: string) => {
5050
const ytext = doc.getText('codemirror');
5151
const undoManager = new Y.UndoManager(ytext);
5252
const awareness = provider.awareness;
53-
const { color, light } = getRandomColor();
5453

54+
provider.on('status', (event: unknown) => {
55+
const ev = event as { status?: string } | undefined;
56+
console.log(`Connection Status: ${ev?.status}`);
57+
});
58+
59+
// TODO: Update state store, then display avatars
60+
awareness.on('update', () => {
61+
console.log(awareness.getStates().values()); // Array of name, color, light
62+
});
63+
64+
const { color, light } = getRandomColor();
5565
// TODO: Get user name
66+
// TODO: Set user ID
5667
awareness.setLocalStateField('user', {
5768
name: `Anon`,
5869
color: color,

frontend/src/services/api-clients.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import axios from 'axios';
33
export const USER_SERVICE = '/user-service';
44
export const QUESTION_SERVICE = '/question-service';
55
export const COLLAB_SERVICE = '/collaboration-service';
6+
export const COLLAB_WS = '/collab-ws';
67

78
const getApiClientBaseConfig = (service: string) => ({
89
baseURL: service,

frontend/vite.config.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ export default defineConfig(({ mode }) => {
4444
'*': '/',
4545
},
4646
},
47+
'/collab-ws': {
48+
target: `${env.VITE_COLLAB_SERVICE.replace('http', 'ws')}`,
49+
ws: true,
50+
},
4751
},
4852
},
4953
};

0 commit comments

Comments
 (0)