Skip to content
Open
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
1 change: 1 addition & 0 deletions src/@types/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ interface StudentQuestion{
time: Date;
text: string;
processed: boolean;
viewed?: boolean;
}
interface ScheduledQuiz {
id: string;
Expand Down
102 changes: 77 additions & 25 deletions src/lecturer/components/app/App.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,23 @@
import { CssBaseline, makeStyles } from "@material-ui/core";
import Backdrop from "@material-ui/core/Backdrop";
import { ThemeProvider, unstable_createMuiStrictModeTheme as createMuiTheme } from "@material-ui/core/styles";
import "fontsource-roboto";
import React, { useContext, useEffect, useState } from "react";
import {
BrowserRouter as Router,
Redirect, Route, Switch
} from "react-router-dom";
import { GridLoader } from "react-spinners";
import { useSocket } from "../../services/SocketService";
import Store, { StoreContext } from "../../services/StoreService";
import { CreateQuestionView } from "../createQuestionView/CreateQuestionView";
import { CreateQuizView } from "../createQuizView/CreateQuizView";
import { CreateSessionView } from "../createSessionView/CreateSessionView";
import { QuestionsListView } from "../questionsListView/QuestionsListView";
import { QuizStatsView } from "../quizStatsView/QuizStatsView";
import { QuizzesListView } from "../quizzesListView/QuizzesListView";
import { SessionDashboardView } from "../sessionDashboardView/SessionDashboardView";
import { TimestampView } from "../timestampView/TimestampView";
import TopBar from "../topBar/topBar";
import 'fontsource-roboto';

import { CssBaseline, makeStyles } from '@material-ui/core';
import Backdrop from '@material-ui/core/Backdrop';
import { ThemeProvider, unstable_createMuiStrictModeTheme as createMuiTheme } from '@material-ui/core/styles';
import React, { useCallback, useContext, useEffect, useState } from 'react';
import { Redirect, Route, Switch } from 'react-router-dom';
import { GridLoader } from 'react-spinners';

import { useSocket } from '../../services/SocketService';
import Store, { StoreContext } from '../../services/StoreService';
import { CreateQuestionView } from '../createQuestionView/CreateQuestionView';
import { CreateQuizView } from '../createQuizView/CreateQuizView';
import { CreateSessionView } from '../createSessionView/CreateSessionView';
import { QuestionsListView } from '../questionsListView/QuestionsListView';
import { QuizStatsView } from '../quizStatsView/QuizStatsView';
import { QuizzesListView } from '../quizzesListView/QuizzesListView';
import { SessionDashboardView } from '../sessionDashboardView/SessionDashboardView';
import { TimestampView } from '../timestampView/TimestampView';
import TopBar from '../topBar/topBar';

const theme = createMuiTheme({
palette: {
Expand Down Expand Up @@ -68,15 +67,69 @@ function App() {
setIsLectureStarted((prev) => !prev);
}

// hotfix by me
// TODO get reaction index with string sent with payload
// TODO make it work nice and properly, because I do not know how
const TIME_WAITING = 20000;
const refreshReactions = useCallback((payload?: ReactionResponsePayload) => {
const reactionsString = [
"HEART",
"HAPPY",
"SAD",
"UP",
"DOWN"
];
let index: number;
if (payload) {
let indexString: string = payload.data.reaction;
index = reactionsString.indexOf(indexString);
} else {
index = Math.round(Math.random() * reactionsString.length);
}
let tmpValues = store.reactionValues;
tmpValues[index]++;
store.reactionValues = tmpValues;
if (!store.reactionModes[index] || store.lastReactionTime > 0)
store.lastReactionTime = Date.now() + TIME_WAITING;
},[store]);

useEffect(() => {
socketEmiter.on("send_student_reaction", refreshReactions);
return () => {
socketEmiter.off("send_student_reaction", refreshReactions);
};
}, [refreshReactions, socketEmiter]);


const refreshQuestionList = useCallback((payload: SendQuestionResponsePayload) => {
console.log("refreshQuestionList");
console.log(payload);
const studentQuestion: StudentQuestion = {
studentNick: payload.data.studentID,
time: new Date(),
text: payload.data.text,
processed: false,
};
const newStudentQuestions = store.studentQuestions;
newStudentQuestions.push(studentQuestion);
store.studentQuestions = newStudentQuestions;
}, [store]);

useEffect(() => {
socketEmiter.on("send_student_question", refreshQuestionList);
return () => {
socketEmiter.off("send_student_question", refreshQuestionList);
};
}, [refreshQuestionList, socketEmiter]);

const classes = makeStyles({
mainContainer:{
minWidth: "100vw",
minHeight: "100vh",
}
})();
return (
<Store>
<Router>

<ThemeProvider theme={theme}>
<CssBaseline />
<Backdrop
Expand Down Expand Up @@ -161,8 +214,7 @@ function App() {
)
}} />
</ThemeProvider>
</Router>
</Store>

);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,8 @@ export function CreateQuestionView() {
}, [QuestionType, answers, mode, noError, question, store.questions, title]);

const timer = useRef<number>();
const handleSubmit = useCallback(() => {
const handleSubmit = useCallback((event) => {
event.preventDefault();
if (!loading) {

if (!validate()) {
Expand Down Expand Up @@ -407,7 +408,7 @@ export function CreateQuestionView() {
if (event.code === "Enter" || event.code === "NumpadEnter") {
event.preventDefault();
if (!loading){
handleSubmit();
handleSubmit(event);
}
}
};
Expand Down
2 changes: 1 addition & 1 deletion src/lecturer/components/createQuizView/CreateQuizView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ export function CreateQuizView() {
}, 500);
}
}
}, [checked, indexArray, loading, questions, right, rightChecked, store, title]);
}, [checked, loading, questions, right, rightChecked, store, title]);

useEffect(() => {
const listener = (event: { code: string; preventDefault: () => void; }) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,45 +3,21 @@ import React, { useContext, useCallback, useEffect, useState } from "react";
import { StoreContext } from "../../services/StoreService";
import { ReactionCounter } from "./ReactionCounter";
import { reactionsIcons } from "../../../common/util/reactions/icons";
import { useSocket } from "../../services/SocketService";
import { ReactionName } from "../../../common/util/reactions/enum";
import { ReactionProgress } from "./ReactionProgress";
import { useSocket } from "../../services/SocketService";

export function ReactionReceiveView() {
const store = useContext(StoreContext);
const { socketEmiter } = useSocket();

const reactions = [
ReactionName.HEART,
ReactionName.HAPPY,
ReactionName.SAD,
ReactionName.UP,
ReactionName.DOWN,
];
// hotfix by me
// TODO get reaction index with string sent with payload
// TODO make it work nice and properly, because I do not know how
const reactionsString = [
"HEART",
"HAPPY",
"SAD",
"UP",
"DOWN"
];
const TIME_WAITING = 20000;
const { socketEmiter } = useSocket();
const refreshReactions = useCallback((payload?: ReactionResponsePayload) => {
let index: number;
if (payload) {
let indexString: string = payload.data.reaction;
index = reactionsString.indexOf(indexString);
} else {
index = Math.round(Math.random() * reactionsString.length);
}
let tmpValues = store.reactionValues;
tmpValues[index]++;
store.reactionValues = tmpValues;
if (!store.reactionModes[index] || store.lastReactionTime > 0)
store.lastReactionTime = Date.now() + TIME_WAITING;
},[]);

const [progressEnabled, setProgressEnabled] = useState<boolean>(!store.reactionModes.reduce((acc, mode) => {
return acc && mode;
Expand Down Expand Up @@ -89,13 +65,6 @@ export function ReactionReceiveView() {
return () => clearInterval(interval);
}, [store, store.lastReactionTime, resetReactions]);

useEffect(() => {
socketEmiter.on("send_student_reaction", refreshReactions);
return () => {
socketEmiter.off("send_student_reaction", refreshReactions);
};
}, [refreshReactions, socketEmiter]);

const classes = makeStyles({
reactionWrapper: {
padding: 10,
Expand All @@ -105,7 +74,7 @@ export function ReactionReceiveView() {
overflow: "hidden",
},
})();

const TIME_WAITING = 20000;
return (
<Paper variant="outlined" square>
{progressEnabled && <ReactionProgress time={TIME_WAITING} />}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { makeStyles, Paper, TextField } from '@material-ui/core';
import { useCallback, useContext, useEffect } from 'react';
import ReactScrollableFeed from 'react-scrollable-feed';

import { useSocket } from '../../services/SocketService';
import { StoreContext } from "../../services/StoreService";
import { StoreContext } from '../../services/StoreService';


export function StudentsQuestionListView() {
Expand All @@ -15,20 +16,20 @@ export function StudentsQuestionListView() {
borderRadius: "0",

},
questionsHeader:{
questionsHeader: {
padding: 10,
fontSize: "16px",
display: "block",
},
questionField:{
overflow:"auto",
height:"98%"
questionField: {
overflow: "auto",
height: "98%"
},
tmp: {
maxHeight: "100%",
},
field:{
margin:"5px 0px"
field: {
margin: "5px 0px"
},
messageReplyButton: {
flexShrink: 0,
Expand All @@ -45,7 +46,7 @@ export function StudentsQuestionListView() {
display: "block",
}
},
"& *":{
"& *": {
pointerEvents: "none",
},
},
Expand All @@ -57,63 +58,51 @@ export function StudentsQuestionListView() {
},
messageText: {
flexGrow: 1,
width:"100%"
width: "100%"
},
questionText:{
width:"100%"
questionText: {
width: "100%"
},
})();

const refreshQuestionList = useCallback((payload: SendQuestionResponsePayload) => {
console.log("refreshQuestionList");
console.log(payload);
const studentQuestion: StudentQuestion = {
studentNick: payload.data.studentID,
time: new Date(),
text: payload.data.text,
processed: false,
};
const newStudentQuestions = store.studentQuestions;
newStudentQuestions.push(studentQuestion);
store.studentQuestions = newStudentQuestions;
}, [store]);

useEffect(() => {
socketEmiter.on("send_student_question", refreshQuestionList);
return () => {
socketEmiter.off("send_student_question", refreshQuestionList);
};
}, [refreshQuestionList, socketEmiter]);
useEffect(
() => {
return () => {
store.studentQuestions.forEach(question => question.viewed = true);
}
}
, [])

return (
<Paper className={classes.root} variant="outlined" square>
<b className={classes.questionsHeader}>
Pytania od studentów
<b className={classes.questionsHeader}>
Pytania od studentów
</b>
<div className={classes.questionField}>
<ReactScrollableFeed>
{store.studentQuestions.map((studentQuestion, index) => {
return (
<div
key={index}
>
<div className={classes.message}>
<div className={classes.messageText}>
<TextField className={classes.field} error={!studentQuestion.processed}
fullWidth={true}
multiline
label={studentQuestion.time.toLocaleTimeString("en-GB") + " | Anonimowy student"}
defaultValue={studentQuestion.text} InputProps={{
className: classes.questionText,
readOnly: true,
}}/>
</div>
<div className={classes.questionField}>
<ReactScrollableFeed>
{store.studentQuestions.map((studentQuestion, index) => {
return (
<div
key={index}
>
<div className={classes.message}>
<div className={classes.messageText}>
<TextField className={classes.field} error={!studentQuestion.viewed}
fullWidth={true}
multiline
label={studentQuestion.time.toLocaleTimeString("en-GB") + " | Anonimowy student"}
defaultValue={studentQuestion.text} InputProps={{
className: classes.questionText,
readOnly: true,
}} />
</div>

</div>
</div>
);
})}
</ReactScrollableFeed>
</div>
</div>
);
})}
</ReactScrollableFeed>
</div>
</Paper>
);
Expand Down
Loading