From 600479378ff83976c9d6cc0a4c2f09178f02ba9c Mon Sep 17 00:00:00 2001 From: Isahann Hanacleto Date: Mon, 14 Aug 2023 10:41:28 -0300 Subject: [PATCH 1/4] #35 fixing bugs --- .../correct-answer-window.component.ts | 45 +------- src/app/main-window/main-window.component.ts | 41 ++----- .../question-window.component.ts | 23 +--- .../score-window/score-window.component.ts | 35 +++--- .../wrong-answer-window.component.ts | 44 +------ src/service/app-storage.service.spec.ts | 16 +++ src/service/app-storage.service.ts | 109 ++++++++++++++++++ src/service/storage.service.ts | 17 ++- 8 files changed, 170 insertions(+), 160 deletions(-) create mode 100644 src/service/app-storage.service.spec.ts create mode 100644 src/service/app-storage.service.ts diff --git a/src/app/correct-answer-window/correct-answer-window.component.ts b/src/app/correct-answer-window/correct-answer-window.component.ts index 73d1fc4..22a05a0 100644 --- a/src/app/correct-answer-window/correct-answer-window.component.ts +++ b/src/app/correct-answer-window/correct-answer-window.component.ts @@ -1,10 +1,7 @@ import {Component, OnInit} from '@angular/core'; import {ActivatedRoute, Router} from "@angular/router"; import {PathsEnum} from "../../model/enums/PathsEnum"; -import {StorageService} from "../../service/storage.service"; -import {AppStorage, WeekScore} from "../../model/AppStorage"; -import * as moment from "moment"; -import {Moment} from "moment/moment"; +import {AppStorageService} from "../../service/app-storage.service"; @Component({ selector: 'app-correct-answer-window', @@ -20,15 +17,13 @@ export class CorrectAnswerWindowComponent implements OnInit { constructor( private readonly router: Router, private readonly route: ActivatedRoute, - private readonly storageService: StorageService + private readonly appStorageService: AppStorageService ) { this.questionScore = parseInt(this.route.snapshot.paramMap.get('points') ?? '0'); } public async ngOnInit(): Promise { - const quizCanBeAnswered: boolean = this.checkIfQuizCanBeAnswered(); - - if (!quizCanBeAnswered) { + if (!this.appStorageService.canQuizBeAnswered()) { await this.returnHome(); return; } @@ -37,43 +32,11 @@ export class CorrectAnswerWindowComponent implements OnInit { this.saveCurrentScore(); } - private checkIfQuizCanBeAnswered(): boolean { - const appStorage: AppStorage = this.storageService.get(); - const lastQuizResponseDate: string | null = appStorage.lastQuizResponseDate; - - if (lastQuizResponseDate === null) return true; - - const now: Moment = moment(); - const nextResponseMinimumDate: Moment = moment(lastQuizResponseDate).add(3, "hours"); - - return now.isSame(nextResponseMinimumDate) || now.isAfter(nextResponseMinimumDate); - } - public async returnHome(): Promise { await this.router.navigateByUrl(PathsEnum.HOME); } private saveCurrentScore(): void { - const appStorage: AppStorage = this.storageService.get(); - const currentWeek: number = moment().isoWeek(); - const newCurrentScoreMap: Map = new Map([[currentWeek, { - score: 0, - rightAnswers: 0, - wrongAnswers: 0, - }]]); - const currentWeekScoreMap: Map = appStorage.weekScoreMap ?? newCurrentScoreMap; - const currentWeekScore: WeekScore = currentWeekScoreMap.get(currentWeek)!; - - currentWeekScore.rightAnswers += 1; - currentWeekScore.score += this.questionScore; - currentWeekScoreMap.set(currentWeek, currentWeekScore!); - - this.storageService.save( - { - ...appStorage, - weekScoreMap: currentWeekScoreMap, - lastQuizResponseDate: moment().toISOString() - } - ) + this.appStorageService.saveAnswer(true, this.questionScore); } } diff --git a/src/app/main-window/main-window.component.ts b/src/app/main-window/main-window.component.ts index 4eb6023..ff42708 100644 --- a/src/app/main-window/main-window.component.ts +++ b/src/app/main-window/main-window.component.ts @@ -1,10 +1,10 @@ import {Component, OnInit} from '@angular/core'; -import {StorageService} from "../../service/storage.service"; import {Router} from "@angular/router"; import {PathsEnum} from "../../model/enums/PathsEnum"; import {AppStorage} from "../../model/AppStorage"; import * as moment from "moment"; import {Duration, Moment} from "moment"; +import {AppStorageService} from "../../service/app-storage.service"; @Component({ selector: 'app-main-window', @@ -19,38 +19,28 @@ export class MainWindowComponent implements OnInit { protected readonly PathsEnum = PathsEnum; constructor( - private readonly storageService: StorageService, - private readonly router: Router + private readonly router: Router, + private readonly appStorageService: AppStorageService ) { } public async ngOnInit(): Promise { - const appStorage: AppStorage = this.storageService.get(); - const lastQuizResponseDate: string | null = appStorage.lastQuizResponseDate; - - this.quizCanBeAnswered = this.checkIfQuizCanBeAnswered(lastQuizResponseDate); + this.quizCanBeAnswered = this.appStorageService.canQuizBeAnswered(); if (!this.quizCanBeAnswered) - this.startCountdown(lastQuizResponseDate); + this.startCountdown(); } public async redirectTo(route: PathsEnum): Promise { await this.router.navigateByUrl(route); } - private checkIfQuizCanBeAnswered(lastQuizResponseDate: string | null): boolean { - if (lastQuizResponseDate === null) return true; - - const now: Moment = moment(); - const nextResponseMinimumDate: Moment = moment(lastQuizResponseDate).add(3, "hours"); - - return now.isSame(nextResponseMinimumDate) || now.isAfter(nextResponseMinimumDate); - } + private startCountdown(): void { + const appStorage: AppStorage = this.appStorageService.retrieveAppStorage(); - private startCountdown(lastQuizResponseDate: string | null): void { - if (lastQuizResponseDate === null) return; + if (appStorage.lastQuizResponseDate === null) return; - const nextResponseMinimumDate: Moment = moment(lastQuizResponseDate).add(3, "hours"); + const nextResponseMinimumDate: Moment = moment(appStorage.lastQuizResponseDate).add(3, "hours"); new Promise(async (resolve): Promise => { while (true) { @@ -58,7 +48,7 @@ export class MainWindowComponent implements OnInit { if (now.isSame(nextResponseMinimumDate) || now.isAfter(nextResponseMinimumDate)) { this.quizCanBeAnswered = true; - this.clearLastAnsweredDate(); + this.appStorageService.clearLastAnsweredDate(); resolve(); break; } @@ -71,15 +61,4 @@ export class MainWindowComponent implements OnInit { } }); } - - private clearLastAnsweredDate(): void { - const appStorage: AppStorage = this.storageService.get(); - - this.storageService.save( - { - ...appStorage, - lastQuizResponseDate: null - } - ); - } } diff --git a/src/app/question-window/question-window.component.ts b/src/app/question-window/question-window.component.ts index a693658..cd6fd56 100644 --- a/src/app/question-window/question-window.component.ts +++ b/src/app/question-window/question-window.component.ts @@ -3,10 +3,7 @@ import {TriviaService} from "../../service/trivia.service"; import {TriviaResponse} from "../../model/TriviaResponse"; import {Router} from "@angular/router"; import {PathsEnum} from "../../model/enums/PathsEnum"; -import {AppStorage} from "../../model/AppStorage"; -import {Moment} from "moment"; -import * as moment from "moment/moment"; -import {StorageService} from "../../service/storage.service"; +import {AppStorageService} from "../../service/app-storage.service"; @Component({ selector: 'app-question-window', @@ -32,14 +29,12 @@ export class QuestionWindowComponent implements OnInit { constructor( private readonly triviaService: TriviaService, private readonly router: Router, - private readonly storageService: StorageService + private readonly appStorageService: AppStorageService ) { } public async ngOnInit(): Promise { - const quizCanBeAnswered: boolean = this.checkIfQuizCanBeAnswered(); - - if (!quizCanBeAnswered) { + if (!this.appStorageService.canQuizBeAnswered()) { await this.returnHome(); return; } @@ -48,18 +43,6 @@ export class QuestionWindowComponent implements OnInit { await this.loadQuestion(); } - private checkIfQuizCanBeAnswered(): boolean { - const appStorage: AppStorage = this.storageService.get(); - const lastQuizResponseDate: string | null = appStorage.lastQuizResponseDate; - - if (lastQuizResponseDate === null) return true; - - const now: Moment = moment(); - const nextResponseMinimumDate: Moment = moment(lastQuizResponseDate).add(3, "hours"); - - return now.isSame(nextResponseMinimumDate) || now.isAfter(nextResponseMinimumDate); - } - public async onClickAnswer(selectedAnswer: string) { this.selectedAnswer = selectedAnswer; await this.confirmAnswerSound.play(); diff --git a/src/app/score-window/score-window.component.ts b/src/app/score-window/score-window.component.ts index ca75ada..01b1764 100644 --- a/src/app/score-window/score-window.component.ts +++ b/src/app/score-window/score-window.component.ts @@ -1,11 +1,11 @@ import {Component, OnInit} from '@angular/core'; -import {StorageService} from "../../service/storage.service"; import {Router} from "@angular/router"; import {PathsEnum} from "../../model/enums/PathsEnum"; -import {AppStorage, WeekScore} from "../../model/AppStorage"; -import * as moment from "moment"; +import {WeekScore} from "../../model/AppStorage"; +import moment from "moment"; import {TemplateService} from "../../service/template.service"; import {TemplateEnum, WeekScoreTemplateParams} from "../../model/enums/Template"; +import {AppStorageService} from "../../service/app-storage.service"; @Component({ selector: 'app-score-window', @@ -22,26 +22,13 @@ export class ScoreWindowComponent implements OnInit { constructor( private readonly router: Router, - private readonly storageService: StorageService, - private readonly templateService: TemplateService + private readonly templateService: TemplateService, + private readonly appStorageService: AppStorageService ) { } public async ngOnInit(): Promise { - const currentWeek: number = moment().isoWeek(); - const appStorage: AppStorage = this.storageService.get(); - const currentWeekScoreMap: Map | undefined = appStorage.weekScoreMap; - - this.currentWeek = currentWeek; - - if (currentWeekScoreMap === undefined) return; - - const currentWeekScore: WeekScore = currentWeekScoreMap.get(currentWeek)!; - - this.currentScore = currentWeekScore.score; - this.rightAnswers = currentWeekScore.rightAnswers; - this.wrongAnswers = currentWeekScore.wrongAnswers; - + this.retrieveScore(); await this.assembleClipboardText(); } @@ -67,4 +54,14 @@ export class ScoreWindowComponent implements OnInit { this.clipboardText = await this.templateService.render(TemplateEnum.WEEK_SCORE, templateParams); } + + private retrieveScore(): void { + const currentWeek: number = moment().isoWeek(); + const currentWeekScore: WeekScore = this.appStorageService.retrieveScoreByWeek(currentWeek); + + this.currentScore = currentWeekScore.score; + this.rightAnswers = currentWeekScore.rightAnswers; + this.wrongAnswers = currentWeekScore.wrongAnswers; + this.currentWeek = currentWeek; + } } diff --git a/src/app/wrong-answer-window/wrong-answer-window.component.ts b/src/app/wrong-answer-window/wrong-answer-window.component.ts index a003a61..ee9fbc5 100644 --- a/src/app/wrong-answer-window/wrong-answer-window.component.ts +++ b/src/app/wrong-answer-window/wrong-answer-window.component.ts @@ -1,10 +1,7 @@ import {Component, OnInit} from '@angular/core'; import {ActivatedRoute, Router} from "@angular/router"; import {PathsEnum} from "../../model/enums/PathsEnum"; -import {StorageService} from "../../service/storage.service"; -import {AppStorage, WeekScore} from "../../model/AppStorage"; -import * as moment from "moment"; -import {Moment} from "moment"; +import {AppStorageService} from "../../service/app-storage.service"; @Component({ selector: 'app-wrong-answer-window', @@ -19,15 +16,13 @@ export class WrongAnswerWindowComponent implements OnInit { constructor( private readonly router: Router, private readonly route: ActivatedRoute, - private readonly storageService: StorageService + private readonly appStorageService: AppStorageService ) { this.correctAnswer = this.route.snapshot.paramMap.get('answer'); } public async ngOnInit(): Promise { - const quizCanBeAnswered: boolean = this.checkIfQuizCanBeAnswered(); - - if (!quizCanBeAnswered) { + if (!this.appStorageService.canQuizBeAnswered()) { await this.returnHome(); return; } @@ -36,42 +31,11 @@ export class WrongAnswerWindowComponent implements OnInit { this.saveCurrentScore(); } - private checkIfQuizCanBeAnswered(): boolean { - const appStorage: AppStorage = this.storageService.get(); - const lastQuizResponseDate: string | null = appStorage.lastQuizResponseDate; - - if (lastQuizResponseDate === null) return true; - - const now: Moment = moment(); - const nextResponseMinimumDate: Moment = moment(lastQuizResponseDate).add(3, "hours"); - - return now.isSame(nextResponseMinimumDate) || now.isAfter(nextResponseMinimumDate); - } - public async returnHome(): Promise { await this.router.navigateByUrl(PathsEnum.HOME); } private saveCurrentScore() { - const appStorage: AppStorage = this.storageService.get(); - const currentWeek: number = moment().isoWeek(); - const newCurrentScoreMap: Map = new Map([[currentWeek, { - score: 0, - rightAnswers: 0, - wrongAnswers: 0, - }]]); - const currentWeekScoreMap: Map = appStorage.weekScoreMap ?? newCurrentScoreMap; - const currentWeekScore: WeekScore = currentWeekScoreMap.get(currentWeek)!; - - currentWeekScore!.wrongAnswers += 1; - currentWeekScoreMap.set(currentWeek, currentWeekScore!); - - this.storageService.save( - { - ...appStorage, - weekScoreMap: currentWeekScoreMap, - lastQuizResponseDate: moment().toISOString() - } - ) + this.appStorageService.saveAnswer(false); } } diff --git a/src/service/app-storage.service.spec.ts b/src/service/app-storage.service.spec.ts new file mode 100644 index 0000000..11185f3 --- /dev/null +++ b/src/service/app-storage.service.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { AppStorageService } from './app-storage.service'; + +describe('AppStorageService', () => { + let service: AppStorageService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(AppStorageService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/src/service/app-storage.service.ts b/src/service/app-storage.service.ts new file mode 100644 index 0000000..896feeb --- /dev/null +++ b/src/service/app-storage.service.ts @@ -0,0 +1,109 @@ +import {Injectable} from '@angular/core'; +import {StorageService} from "./storage.service"; +import {AppStorage, WeekScore} from "../model/AppStorage"; +import moment, {Moment} from "moment/moment"; + +@Injectable({ + providedIn: 'root' +}) +export class AppStorageService { + + constructor( + private readonly storageService: StorageService + ) { + } + + public canQuizBeAnswered(): boolean { + const appStorage: AppStorage = this.retrieveAppStorage(); + const lastQuizResponseDate: string | null = appStorage.lastQuizResponseDate; + + if (lastQuizResponseDate === null) { + return true; + } else { + const now: Moment = moment(); + const nextResponseMinimumDate: Moment = moment(lastQuizResponseDate).add(3, "hours"); + + return now.isSame(nextResponseMinimumDate) || now.isAfter(nextResponseMinimumDate); + } + } + + public saveAnswer(correctAnswer: boolean, questionScore?: number | null): void { + const currentWeek: number = moment().isoWeek(); + const appStorage: AppStorage = this.retrieveAppStorage(); + const currentWeekScoreMap: Map = appStorage.weekScoreMap!; + const currentWeekScore: WeekScore = currentWeekScoreMap.get(currentWeek)!; + + if (correctAnswer) { + currentWeekScore.rightAnswers += 1; + currentWeekScore.score += questionScore!; + } else { + currentWeekScore.wrongAnswers += 1; + } + + currentWeekScoreMap.set(currentWeek, currentWeekScore!); + + this.storageService.save( + { + ...appStorage, + weekScoreMap: currentWeekScoreMap, + lastQuizResponseDate: moment().toISOString() + } + ) + } + + public clearLastAnsweredDate(): void { + const appStorage: AppStorage = this.retrieveAppStorage(); + + this.storageService.save( + { + ...appStorage, + lastQuizResponseDate: null + } + ); + } + + public retrieveScoreByWeek(currentWeek: number): WeekScore { + const appStorage: AppStorage = this.retrieveAppStorage(); + const currentWeekScoreMap: Map = appStorage.weekScoreMap!; + + if (currentWeekScoreMap.has(currentWeek)) { + return currentWeekScoreMap.get(currentWeek)!; + } else { + const newCurrentWeekScore: WeekScore = { + score: 0, + rightAnswers: 0, + wrongAnswers: 0 + } + + appStorage.weekScoreMap!.set(currentWeek, newCurrentWeekScore); + this.storageService.save(appStorage); + + return newCurrentWeekScore; + } + } + + public retrieveAppStorage(): AppStorage { + let appStorage: AppStorage | null = this.storageService.get(); + + if (appStorage === null) + appStorage = this.createNewAppStorage(); + + return appStorage; + } + + private createNewAppStorage(): AppStorage { + const currentWeek: number = moment().isoWeek(); + const appStorage = { + lastQuizResponseDate: null, + weekScoreMap: new Map([[currentWeek, { + score: 0, + rightAnswers: 0, + wrongAnswers: 0, + }]]) + } + + this.storageService.save(appStorage); + return appStorage; + } + +} diff --git a/src/service/storage.service.ts b/src/service/storage.service.ts index e50db91..72ae830 100644 --- a/src/service/storage.service.ts +++ b/src/service/storage.service.ts @@ -22,14 +22,13 @@ export class StorageService { this.localStorage.setItem(this.storageKey, encryptedObject); } - public get(): AppStorage { + public get(): AppStorage | null { const encryptedItem: string | null = this.localStorage.getItem(this.storageKey); - return (encryptedItem === null || encryptedItem === '') ? - { - currentScore: 0, - lastQuizResponseDate: null - } : - JSON.parse(this.decrypt(encryptedItem), this.reviver); + + if (encryptedItem === null || encryptedItem === '') + return null; + else + return JSON.parse(this.decrypt(encryptedItem), this.reviver); } private encrypt(value: string): string { @@ -43,7 +42,7 @@ export class StorageService { } private replacer(key: any, value: any) { - if(value instanceof Map) { + if (value instanceof Map) { return { dataType: 'Map', value: Array.from(value.entries()), // or with spread: value: [...value] @@ -54,7 +53,7 @@ export class StorageService { } private reviver(key: any, value: any) { - if(typeof value === 'object' && value !== null) { + if (typeof value === 'object' && value !== null) { if (value.dataType === 'Map') { return new Map(value.value); } From 104f994b391d97e9d988e86b31c59e667c413905 Mon Sep 17 00:00:00 2001 From: Isahann Hanacleto Date: Mon, 14 Aug 2023 13:42:27 -0300 Subject: [PATCH 2/4] #23 adding all scores --- .../score-window/score-window.component.html | 27 ++++++++++++++++--- .../score-window/score-window.component.sass | 14 ++++++++++ .../score-window/score-window.component.ts | 5 ++++ 3 files changed, 42 insertions(+), 4 deletions(-) diff --git a/src/app/score-window/score-window.component.html b/src/app/score-window/score-window.component.html index c89da8d..621704e 100644 --- a/src/app/score-window/score-window.component.html +++ b/src/app/score-window/score-window.component.html @@ -5,9 +5,9 @@
- - - + + +
@@ -17,8 +17,27 @@
+
+ +
    +
  • + +
    + 🗓 Week {{keyValue.key}} +
      +
    • 🟩 {{keyValue.value.rightAnswers}} right answers
    • +
    • 🟥 {{keyValue.value.wrongAnswers}} wrong answers
    • +
    • 🟦 {{keyValue.value.score}} total points
    • +
    +
    +
    +
  • +
+
+
- +
diff --git a/src/app/score-window/score-window.component.sass b/src/app/score-window/score-window.component.sass index 732dcad..50540f8 100644 --- a/src/app/score-window/score-window.component.sass +++ b/src/app/score-window/score-window.component.sass @@ -45,3 +45,17 @@ color: green font-weight: bold margin: 5px + + &_previous-scores + width: 100% + display: flex + flex-direction: column + align-items: center + justify-content: center + + .tree-view + margin: 5px + width: 200px + max-height: 200px + overflow: auto + diff --git a/src/app/score-window/score-window.component.ts b/src/app/score-window/score-window.component.ts index 01b1764..b3500a5 100644 --- a/src/app/score-window/score-window.component.ts +++ b/src/app/score-window/score-window.component.ts @@ -17,6 +17,7 @@ export class ScoreWindowComponent implements OnInit { public currentWeek: number = 0; public rightAnswers: number = 0; public wrongAnswers: number = 0; + public previousScores: Map | null = null; public clipboardText: string = ''; public displayClipboardMessage: boolean = false; @@ -58,7 +59,11 @@ export class ScoreWindowComponent implements OnInit { private retrieveScore(): void { const currentWeek: number = moment().isoWeek(); const currentWeekScore: WeekScore = this.appStorageService.retrieveScoreByWeek(currentWeek); + const previousScoresMap: Map = this.appStorageService.retrieveAppStorage().weekScoreMap!; + // previousScoresMap.delete(currentWeek); + + this.previousScores = previousScoresMap; this.currentScore = currentWeekScore.score; this.rightAnswers = currentWeekScore.rightAnswers; this.wrongAnswers = currentWeekScore.wrongAnswers; From 625898bf62d79cbd7ed23e0c156e2d0d548803de Mon Sep 17 00:00:00 2001 From: Isahann Hanacleto Date: Mon, 14 Aug 2023 13:45:06 -0300 Subject: [PATCH 3/4] v1.2.1 --- package.json | 2 +- src/app/about-window/about-window.component.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index cc80d9b..bd0594d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "xpquiz.github.io", - "version": "1.2.0", + "version": "1.2.1", "scripts": { "ng": "ng", "start": "ng serve", diff --git a/src/app/about-window/about-window.component.html b/src/app/about-window/about-window.component.html index f9ba584..6faba02 100644 --- a/src/app/about-window/about-window.component.html +++ b/src/app/about-window/about-window.component.html @@ -1,7 +1,7 @@
- + From 8fd22fbd567449e7d59f941bb5e71d2d7e831589 Mon Sep 17 00:00:00 2001 From: Isahann Hanacleto Date: Mon, 14 Aug 2023 13:46:11 -0300 Subject: [PATCH 4/4] Fix --- src/app/score-window/score-window.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/score-window/score-window.component.ts b/src/app/score-window/score-window.component.ts index b3500a5..f1936e9 100644 --- a/src/app/score-window/score-window.component.ts +++ b/src/app/score-window/score-window.component.ts @@ -61,7 +61,7 @@ export class ScoreWindowComponent implements OnInit { const currentWeekScore: WeekScore = this.appStorageService.retrieveScoreByWeek(currentWeek); const previousScoresMap: Map = this.appStorageService.retrieveAppStorage().weekScoreMap!; - // previousScoresMap.delete(currentWeek); + previousScoresMap.delete(currentWeek); this.previousScores = previousScoresMap; this.currentScore = currentWeekScore.score;