Commit f05c8155 authored by Christopher Fullarton's avatar Christopher Fullarton

Fixes bugs where responses were overriden on slow connections

parent 29740391
Pipeline #30197 passed with stages
in 13 minutes and 14 seconds
......@@ -114,6 +114,7 @@ export class ConfidenceRateComponent implements OnInit, OnDestroy {
this._messageSubscriptions.push(...[
this.messageQueue.subscribe(MessageProtocol.NextQuestion, payload => {
this.quizService.quiz.currentQuestionIndex = payload.nextQuestionIndex;
sessionStorage.removeItem(StorageKey.CurrentQuestionIndex);
}), this.messageQueue.subscribe(MessageProtocol.Start, payload => {
this.quizService.quiz.currentStartTimestamp = payload.currentStartTimestamp;
this.router.navigate(['/quiz', 'flow', 'voting']);
......
......@@ -98,7 +98,6 @@ export class LeaderboardComponent implements OnInit, OnDestroy {
this._name = this.quizService.quiz.name;
this.initData();
this.attendeeService.restoreMembers();
this.addFooterElements();
}));
......@@ -204,6 +203,10 @@ export class LeaderboardComponent implements OnInit, OnDestroy {
private handleMessages(): void {
this._messageSubscriptions.push(...[
this.messageQueue.subscribe(MessageProtocol.NextQuestion, payload => {
this.quizService.quiz.currentQuestionIndex = payload.nextQuestionIndex;
sessionStorage.removeItem(StorageKey.CurrentQuestionIndex);
}),
this.messageQueue.subscribe(MessageProtocol.Start, payload => {
this.router.navigate(['/quiz', 'flow', 'voting']);
}), this.messageQueue.subscribe(MessageProtocol.UpdatedResponse, payload => {
......
......@@ -85,11 +85,10 @@ export class QuizLobbyComponent implements OnInit, OnDestroy {
if (this.quizService.isOwner) {
console.log('QuizLobbyComponent: quiz for owner initialized', this.quizService.quiz);
this.handleNewQuiz(this.quizService.quiz);
this.attendeeService.restoreMembers();
} else {
this.handleNewAttendee();
this.attendeeService.restoreMembers();
}
this.attendeeService.restoreMembers();
}));
this.quizService.loadDataToPlay(sessionStorage.getItem(StorageKey.CurrentQuizName)).then(() => {
......@@ -230,8 +229,6 @@ export class QuizLobbyComponent implements OnInit, OnDestroy {
const promise = this.attendeeService.attendees.length ? this.ngbModal.open(EditModeConfirmComponent).result : new Promise<any>(
resolve => resolve());
promise.then(() => {
this._subscriptions.forEach(sub => sub.unsubscribe());
this._messageSubscriptions.forEach(id => this.messageQueue.unsubscribe(id));
this.quizService.close();
this.attendeeService.cleanUp();
this.connectionService.cleanUp();
......@@ -252,6 +249,7 @@ export class QuizLobbyComponent implements OnInit, OnDestroy {
this.attendeeService.removeMember(payload.name);
}), this.messageQueue.subscribe(MessageProtocol.NextQuestion, payload => {
this.quizService.quiz.currentQuestionIndex = payload.nextQuestionIndex;
sessionStorage.removeItem(StorageKey.CurrentQuestionIndex);
}), this.messageQueue.subscribe(MessageProtocol.Start, payload => {
this.quizService.quiz.currentStartTimestamp = payload.currentStartTimestamp;
}), this.messageQueue.subscribe(MessageProtocol.Closed, payload => {
......
......@@ -151,6 +151,7 @@ export class QuestionDetailsComponent implements OnInit, OnDestroy {
this.attendeeService.modifyResponse(payload);
}), this.messageQueue.subscribe(MessageProtocol.NextQuestion, payload => {
this.quizService.quiz.currentQuestionIndex = payload.nextQuestionIndex;
sessionStorage.removeItem(StorageKey.CurrentQuestionIndex);
}), this.messageQueue.subscribe(MessageProtocol.Start, payload => {
this.quizService.quiz.currentStartTimestamp = payload.currentStartTimestamp;
}), this.messageQueue.subscribe(MessageProtocol.Reset, payload => {
......
......@@ -180,8 +180,9 @@ export class QuizResultsComponent implements OnInit, OnDestroy {
public showResponseProgress(): boolean {
this.cd.markForCheck();
const currentQuestion = this.quizService.currentQuestion();
return (this.quizService.quiz && this.quizService.quiz.sessionConfig.showResponseProgress) || //
(this.quizService.currentQuestion().timer && this.countdown === 0);
(currentQuestion && currentQuestion.timer && this.countdown === 0);
}
public getReadingConfirmationData(questionIndex: number): { base: number, absolute: number, percent: string } {
......@@ -210,12 +211,10 @@ export class QuizResultsComponent implements OnInit, OnDestroy {
}
}));
this._subscriptions.push(this.quizService.quizUpdateEmitter.subscribe(quiz => {
this._subscriptions.push(this.quizService.quizUpdateEmitter.subscribe(async quiz => {
if (!quiz) {
return;
}
this.hideProgressbarStyle = quiz.currentStartTimestamp > -1;
const storedSelectedQuestionIndex = parseInt(sessionStorage.getItem(StorageKey.CurrentQuestionIndex), 10);
if (!isNaN(storedSelectedQuestionIndex)) {
this.modifyVisibleQuestion(storedSelectedQuestionIndex);
......@@ -223,11 +222,10 @@ export class QuizResultsComponent implements OnInit, OnDestroy {
} else {
this.modifyVisibleQuestion(this.quizService.quiz.currentQuestionIndex);
}
this.attendeeService.restoreMembers().then(() => {
this.initData();
});
this.addFooterElements();
await this.initData();
this.addFooterElements();
this.cd.markForCheck();
}));
......@@ -308,32 +306,34 @@ export class QuizResultsComponent implements OnInit, OnDestroy {
this.isStarting = false;
}
private initData(): void {
private initData(): Promise<void> {
this.quizApiService.getQuizStatus(this.quizService.quiz.name).toPromise().then(currentStateData => {
return this.quizApiService.getQuizStatus(this.quizService.quiz.name).toPromise().then(currentStateData => {
if (currentStateData.status !== StatusProtocol.Success) {
this.router.navigate(['/']);
return;
}
if (currentStateData.payload.state === QuizState.Active) {
this.attendeeService.clearResponses();
this.quizService.quiz.currentQuestionIndex = -1;
this.router.navigate(['/quiz', 'flow', 'lobby']);
return;
}
const question = this.quizService.currentQuestion();
this.hideProgressbarStyle = currentStateData.payload.startTimestamp > -1;
if (!this.countdown) {
this.countdown = 0;
if (question.timer === 0 && !currentStateData.payload.readingConfirmationRequested && this.attendeeService.attendees.some(
nick => nick.responses[this.quizService.quiz.currentQuestionIndex].responseTime === -1)) {
this.showStartQuizButton = false;
this.hideProgressbarStyle = false;
this.showStopQuizButton = this.quizService.isOwner;
} else {
this.showStartQuizButton = this.quizService.isOwner && //
this.quizService.quiz.questionList.length > this.quizService.quiz.currentQuestionIndex + 1;
this.hideProgressbarStyle = false;
}
} else {
......@@ -343,16 +343,19 @@ export class QuizResultsComponent implements OnInit, OnDestroy {
})) {
console.log('QuizResultsComponent: Stopping countdown since all attendees have answered the current question');
this.countdown = 0;
this.hideProgressbarStyle = false;
this.showStartQuizButton = this.quizService.isOwner && this.quizService.quiz.questionList.length
> this.quizService.quiz.currentQuestionIndex + 1;
} else if (currentStateData.payload.readingConfirmationRequested) {
console.log('QuizResultsComponent: Stopping countdown since reading confirmation is requested');
this.countdown = 0;
this.hideProgressbarStyle = false;
this.showStartQuizButton = this.quizService.isOwner && this.quizService.quiz.questionList.length
> this.quizService.quiz.currentQuestionIndex + 1;
} else {
console.log('QuizResultsComponent: Countdown is proceeding');
this.hideProgressbarStyle = currentStateData.payload.startTimestamp > -1;
}
}
......@@ -427,15 +430,7 @@ export class QuizResultsComponent implements OnInit, OnDestroy {
this.cd.markForCheck();
}), this.messageQueue.subscribe(MessageProtocol.UpdatedResponse, payload => {
this.attendeeService.modifyResponse(payload);
if (this.attendeeService.attendees.every(nick => {
const val = nick.responses[this.quizService.quiz.currentQuestionIndex].value;
return typeof val === 'number' ? val > -1 : val.length > 0;
})) {
this.countdown = 0;
this.hideProgressbarStyle = false;
this.showStopQuizButton = false;
}
console.log('QuizResultsComponent: modify response data for nickname', payload.nickname);
this.cd.markForCheck();
}), this.messageQueue.subscribe(MessageProtocol.NextQuestion, payload => {
this.quizService.quiz.currentQuestionIndex = payload.nextQuestionIndex;
......
......@@ -78,7 +78,6 @@ export class ReadingConfirmationComponent implements OnInit, OnDestroy {
return;
}
this.attendeeService.restoreMembers();
this.questionIndex = this.quizService.quiz.currentQuestionIndex;
this.questionTextService.change(this.quizService.currentQuestion().questionText);
}));
......@@ -105,6 +104,10 @@ export class ReadingConfirmationComponent implements OnInit, OnDestroy {
private handleMessages(): void {
this._messageSubscriptions.push(...[
this.messageQueue.subscribe(MessageProtocol.NextQuestion, payload => {
this.quizService.quiz.currentQuestionIndex = payload.nextQuestionIndex;
sessionStorage.removeItem(StorageKey.CurrentQuestionIndex);
}),
this.messageQueue.subscribe(MessageProtocol.Start, payload => {
this.router.navigate(['/quiz', 'flow', 'voting']);
}), this.messageQueue.subscribe(MessageProtocol.UpdatedResponse, payload => {
......
......@@ -147,10 +147,6 @@ export class VotingComponent implements OnInit, OnDestroy {
public sendResponses(route?: string): void {
this.isSendingResponse = true;
if (this.countdown) {
this.countdown.onChange.unsubscribe();
this.countdown.stop();
}
this.router.navigate([
'/quiz',
'flow',
......@@ -181,7 +177,6 @@ export class VotingComponent implements OnInit, OnDestroy {
this._currentQuestion = this.quizService.currentQuestion();
this.initData();
this.attendeeService.restoreMembers();
this._subscriptions.push(this.questionTextService.eventEmitter.subscribe((value: string | Array<string>) => {
if (Array.isArray(value)) {
......@@ -225,6 +220,11 @@ export class VotingComponent implements OnInit, OnDestroy {
}
});
if (this.countdown) {
this.countdown.onChange.unsubscribe();
this.countdown.stop();
}
this._subscriptions.forEach(sub => sub.unsubscribe());
this._messageSubscriptions.forEach(id => this.messageQueue.unsubscribe(id));
}
......
......@@ -9,7 +9,7 @@ import { FooterBarService } from '../footer-bar/footer-bar.service';
import { QuizService } from '../quiz/quiz.service';
import { StorageService } from '../storage/storage.service';
@Injectable()
@Injectable({ providedIn: 'root' })
export class AttendeeService {
private _attendees: Array<MemberEntity> = [];
......@@ -85,15 +85,15 @@ export class AttendeeService {
return name === this._ownNick;
}
public modifyResponse(payload: { nickname: string, update: { [key: string]: any } }): void {
public modifyResponse(payload: { nickname: string, questionIndex: number, update: { [key: string]: any } }): void {
const member = this.getMember(payload.nickname);
if (!member) {
console.error('Cannot add member response. Member not found', payload.nickname);
console.error('AttendeeService: Cannot add member response. Member not found', payload.nickname);
return;
}
Object.keys(payload.update).forEach(updateKey => {
member.responses[this.quizService.quiz.currentQuestionIndex][updateKey] = payload.update[updateKey];
member.responses[payload.questionIndex][updateKey] = payload.update[updateKey];
});
}
......@@ -115,6 +115,13 @@ export class AttendeeService {
private loadData(): void {
this._ownNick = sessionStorage.getItem(StorageKey.CurrentNickName);
this.quizService.quizUpdateEmitter.subscribe(quiz => {
if (!quiz) {
return;
}
this.restoreMembers();
});
}
private getMember(nickname: string): MemberEntity {
......
......@@ -24,5 +24,8 @@ export class HeaderLabelService {
}
constructor(@Inject(PLATFORM_ID) private platformId: Object, private translateService: TranslateService) {
this.translateService.onLangChange.subscribe(() => {
this.headerLabel = this._headerLabel;
});
}
}
Markdown is supported
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