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

Create release 1.1.1 #249

Merged
merged 18 commits into from
Nov 13, 2023
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
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