Skip to content

Commit

Permalink
Create release 1.1.1 (#249)
Browse files Browse the repository at this point in the history
Fix some bugs related to loading state, match-finding etc

---------

Co-authored-by: Ong Jun Xiong <[email protected]>
Co-authored-by: chunweii <[email protected]>
  • Loading branch information
3 people authored Nov 13, 2023
1 parent efda09a commit 7d95ade
Show file tree
Hide file tree
Showing 20 changed files with 334 additions and 107 deletions.
9 changes: 7 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,11 @@ your services / frontend.
├── /frontend
│ └── /pages for peerprep (NextJs application)
├── /deployment
│ ├── /docker
│ └── /kubernetes
│ ├── /gke-prod-manifests
│ ├── /prod-dockerfiles
│ └── build-export-prod-images.sh
├── /prisma
├── /utils
├── .env (not in git)
├── .env.firebase_emulators_test (not in git)
└── README.md (and other root-level files & docs)
Expand Down Expand Up @@ -137,6 +140,8 @@ Docker and Docker Compose are used to set up a simulated production build (meani
containers that will be spun up locally are almost identical to those in the production environment, with the exception
of some environment variables).
NOTE: Do not run both Docker and No Docker at the same time. This will cause port conflicts.
1. **Run yarn docker:build:** From the root repo, run
```bash
Expand Down
10 changes: 6 additions & 4 deletions frontend/src/components/profile/columns.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Attempt } from "@/types/UserTypes"
import { ColumnDef } from "@tanstack/react-table"
import { Attempt } from "@/types/UserTypes";
import { ColumnDef } from "@tanstack/react-table";
import { Button } from "../ui/button";

export const columns: ColumnDef<Attempt>[] = [
Expand All @@ -16,7 +16,7 @@ export const columns: ColumnDef<Attempt>[] = [
header: "Status",
cell: ({ row }) => {
const solved = row.getValue("solved") as boolean;
return (solved ? <div className="text-green-500">Solved</div> : "Unsolved");
return solved ? <div className="text-green-500">Solved</div> : "Unsolved";
},
},
{
Expand All @@ -26,6 +26,8 @@ export const columns: ColumnDef<Attempt>[] = [
const timeCreated = row.getValue("time_created") as Date;
return timeCreated.toLocaleString();
},
enableSorting: true,
sortDescFirst: true,
},
{
id: "actions",
Expand All @@ -46,4 +48,4 @@ export const columns: ColumnDef<Attempt>[] = [
);
},
},
]
];
25 changes: 15 additions & 10 deletions frontend/src/components/profile/data-table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import {
flexRender,
getCoreRowModel,
useReactTable,
} from "@tanstack/react-table"
getSortedRowModel,
} from "@tanstack/react-table";

import {
Table,
Expand All @@ -12,11 +13,11 @@ import {
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table"
} from "@/components/ui/table";

interface DataTableProps<TData, TValue> {
columns: ColumnDef<TData, TValue>[]
data: TData[]
columns: ColumnDef<TData, TValue>[];
data: TData[];
}

export function DataTable<TData, TValue>({
Expand All @@ -27,7 +28,11 @@ export function DataTable<TData, TValue>({
data,
columns,
getCoreRowModel: getCoreRowModel(),
})
initialState: {
sorting: [{ id: "time_created", desc: true }],
},
getSortedRowModel: getSortedRowModel(),
});

return (
<div className="rounded-md border">
Expand All @@ -41,11 +46,11 @@ export function DataTable<TData, TValue>({
{header.isPlaceholder
? null
: flexRender(
header.column.columnDef.header,
header.getContext()
)}
header.column.columnDef.header,
header.getContext()
)}
</TableHead>
)
);
})}
</TableRow>
))}
Expand Down Expand Up @@ -74,5 +79,5 @@ export function DataTable<TData, TValue>({
</TableBody>
</Table>
</div>
)
);
}
48 changes: 32 additions & 16 deletions frontend/src/components/room/code-editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ type CodeEditorProps = {
onChange: React.Dispatch<React.SetStateAction<string>>;
onCursorChange?: React.Dispatch<React.SetStateAction<number>>;
hasRoom?: boolean;
onSubmitClick?: (param: string) => void;
onSubmitClick?: (param: string, solved: boolean) => void;
onLeaveRoomClick?: () => void;
};

Expand Down Expand Up @@ -72,6 +72,7 @@ export default function CodeEditor({
}: CodeEditorProps) {
const [open, setOpen] = React.useState(false);
const [value, setValue] = React.useState("");
const [frameWork, setFrameWork] = React.useState(language); // default to python
const [isSubmitting, setIsSubmitting] = React.useState(false);

const [monacoInstance, setMonacoInstance] =
Expand Down Expand Up @@ -114,13 +115,13 @@ export default function CodeEditor({
[onChange, onCursorChange, monacoInstance]
);

const handleOnSubmitClick = async () => {
const handleOnSubmitClick = async (solved: boolean) => {
if (isSubmitting) {
return; // Do nothing if a submission is already in progress.
}
setIsSubmitting(true);
try {
onSubmitClick(monacoInstance?.getValue() ?? value);
onSubmitClick(monacoInstance?.getValue() ?? value, solved);
} catch (error) {
console.log(error);
}
Expand All @@ -137,8 +138,8 @@ export default function CodeEditor({
aria-expanded={open}
className="w-[240px] justify-between"
>
{value
? languages.find((framework) => framework.value === value)
{frameWork
? languages.find((framework) => framework.value === frameWork)
?.label
: "Select framework..."}
<ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
Expand All @@ -153,14 +154,18 @@ export default function CodeEditor({
<CommandItem
key={framework.value}
onSelect={(currentValue) => {
setValue(currentValue === value ? "" : currentValue);
setFrameWork(
currentValue === frameWork ? "" : currentValue
);
setOpen(false);
}}
>
<Check
className={cn(
"mr-2 h-4 w-4",
value === framework.value ? "opacity-100" : "opacity-0"
frameWork === framework.value
? "opacity-100"
: "opacity-0"
)}
/>
{framework.label}
Expand All @@ -183,8 +188,9 @@ export default function CodeEditor({
</div>
</div>
<Editor
key={frameWork}
height={height}
defaultLanguage={language}
defaultLanguage={frameWork}
defaultValue={defaultValue}
value={text}
theme={theme}
Expand All @@ -198,14 +204,24 @@ export default function CodeEditor({
Leave Room
</Button>
) : (
<Button
size={"sm"}
variant="default"
onClick={handleOnSubmitClick}
disabled={isSubmitting}
>
Submit
</Button>
<div className="flex flex-row space-x-4">
<Button
size={"sm"}
variant="secondary"
onClick={() => handleOnSubmitClick(false)}
disabled={isSubmitting}
>
Submit as unsolved
</Button>
<Button
size={"sm"}
variant="default"
onClick={() => handleOnSubmitClick(true)}
disabled={isSubmitting}
>
Submit as Solved
</Button>
</div>
)}
</div>
</Card>
Expand Down
24 changes: 17 additions & 7 deletions frontend/src/components/room/video-room.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
import React, { useEffect, useRef, useState } from 'react';
import React, { useContext, useEffect, useRef, useState } from 'react';
import { LocalParticipant, LocalVideoTrack, Participant, RemoteParticipant, RemoteAudioTrack, RemoteVideoTrack, Room, Track } from 'twilio-video';
import { Button } from '../ui/button';
import { Mic, MicOff, Video, VideoOff } from 'lucide-react';
import { useUser } from '@/hooks/useUser';
import { AuthContext } from '../../contexts/AuthContext';

interface VideoRoomProps {
room: Room | null;
className?: string;
}

function SingleVideoTrack({ track, userId, isLocal, isMute, toggleMute, isCameraOn, toggleCamera }:
function SingleVideoTrack({ track, userId, displayName, isLocal, isMute, toggleMute, isCameraOn, toggleCamera }:
{
track: RemoteVideoTrack | LocalVideoTrack, userId: string, isLocal: boolean,
track: RemoteVideoTrack | LocalVideoTrack, userId: string, displayName: string, isLocal: boolean,
isMute: boolean, toggleMute: () => void,
isCameraOn: boolean, toggleCamera: () => void
}) {
Expand All @@ -31,7 +33,7 @@ function SingleVideoTrack({ track, userId, isLocal, isMute, toggleMute, isCamera
<div className="w-64 p-2 flex flex-col items-center justify-center border border-primary rounded-lg">
<div ref={videoContainer}></div>
<div className="flex-1 ml-1 w-full h-8 flex items-center justify-between">
<p>{userId}</p>
<p>{displayName}</p>
{isLocal ? <div className="flex flex-row gap-2 justify-end">
<Button variant="ghost" size="icon" onClick={toggleCamera}>
{isCameraOn ? <Video /> : <VideoOff />}
Expand Down Expand Up @@ -65,9 +67,18 @@ const VideoRoom: React.FC<VideoRoomProps> = ({ room, className }) => {
const [isMute, setIsMute] = useState(true);
const [participants, setParticipants] = useState<RemoteParticipant[]>([]);
const [localParticipant, setLocalParticipant] = useState<LocalParticipant | null>(null);
const [participantNames, setParticipantNames] = useState<{[id: string]: string}>({});
const {user} = useContext(AuthContext);
const {getAppUser} = useUser();


const handleNewParticipant = (participant: RemoteParticipant) => {
if (!(participant.identity in participantNames)) {
setParticipantNames(p => ({...p, [participant.identity]: "Loading..."}));
getAppUser(participant.identity, false).then(user => {
setParticipantNames(p => ({...p, [participant.identity]: user?.displayName || ""}));
}).catch(err => console.log);
}

participant.on('trackSubscribed', track => {
setParticipants(p => [...p])
Expand All @@ -82,7 +93,6 @@ const VideoRoom: React.FC<VideoRoomProps> = ({ room, className }) => {
console.log('Participant "%s" connected,', participant.identity);

setParticipants(participants => [...participants, participant]);

handleNewParticipant(participant);
};

Expand Down Expand Up @@ -134,13 +144,13 @@ const VideoRoom: React.FC<VideoRoomProps> = ({ room, className }) => {
<div className="flex gap-4 absolute bottom-10">
{localParticipant ? Array.from(localParticipant.videoTracks.values()).map(publication => {
if (publication.track.kind === 'video') {
return <SingleVideoTrack track={publication.track} key={localParticipant.identity} userId={localParticipant.identity} isLocal={true} isMute={isMute} toggleMute={toggleMute} isCameraOn={isCameraOn} toggleCamera={toggleCamera} />;
return <SingleVideoTrack track={publication.track} key={localParticipant.identity} userId={localParticipant.identity} displayName={user?.displayName || ""} isLocal={true} isMute={isMute} toggleMute={toggleMute} isCameraOn={isCameraOn} toggleCamera={toggleCamera} />;
} else { return null; }
}) : null}
{participants.flatMap(participant => {
return Array.from(participant.videoTracks.values()).map(publication => {
if (publication.track?.kind === 'video') {
return <SingleVideoTrack track={publication.track} key={participant.identity} userId={participant.identity} isLocal={false} isMute={isMute} toggleMute={toggleMute} isCameraOn={isCameraOn} toggleCamera={toggleCamera} />;
return <SingleVideoTrack track={publication.track} key={participant.identity} userId={participant.identity} displayName={participantNames[participant.identity] || "Loading..."} isLocal={false} isMute={isMute} toggleMute={toggleMute} isCameraOn={isCameraOn} toggleCamera={toggleCamera} />;
} else {
return null;
}
Expand Down
23 changes: 13 additions & 10 deletions frontend/src/hooks/useCollaboration.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,10 @@ const useCollaboration = ({
"User-Id-Token": token,
},
});
setSocket(socketConnection);
setSocket((prevSocket) => {
prevSocket?.disconnect();
return socketConnection;
});

socketConnection.emit(SocketEvents.ROOM_JOIN, roomId, userId);
if (
Expand Down Expand Up @@ -123,11 +126,11 @@ const useCollaboration = ({
cursor: number | undefined | null;
}) => {
prevCursorRef.current = cursorRef.current;
console.log("prevCursor: " + prevCursorRef.current);
// console.log("prevCursor: " + prevCursorRef.current);

console.log("cursor: " + cursor);
// console.log("cursor: " + cursor);

console.log("Update vers to " + version);
// console.log("Update vers to " + version);
vers = version;

if (awaitingAck.current) return;
Expand All @@ -136,13 +139,13 @@ const useCollaboration = ({
prevTextRef.current = text;
setText(text);
if (cursor && cursor > -1) {
console.log("Update cursor to " + cursor);
// console.log("Update cursor to " + cursor);
cursorRef.current = cursor;
setCursor(cursor);
} else {
cursorRef.current = prevCursorRef.current;
cursor = prevCursorRef.current;
console.log("Update cursor to " + prevCursorRef.current);
// console.log("Update cursor to " + prevCursorRef.current);
setCursor(prevCursorRef.current);
}
awaitingSync.current = false;
Expand Down Expand Up @@ -177,17 +180,17 @@ const useCollaboration = ({

awaitingAck.current = true;

console.log("prevtext: " + prevTextRef.current);
console.log("currenttext: " + textRef.current);
console.log("version: " + vers);
// console.log("prevtext: " + prevTextRef.current);
// console.log("currenttext: " + textRef.current);
// console.log("version: " + vers);
const textOp: TextOp = createTextOpFromTexts(
prevTextRef.current,
textRef.current
);

prevTextRef.current = textRef.current;

console.log(textOp);
// console.log(textOp);

const textOperationSet: TextOperationSetWithCursor = {
version: vers,
Expand Down
5 changes: 3 additions & 2 deletions frontend/src/hooks/useMatch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,11 @@ export const useMatch = () => {

const updateQuestionIdInMatch = async (
roomId: string,
questionId: string
questionTitle: string,
questionId: string,
) => {
if (authIsReady && currentUser) {
await patchMatchQuestionByRoomidApi(currentUser, roomId, questionId);
await patchMatchQuestionByRoomidApi(currentUser, roomId, questionId, questionTitle);
}
};

Expand Down
3 changes: 2 additions & 1 deletion frontend/src/pages/api/matchHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ export const getMatchByRoomid = async (user: any, roomId: string) => {
export const patchMatchQuestionByRoomid = async (
user: any,
roomId: string,
questionId: string
questionId: string,
questionTitle: string,
) => {
try {
const url = `${matchApiPathAddress}match/${roomId}`;
Expand Down
Loading

0 comments on commit 7d95ade

Please sign in to comment.