Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: update read only view to show code, language, chat and execution result #209

Merged
merged 7 commits into from
Nov 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion backend/collaboration-service/src/models/collab.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Schema } from 'mongoose'
import { CollabDto } from '../types/CollabDto'
import { LanguageMode } from '@repo/collaboration-types'
import chatModelSchema from './chat.model'
import executionResultSchema from './result.model'

const collabSchema = new Schema<CollabDto>({
language: {
Expand All @@ -14,8 +15,9 @@ const collabSchema = new Schema<CollabDto>({
required: false,
},
executionResult: {
type: String,
type: executionResultSchema,
required: false,
default: {},
},
chatHistory: {
type: [chatModelSchema],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Model, model } from 'mongoose'
import { CollabDto } from '../types'
import collabSchema from './collab.model'
import { LanguageMode, ChatModel } from '@repo/collaboration-types'
import { LanguageMode, ChatModel, ResultModel } from '@repo/collaboration-types'

const collabModel: Model<CollabDto> = model('collab', collabSchema)

Expand Down Expand Up @@ -32,6 +32,6 @@ export async function saveCode(id: string, code: string) {
return collabModel.updateOne({ _id: id }, { $set: { code: code } })
}

export async function saveResult(id: string, result: string) {
export async function saveResult(id: string, result: ResultModel) {
return collabModel.updateOne({ _id: id }, { $set: { executionResult: result } })
}
31 changes: 31 additions & 0 deletions backend/collaboration-service/src/models/result.model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { Schema } from 'mongoose'
import { ResultModel } from '@repo/collaboration-types'

const executionResultSchema = new Schema<ResultModel>({
time: {
type: String,
required: false,
},
status: {
type: Object,
required: false,
},
stderr: {
type: String,
required: false,
},
compile_output: {
type: String,
required: false,
},
stdout: {
type: String,
required: false,
},
testIndex: {
type: Number,
required: false,
},
})

export default executionResultSchema
23 changes: 16 additions & 7 deletions backend/collaboration-service/src/services/socketio.service.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import loggerUtil from '../common/logger.util'
import { Server as IOServer, Socket } from 'socket.io'
import { completeCollaborationSession } from './collab.service'
import { updateChatHistory, updateLanguage } from '../models/collab.repository'
import { saveResult, updateChatHistory, updateLanguage } from '../models/collab.repository'
import { LanguageMode, ChatModel } from '@repo/collaboration-types'
import { SubmissionResponseDto } from '../types'
import { IResponse, ISubmission } from '@repo/submission-types'
import { ISubmission } from '@repo/submission-types'
import { ResultModel } from '@repo/collaboration-types'
import { submitCode } from '../controllers/collab.controller'

export class WebSocketConnection {
Expand All @@ -25,17 +26,17 @@ export class WebSocketConnection {
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.emit('update-language', this.languages.get(roomId), false)
}
})

socket.on('send_message', (data: ChatModel) => {
socket.on('send_message', async (data: ChatModel) => {
await updateChatHistory(data.roomId, data)
this.io.to(data.roomId).emit('receive_message', data)
updateChatHistory(data.roomId, data)
})

socket.on('change-language', async (language: string) => {
this.io.to(roomId).emit('update-language', language)
this.io.to(roomId).emit('update-language', language, true)
this.languages.set(roomId, language)
await updateLanguage(roomId, language as LanguageMode)
})
Expand All @@ -45,8 +46,16 @@ export class WebSocketConnection {
try {
const dto: SubmissionResponseDto = await submitCode(data)
const { stdout, status, time, stderr, compile_output } = dto
const response: IResponse = { stdout, status, time, stderr, compile_output }
const response: ResultModel = {
stdout,
status,
time,
stderr,
compile_output,
testIndex: data.testIndex,
}
this.io.to(roomId).emit('code-executed', response, data.expected_output)
await saveResult(roomId, response)
} catch (err) {
this.io.to(roomId).emit('code-executed', { error: err })
}
Expand Down
10 changes: 5 additions & 5 deletions backend/collaboration-service/src/types/CollabDto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
ValidationError,
} from 'class-validator'
import { Type } from 'class-transformer'
import { LanguageMode, ChatModel, ICollabCreateSessionDto } from '@repo/collaboration-types'
import { LanguageMode, ChatModel, ICollabCreateSessionDto, ResultModel } from '@repo/collaboration-types'
import 'reflect-metadata'

export class CollabDto {
Expand All @@ -25,8 +25,8 @@ export class CollabDto {
@IsString()
code: string

@IsString()
executionResult: string
@Type(() => ResultModel)
executionResult: ResultModel

@IsArray()
@ValidateNested({ each: true })
Expand All @@ -41,7 +41,7 @@ export class CollabDto {
matchId: string,
language: LanguageMode,
code: string,
executionResult: string,
executionResult: ResultModel,
chatHistory: ChatModel[]
) {
this.matchId = matchId
Expand All @@ -53,7 +53,7 @@ export class CollabDto {
}

static fromCreateRequest({ body: { matchId, language } }: ITypedBodyRequest<ICollabCreateSessionDto>): CollabDto {
return new CollabDto(matchId, language, '', '', [])
return new CollabDto(matchId, language, '', {}, [])
}

static fromModel({ matchId, language, code, executionResult, chatHistory }: CollabDto): CollabDto {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,14 @@ export async function handleCreateMatch(data: IMatch, ws1: string, ws2: string):
wsConnection.sendMessageToUser(ws2, JSON.stringify({ type: WebSocketMessageType.DUPLICATE }))
}

const question = await getRandomQuestion(data.category, convertComplexityToSortedComplexity(data.complexity))
let question

try {
question = await getRandomQuestion(data.category, convertComplexityToSortedComplexity(data.complexity))
} catch (err) {
logger.error('[Matching-Service] Failed to get random question' + err)
return
}

if (!question) {
logger.error('[Matching-Service] Could not get a random question')
Expand Down
3 changes: 2 additions & 1 deletion frontend/components/customs/difficulty-label.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { capitalizeFirstLowerRest } from '@/util/string-modification'
import CustomLabel from '../ui/label'
import { Complexity } from '@repo/user-types'

Expand Down Expand Up @@ -28,5 +29,5 @@ export const DifficultyLabel: FC<DifficultyLabelProps> = ({ complexity }) => {
bgColor = 'bg-theme-100'
}

return <CustomLabel title={complexity} textColor={textColor} bgColor={bgColor} />
return <CustomLabel title={capitalizeFirstLowerRest(complexity)} textColor={textColor} bgColor={bgColor} />
}
11 changes: 6 additions & 5 deletions frontend/components/dashboard/new-session.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,20 @@ import { toast } from 'sonner'
import { addUserToMatchmaking } from '../../services/matching-service-api'
import CustomModal from '../customs/custom-modal'
import Loading from '../customs/loading'
import { capitalizeFirstLowerRest } from '@/util/string-modification'

export const NewSession = () => {
const router = useRouter()
const socketRef = useRef<WebSocket | undefined>(undefined)

const TopicOptions = Object.values(Category).map((category) => ({
value: category,
label: category.charAt(0).toUpperCase() + category.toLocaleLowerCase().slice(1),
label: capitalizeFirstLowerRest(category),
}))

const ComplexityOptions = Object.values(Complexity).map((complexity) => ({
value: complexity,
label: complexity.charAt(0).toUpperCase() + complexity.toLocaleLowerCase().slice(1),
label: capitalizeFirstLowerRest(complexity),
}))

const { data: session } = useSession()
Expand All @@ -52,7 +53,7 @@ export const NewSession = () => {

const handleMatchmaking = async () => {
if (!selectedTopic || !selectedComplexity) {
toast.error('Please select a topic and complexity level to start matchmaking.')
toast.error('Please select a category and complexity level to start matchmaking.')
return
}
setTimeElapsed(0)
Expand Down Expand Up @@ -171,11 +172,11 @@ export const NewSession = () => {
<h5 className=" text-xl text-medium font-bold">Start a New Session</h5>
<br />
<p className="text-medium font-medium mb-1">
Choose a <strong>Topic</strong> and <strong>Complexity</strong> level to start your collaborative
Choose a <strong>Category</strong> and <strong>Complexity</strong> level to start your collaborative
coding session!
</p>

<p className="text-medium font-bold mt-6 mb-2">Topic</p>
<p className="text-medium font-bold mt-6 mb-2">Category</p>
<Select onValueChange={(val: string) => setSelectedTopic(val as Category)}>
<SelectTrigger>
<SelectValue placeholder="Select one..." />
Expand Down
26 changes: 21 additions & 5 deletions frontend/components/dashboard/recent-sessions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@
import Link from 'next/link'
import { MoveRight } from 'lucide-react'
import { IPartialSessions } from '@/types'
import CustomLabel from '../ui/label'
import { capitalizeFirstLowerRest } from '@/util/string-modification'

const cols: { key: keyof IPartialSessions; label: string }[] = [
{
Expand Down Expand Up @@ -40,11 +42,25 @@ export const RecentSessions = ({ data }: { data: IPartialSessions[] }) => {
<TableBody>
{data.map((row, index) => (
<TableRow key={index}>
{cols.map((col) => (
<TableCell key={col.key}>
<p>{row[col.key]}</p>
</TableCell>
))}
{cols.map((col) => {
if (col.key === 'category') {
return (
<TableCell key={col.key}>
<CustomLabel
title={capitalizeFirstLowerRest(row[col.key])}
textColor="text-theme"
bgColor="bg-theme-100"
/>
</TableCell>
)
} else {
return (
<TableCell key={col.key}>
<p>{row[col.key]}</p>
</TableCell>
)
}
})}
</TableRow>
))}
</TableBody>
Expand Down
7 changes: 4 additions & 3 deletions frontend/components/dashboard/resume-session.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { useRouter } from 'next/router'
import { Button } from '../ui/button'
import { IMatch } from '@repo/user-types'
import { convertSortedComplexityToComplexity } from '@repo/question-types'
import { capitalizeFirstLowerRest } from '@/util/string-modification'

interface IResumeSessionProps {
match: IMatch
Expand All @@ -28,12 +29,12 @@ export default function ResumeSession({ match, isOngoing }: IResumeSessionProps)
<p>You have an ongoing session for:</p>
<form>
<label htmlFor="topic" className="block font-bold mb-2">
Topic
Category
</label>
<input
id="ongoing-topic"
type="text"
value={category}
value={capitalizeFirstLowerRest(category)}
readOnly
className="w-full p-2 text-sm border-solid border-2 border-gray-200 rounded bg-gray-50"
/>
Expand All @@ -43,7 +44,7 @@ export default function ResumeSession({ match, isOngoing }: IResumeSessionProps)
<input
id="ongoing-complexity"
type="text"
value={convertSortedComplexityToComplexity(complexity)}
value={capitalizeFirstLowerRest(convertSortedComplexityToComplexity(complexity))}
readOnly
className="w-full p-2 text-sm border-solid border-2 border-gray-200 rounded bg-gray-50"
/>
Expand Down
Loading
Loading