Commit e5f76503 authored by Ruben Bimberg's avatar Ruben Bimberg 💻 Committed by Christopher Mark Fullarton
Browse files

Merge EwCSS task into staging

parent 3df92bb2
......@@ -17,6 +17,7 @@ export class QuizEntity {
public memberGroups: Array<MemberGroupEntity>;
public visibility: QuizVisibility;
public description: string;
public questionCount?: number;
constructor(settingsService, props) {
this.name = props.name;
......@@ -28,6 +29,7 @@ export class QuizEntity {
this.expiry = props.expiry;
this.currentStartTimestamp = props.currentStartTimestamp;
this.memberGroups = props.memberGroups;
this.questionCount = props.questionCount || this.questionList.length;
}
public addQuestion(question: AbstractQuestionEntity, index: number = -1): AbstractQuestionEntity {
......
......@@ -45,6 +45,7 @@ export enum MessageProtocol {
SetInactive = 'SetInactive', //
IsInactive = 'IsInactive', //
NextQuestion = 'NextQuestion', //
NextQuizQuestion = 'NextQuizQuestion', //
Start = 'Start', //
Stop = 'Stop', //
Undefined = 'Undefined', //
......
......@@ -174,6 +174,8 @@ export class AnswerResultComponent implements OnInit, OnDestroy, IHasTriggeredNa
this.hasTriggeredNavigation = true;
this.router.navigate(['/']);
}), this.messageQueue.subscribe(MessageProtocol.NextQuizQuestion, payload => {
this.quizService.onNextQuizQuestion(payload);
}),
]);
}
......
......@@ -205,7 +205,9 @@ export class ConfidenceRateComponent implements OnInit, OnDestroy, IHasTriggered
this._hasCountdownLeft = payload.value > 0;
}), this.messageQueue.subscribe(MessageProtocol.Stop, () => {
this._hasCountdownLeft = false;
})
}), this.messageQueue.subscribe(MessageProtocol.NextQuizQuestion, payload => {
this.quizService.onNextQuizQuestion(payload);
}),
]);
}
......
......@@ -45,6 +45,7 @@ export class LeaderboardComponent implements OnInit, OnDestroy, IHasTriggeredNav
get ownResponse(): { index: number; element: ILeaderBoardItem; closestOpponent: ILeaderBoardItem } {
return this._ownResponse;
}
public static readonly TYPE = 'LeaderboardComponent';
private _questionIndex: number;
......@@ -243,6 +244,17 @@ export class LeaderboardComponent implements OnInit, OnDestroy, IHasTriggeredNav
this.attendeeService.modifyResponse(payload);
}), this.messageQueue.subscribe(MessageProtocol.UpdatedSettings, payload => {
this.quizService.quiz.sessionConfig = payload.sessionConfig;
}), this.messageQueue.subscribe(MessageProtocol.ReadingConfirmationRequested, payload => {
if (this.hasTriggeredNavigation) {
return;
}
this.hasTriggeredNavigation = true;
if (this.settingsService.frontEnv?.readingConfirmationEnabled) {
this.router.navigate(['/quiz', 'flow', 'reading-confirmation']);
} else {
this.router.navigate(['/quiz', 'flow', 'voting']);
}
}), this.messageQueue.subscribe(MessageProtocol.Reset, payload => {
this.attendeeService.clearResponses();
this.quizService.quiz.currentQuestionIndex = -1;
......@@ -257,6 +269,8 @@ export class LeaderboardComponent implements OnInit, OnDestroy, IHasTriggeredNav
}), this.messageQueue.subscribe(MessageProtocol.Closed, payload => {
this.hasTriggeredNavigation = true;
this.router.navigate(['/']);
}), this.messageQueue.subscribe(MessageProtocol.NextQuizQuestion, payload => {
this.quizService.onNextQuizQuestion(payload);
}),
]);
}
......
......@@ -88,7 +88,7 @@
<div class="question">
<h5 *ngIf="quizService.quiz?.questionList.length">
<span class="mr-1">{{'component.liveResults.question_number' | translate}}&nbsp;{{selectedQuestionIndex + 1}} / {{quizService.quiz.questionList.length}}</span>
<span class="mr-1">{{'component.liveResults.question_number' | translate}}&nbsp;{{selectedQuestionIndex + 1}} / {{quizService.quiz.questionCount}}</span>
<fa-icon *ngIf="isLoadingQuestionData"
[icon]="'spinner'"
[spin]="true"></fa-icon>
......
......@@ -725,6 +725,8 @@ export class QuizResultsComponent implements OnInit, OnDestroy, IHasTriggeredNav
this.hasTriggeredNavigation = true;
this.router.navigate(['/quiz', 'flow', 'answer-result']);
}), this.messageQueue.subscribe(MessageProtocol.NextQuizQuestion, payload => {
this.quizService.onNextQuizQuestion(payload);
}),
]);
}
......
......@@ -147,17 +147,23 @@ export class VotingComponent implements OnInit, OnDestroy, IHasTriggeredNavigati
this.isSendingResponse = true;
this.hasTriggeredNavigation = true;
let result: Array<number> | number | string;
let result: Array<string> | number | string;
if (Array.isArray(this._selectedAnswers)) {
result = this._selectedAnswers.map(v => this._answers.findIndex(answer => answer === v));
const indices = this._selectedAnswers.map(v => this._answers.findIndex(answer => answer === v));
result = indices.map(index => this._currentQuestion.answerOptionList[index].answerText);
} else {
result = this._selectedAnswers;
}
const quiz = this.quizService.quiz;
const index = this.quizService.quiz.currentQuestionIndex;
this.memberApiService.putResponse(result).subscribe((data: IMessage) => {
if (data.status !== StatusProtocol.Success) {
console.log('VotingComponent: PutResponse failed', data);
}
if (data.payload?.TYPE) {
quiz.questionList[index] = data.payload;
}
this.router.navigate(this.getNextRoute(route));
}, err => {
console.log('VotingComponent: PutResponse failed', err);
......@@ -292,10 +298,6 @@ export class VotingComponent implements OnInit, OnDestroy, IHasTriggeredNavigati
}
this.countdown = payload.value;
if (!this.countdown) {
this.hasTriggeredNavigation = true;
this.sendResponses('results');
}
this.cd.markForCheck();
}), this.messageQueue.subscribe(MessageProtocol.Reset, payload => {
if (this.hasTriggeredNavigation) {
......@@ -323,11 +325,12 @@ export class VotingComponent implements OnInit, OnDestroy, IHasTriggeredNavigati
this.hasTriggeredNavigation = true;
this.router.navigate(['/']);
}
}), this.messageQueue.subscribe(MessageProtocol.Stop, payload => {
}), this.messageQueue.subscribe(MessageProtocol.NextQuizQuestion, payload => {
if (this.hasTriggeredNavigation) {
return;
}
this.quizService.onNextQuizQuestion(payload);
this.hasTriggeredNavigation = true;
this.sendResponses('results');
}),
......
......@@ -134,6 +134,7 @@ export class QuizJoinComponent implements OnInit, OnDestroy {
}
this.quizService.quiz = quizStatusData.payload.quiz;
this.quizService.quiz.questionList.forEach(question => question.answerOptionList.sort(() => 0.5 - Math.random()));
this.quizService.isOwner = false;
this.themesService.updateCurrentlyUsedTheme();
......
......@@ -218,4 +218,85 @@ describe('QuizService', () => {
service.stopEditMode();
expect(service['_isInEditMode']).toEqual(false);
});
it('should handle new quiz question payloads', () => {
const service: QuizService = TestBed.inject(QuizService);
service.quiz = quizMock;
const firstQuestion = {
TYPE: 'MultipleChoiceQuestion',
answerOptionList: [
{
TYPE: 'DefaultAnswerOption',
answerText: 'green',
isCorrect: false,
},
{
TYPE: 'DefaultAnswerOption',
answerText: 'red',
isCorrect: true,
},
],
questionText: 'Which color has blood?',
timer: 30,
displayAnswerText: true,
tags: [],
requiredForToken: true,
difficulty: 1,
};
service.quiz.questionList.length = 0;
service['_isOwner'] = false;
service.onNextQuizQuestion({
nextQuestion: firstQuestion
});
expect(service.quiz.questionList.length).toEqual(1);
});
it('should ignore new quiz question payloads for owner', () => {
const service: QuizService = TestBed.inject(QuizService);
service.quiz = quizMock;
const firstQuestion = {
TYPE: 'MultipleChoiceQuestion',
answerOptionList: [
{
TYPE: 'DefaultAnswerOption',
answerText: 'green',
isCorrect: false,
},
{
TYPE: 'DefaultAnswerOption',
answerText: 'red',
isCorrect: true,
},
],
questionText: 'Which color has blood?',
timer: 30,
displayAnswerText: true,
tags: [],
requiredForToken: true,
difficulty: 1,
};
service.quiz.questionList.length = 0;
service['_isOwner'] = true;
service.onNextQuizQuestion({
nextQuestion: firstQuestion
});
expect(service.quiz.questionList.length).toEqual(0);
});
it('should ignore empty question on end', () => {
const service: QuizService = TestBed.inject(QuizService);
service.quiz = quizMock;
const previous = service.quiz.questionList.length;
service['_isOwner'] = false;
service.onNextQuizQuestion({
nextQuestion: {}
});
expect(service.quiz.questionList.length).toEqual(previous);
});
});
......@@ -288,6 +288,18 @@ export class QuizService {
this.playAudio = !this.playAudio;
}
public onNextQuizQuestion(payload: any): void {
if (this.isOwner) {
return;
}
const questions = this.quiz.questionList;
const newQuestion = payload.nextQuestion as AbstractQuestionEntity;
if (newQuestion?.answerOptionList) {
newQuestion.answerOptionList.sort(() => 0.5 - Math.random());
questions.splice(questions.length, 0, newQuestion);
}
}
private restoreSettings(quizName: string): Promise<boolean> {
return new Promise<boolean>((resolve, reject) => {
this.quizApiService.getQuiz(quizName).subscribe(response => {
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment