Skip to content

Commit

Permalink
Merge pull request #179 from CS3219-AY2425S1/handle-ws-languages
Browse files Browse the repository at this point in the history
Support Changing of Languages
  • Loading branch information
shishirbychapur authored Nov 1, 2024
2 parents 6b612ba + 4c4870c commit ae06b95
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 16 deletions.
17 changes: 16 additions & 1 deletion backend/collaboration-service/src/services/socketio.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { completeCollaborationSession } from './collab.service'

export class WebSocketConnection {
private io: IOServer
private languages: Map<string, string> = new Map()

constructor(port: number) {
this.io = new IOServer(port, {
Expand All @@ -18,18 +19,32 @@ export class WebSocketConnection {
socket.on('joinRoom', ({ roomId }) => {
socket.join(roomId)
this.io.to(roomId).emit('user-connected', name)
if (this.languages.has(roomId)) {
socket.emit('update-language', this.languages.get(roomId))
}
})

socket.on('change-language', (language: string) => {
this.io.to(roomId).emit('update-language', language)
this.languages.set(roomId, language)
})

socket.on('disconnect', async () => {
const room = this.io.sockets.adapter.rooms.get(roomId)
let room = this.io.sockets.adapter.rooms.get(roomId)
socket.leave(roomId)
if (!this.isUserInRoom(roomId, name)) {
this.io.to(roomId).emit('user-disconnected', name)
loggerUtil.info(`User ${name} disconnected from room ${roomId}`)
}

// If user refreshes and other user has disconnected, then give a bit of time to reconnect
await new Promise((resolve) => setTimeout(resolve, 3000))
room = this.io.sockets.adapter.rooms.get(roomId)

if (!room) {
loggerUtil.info(`Room ${roomId} is empty. Completing session.`)
await completeCollaborationSession(roomId)
this.languages.delete(roomId)
}
})
})
Expand Down
19 changes: 12 additions & 7 deletions frontend/pages/code/[id]/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { EndIcon, PlayIcon, SubmitIcon } from '@/assets/icons'
import { ITestcase } from '@/types'
import { ITestcase, LanguageMode, getCodeMirrorLanguage } from '@/types'
import { mockChatData, mockTestCaseData, mockUserData } from '@/mock-data'
import { useEffect, useRef, useState } from 'react'

Expand All @@ -20,6 +20,7 @@ import { getMatchDetails } from '@/services/matching-service-api'
import { convertSortedComplexityToComplexity } from '@repo/question-types'
import io, { Socket } from 'socket.io-client'
import UserAvatar from '@/components/customs/custom-avatar'
import { toast } from 'sonner'

interface ICollaborator {
name: string
Expand Down Expand Up @@ -63,7 +64,7 @@ export default function Code() {
const [isChatOpen, setIsChatOpen] = useState(true)
const [chatData, setChatData] = useState(initialChatData)
const { id } = router.query
const [editorLanguage, setEditorLanguage] = useState('javascript')
const [editorLanguage, setEditorLanguage] = useState<LanguageMode>(LanguageMode.Javascript)
const testTabs = ['Testcases', 'Test Results']
const [activeTestTab, setActiveTestTab] = useState(0)
const [matchData, setMatchData] = useState<IMatch | undefined>(undefined)
Expand Down Expand Up @@ -103,15 +104,18 @@ export default function Code() {
}
})

socketRef.current.on('update-language', (language: string) => {
setEditorLanguage(language as LanguageMode)
toast.success('Language mode updated')
})

socketRef.current.on('user-connected', (username: string) => {
console.log('triggered')
if (username !== sessionData?.user.username) {
setIsOtherUserOnline(true)
}
})

socketRef.current.on('user-disconnected', (username: string) => {
console.log('triggered')
if (username !== sessionData?.user.username) {
setIsOtherUserOnline(false)
}
Expand Down Expand Up @@ -156,8 +160,7 @@ export default function Code() {
}, [chatData])

const handleLanguageModeSelect = (value: string) => {
console.log('Hey', value)
setEditorLanguage(value)
socketRef.current?.emit('change-language', value)
}

const handleRunTests = () => {
Expand Down Expand Up @@ -290,11 +293,13 @@ export default function Code() {
<div id="editor-container" className="mt-4">
<div id="language-mode-select" className="rounded-t-xl bg-black">
<LanguageModeSelect
displayValue={editorLanguage}
setDisplayValue={setEditorLanguage}
onSelectChange={handleLanguageModeSelect}
className="w-max text-white bg-neutral-800 rounded-tl-lg"
/>
</div>
<CodeMirrorEditor roomId={id as string} language={editorLanguage} />
<CodeMirrorEditor roomId={id as string} language={getCodeMirrorLanguage(editorLanguage)} />
</div>
<CustomTabs
tabs={testTabs}
Expand Down
12 changes: 6 additions & 6 deletions frontend/pages/code/language-mode-select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { CsharpIcon, GolangIcon, JavaIcon, JavascriptIcon, PythonIcon, RubyIcon,

interface LanguageModeSelectProps {
className: string
displayValue: LanguageMode
setDisplayValue: (value: LanguageMode) => void
onSelectChange: (value: LanguageMode) => void
}

Expand Down Expand Up @@ -32,22 +34,20 @@ const getLanguageIcon = (language: LanguageMode) => {
}

const LanguageModeSelect = (props: LanguageModeSelectProps) => {
const [displayValue, setDisplayValue] = React.useState(languageModeOptions[0])

const handleValueChange = (val: string) => {
const selectedLanguage = val as LanguageMode
setDisplayValue(selectedLanguage)
props.setDisplayValue(selectedLanguage)
props.onSelectChange(selectedLanguage)
}

return (
<div className={props.className}>
<Select defaultValue={languageModeOptions[0]} value={displayValue} onValueChange={handleValueChange}>
<Select defaultValue={languageModeOptions[0]} value={props.displayValue} onValueChange={handleValueChange}>
<SelectTrigger>
<SelectValue>
<div className="flex items-center gap-2">
{getLanguageIcon(displayValue)}
{displayValue}
{getLanguageIcon(props.displayValue)}
{props.displayValue}
</div>
</SelectValue>
</SelectTrigger>
Expand Down
4 changes: 2 additions & 2 deletions frontend/types/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { LanguageMode } from './language-mode'
import { LanguageMode, getCodeMirrorLanguage } from './language-mode'
import { IQuestion, QuestionStatus, IQuestionsApi } from './question'
import { ITestcase } from './test-case'
import {
Expand All @@ -14,7 +14,7 @@ import { IFormFields, FormType } from './form'
import { ISession } from './session'
import { IGetQuestions, IGetQuestionsDto } from './questions-api'

export { LanguageMode, SortDirection, QuestionStatus, FormType, Modification }
export { LanguageMode, SortDirection, QuestionStatus, FormType, Modification, getCodeMirrorLanguage }
export type {
IQuestion,
ITestcase,
Expand Down
14 changes: 14 additions & 0 deletions frontend/types/language-mode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,17 @@ export enum LanguageMode {
Ruby = 'ruby',
Typescript = 'Typescript',
}

const languageMapping = {
[LanguageMode.Csharp]: 'cs',
[LanguageMode.Golang]: 'go',
[LanguageMode.Javascript]: 'javascript',
[LanguageMode.Java]: 'java',
[LanguageMode.Python]: 'python',
[LanguageMode.Ruby]: 'ruby',
[LanguageMode.Typescript]: 'typescript',
}

export function getCodeMirrorLanguage(mode: LanguageMode) {
return languageMapping[mode]
}

0 comments on commit ae06b95

Please sign in to comment.