Apollo/apollo-frontend/src/app/minigame-biotrivia/minigame-biotrivia.component.ts
2021-03-12 21:38:38 +02:00

167 lines
4.9 KiB
TypeScript

import { Component, ElementRef, NgZone, OnInit, ViewChild, ViewChildren } from '@angular/core';
import { IgxRadioComponent, IgxRadioGroupDirective } from 'igniteui-angular';
import { Observable, Subject } from 'rxjs';
import { Answer, DbService, Question } from '../db.service';
@Component({
selector: 'app-minigame-biotrivia',
templateUrl: './minigame-biotrivia.component.html',
styleUrls: ['./minigame-biotrivia.component.scss']
})
export class MinigameBiotriviaComponent implements OnInit {
@ViewChildren('startDialog') startingElementRef;
@ViewChildren('ongoingDialog') ongoingElementRef;
@ViewChildren('endDialog') endingElementRef;
stage: 'starting' | 'starting-ongoing' | 'ongoing' | 'ongoing-ended' | 'ended' = 'starting';
questions: Question[];
displayError = false;
guessedQuestions = 0;
currQuestionN = 0;
currQuestion: Question;
currAnswers: string[];
answers: Array<{ question: Question, answer: string }> = [];
selectedAnswer = '';
isAnswered(): boolean {
return this.selectedAnswer !== '';
}
constructor(
private db: DbService
) { }
ngOnInit(): void {
}
submitAnswer(): void {
if (!this.isAnswered()) {
this.displayError = true;
return;
}
this.ongoingElementRef.first.nativeElement.style.position = 'absolute';
if (this.selectedAnswer === this.currQuestion.answer.correctChoise) this.guessedQuestions++;
this.answers.push({
answer: this.selectedAnswer,
question: this.currQuestion,
});
if (this.currQuestionN >= this.questions.length) {
this.stage = 'ongoing-ended';
setTimeout(() => {
this.endingElementRef.first.nativeElement.style.opacity = 0;
this.animateElements(
this.ongoingElementRef.first.nativeElement,
this.endingElementRef.first.nativeElement
// tslint:disable-next-line: deprecation
).subscribe(() => {
this.stage = 'ended';
});
}, 10);
return;
}
this.displayError = false;
this.selectedAnswer = '';
this.loadNextQuestion();
}
animateElements(el1: HTMLElement, el2: HTMLElement): Observable<void> {
const a = new Subject<void>();
el1.style.position = 'absolute';
el1.animate([
{
transform: 'translateX(0)',
opacity: 1,
},
{
transform: 'translateX(-100vh)',
opacity: 0,
},
], {
duration: 200,
easing: 'ease-in',
}).onfinish = () => {
el1.style.opacity = '0';
};
el2.animate([
{
transform: 'translateX(100vh)',
opacity: 0,
},
{
transform: 'translateX(0)',
opacity: 1,
},
], {
duration: 200,
easing: 'ease-out',
}).onfinish = () => {
el2.style.opacity = '1';
a.next();
};
return a;
}
loadQuestion(i: number): void {
this.currQuestion = this.questions[i];
this.currAnswers = this.shuffle(this.questions[i].answer.choises);
}
loadNextQuestion(): void {
this.loadQuestion(this.currQuestionN++);
}
startGame(): void {
if (this.stage !== 'starting') return;
const startingEl = this.startingElementRef.first.nativeElement as HTMLElement;
startingEl.style.position = 'absolute';
this.stage = 'starting-ongoing';
this.questions = this.db.getRandomQuestions(1, this.db.getRandomCategory());
this.loadNextQuestion();
setTimeout(() => {
const ongoingEl = this.ongoingElementRef.first.nativeElement as HTMLElement;
// tslint:disable-next-line: deprecation
this.animateElements(startingEl, ongoingEl).subscribe(() => {
this.stage = 'ongoing';
});
}, 20);
}
shuffle<T>(array: T[]): T[] {
let currentIndex = array.length;
let temporaryValue;
let randomIndex;
// While there remain elements to shuffle...
while (0 !== currentIndex) {
// Pick a remaining element...
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex -= 1;
// And swap it with the current element.
temporaryValue = array[currentIndex];
array[currentIndex] = array[randomIndex];
array[randomIndex] = temporaryValue;
}
return array;
}
getIncorrectAnswers(): { question: Question, answer: string }[] {
return this.answers.filter(v => v.answer === v.question.answer.correctChoise);
}
}