diff --git a/src/app/admin/dialog-template/dialog-template.component.html b/src/app/admin/dialog-template/dialog-template.component.html deleted file mode 100644 index 0b050c59..00000000 --- a/src/app/admin/dialog-template/dialog-template.component.html +++ /dev/null @@ -1,15 +0,0 @@ -
-

Informasjon:

-
-
-

Navn på iterasjon: {{ data.iterationName }}

-
-
-

Tidspunktet iterasjonen ble lagd: {{ data.timeCreated }}

-
-
-

Antall (nye) bilder i treningssettet: {{ data.imageCount }}

-
-
-

(Trykk utenfor boksen for å lukke)

-
diff --git a/src/app/admin/dialog-template/dialog-template.component.scss b/src/app/admin/dialog-template/dialog-template.component.scss deleted file mode 100644 index 7bba162e..00000000 --- a/src/app/admin/dialog-template/dialog-template.component.scss +++ /dev/null @@ -1,23 +0,0 @@ -.dialog-title { - font-weight: bold; - font-size: 35px; - text-align: center; -} - -.content { - display: flex; - justify-content: center; - width: 625px; - height: 50px; - font-size: 20px; -} - -.mat-dialog-container { - border-radius: 56px; - width: 698px; - height: 246px; - - display: flex; - align-items: center; - justify-content: center; -} diff --git a/src/app/admin/dialog/dialog.component.html b/src/app/admin/dialog/dialog.component.html new file mode 100644 index 00000000..0e63ba59 --- /dev/null +++ b/src/app/admin/dialog/dialog.component.html @@ -0,0 +1,11 @@ +
+

Informasjon

+ +
+

Navn på iterasjon: {{ data.iterationName }}

+

Tidspunktet iterasjonen ble lagd: {{ data.timeCreated }}

+

Antall (nye) bilder i treningssettet: {{ data.imageCount }}

+
+ + +
diff --git a/src/app/admin/dialog/dialog.component.scss b/src/app/admin/dialog/dialog.component.scss new file mode 100644 index 00000000..80010334 --- /dev/null +++ b/src/app/admin/dialog/dialog.component.scss @@ -0,0 +1,29 @@ +.dialog-content { + text-align: center; + padding: 20px; + max-width: 400px; + margin: auto; +} + +.dialog-title { + font-size: 24px; + font-weight: bold; + margin-bottom: 20px; +} + +.dialog-body p { + font-size: 16px; + margin: 10px 0; + font-weight: 500; +} + +.dialog-body b { + font-weight: 900; +} + +.dialog-footer { + font-size: 14px; + color: grey; + margin-top: 20px; + font-style: italic; +} diff --git a/src/app/admin/dialog-template/dialog-template.component.ts b/src/app/admin/dialog/dialog.component.ts similarity index 74% rename from src/app/admin/dialog-template/dialog-template.component.ts rename to src/app/admin/dialog/dialog.component.ts index ba36c64c..f124f130 100644 --- a/src/app/admin/dialog-template/dialog-template.component.ts +++ b/src/app/admin/dialog/dialog.component.ts @@ -5,11 +5,11 @@ import { DialogData } from '@/app/shared/models/interfaces'; @Component({ selector: 'app-dialog-template', - templateUrl: './dialog-template.component.html', - styleUrls: ['./dialog-template.component.scss'], + templateUrl: './dialog.component.html', + styleUrls: ['./dialog.component.scss'], standalone: true, imports: [CdkScrollable, MatDialogContent, MatDialogTitle], }) -export class DialogTemplateComponent { +export class DialogComponent { constructor(@Inject(MAT_DIALOG_DATA) public data: DialogData) {} } diff --git a/src/app/admin/info-dialog/info-dialog.component.ts b/src/app/admin/info-dialog/info-dialog.component.ts index fd320b67..fb67ffc2 100644 --- a/src/app/admin/info-dialog/info-dialog.component.ts +++ b/src/app/admin/info-dialog/info-dialog.component.ts @@ -1,6 +1,6 @@ import { Component } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; -import { DialogTemplateComponent } from './../dialog-template/dialog-template.component'; +import { DialogComponent } from '../dialog/dialog.component'; import { ErrorLogDialogComponent } from '../error-dialog/error-dialog.component'; import { LogData } from '@/app/shared/models/backend-interfaces'; @@ -14,7 +14,7 @@ export class InfoDialogComponent { constructor(public dialog: MatDialog) {} openDialog(iterName: string, time: string, imgCount: string) { - this.dialog.open(DialogTemplateComponent, { + this.dialog.open(DialogComponent, { data: { iterationName: iterName, timeCreated: time, @@ -23,10 +23,12 @@ export class InfoDialogComponent { }); } - openErrorLog(logDataArray: LogData[]) { +openErrorLog(logDataArray: LogData[]) { - this.dialog.open(ErrorLogDialogComponent, { - data: logDataArray, - }); - } + this.dialog.open(ErrorLogDialogComponent, { + data: logDataArray, + }); } + +} + diff --git a/src/app/admin/info-page/info-page.component.html b/src/app/admin/info-page/info-page.component.html new file mode 100644 index 00000000..c293ba8d --- /dev/null +++ b/src/app/admin/info-page/info-page.component.html @@ -0,0 +1,16 @@ +

Administrative handlinger

+
+
+ +

+ +

+ +

+ +
+
+ +
+ +
diff --git a/src/app/admin/info/info.component.scss b/src/app/admin/info-page/info-page.component.scss similarity index 92% rename from src/app/admin/info/info.component.scss rename to src/app/admin/info-page/info-page.component.scss index 053fd3f9..c928b4db 100644 --- a/src/app/admin/info/info.component.scss +++ b/src/app/admin/info-page/info-page.component.scss @@ -39,7 +39,7 @@ p { } .btn-group button:first-child { - background-color: #c78bde; + background-color: #734f81; margin-top: 2vh; border: 1px solid #96a7b1; } diff --git a/src/app/admin/info/info.component.ts b/src/app/admin/info-page/info-page.component.ts similarity index 62% rename from src/app/admin/info/info.component.ts rename to src/app/admin/info-page/info-page.component.ts index 6fcb496c..4ddbdca8 100644 --- a/src/app/admin/info/info.component.ts +++ b/src/app/admin/info-page/info-page.component.ts @@ -2,7 +2,7 @@ import { Component } from '@angular/core'; import { Router } from '@angular/router'; import { LoginService } from '../login.service'; import { MatSnackBar } from '@angular/material/snack-bar'; -import { InfoDialogComponent } from './../info-dialog/info-dialog.component'; +import { InfoDialogComponent } from '../info-dialog/info-dialog.component'; import { PairingService } from '../../game/services/pairing.service'; import { MatButton } from '@angular/material/button'; import { LogData, StatusData } from '@/app/shared/models/backend-interfaces'; @@ -10,12 +10,12 @@ import { LoggingService } from '../../game/services/logging.service'; @Component({ selector: 'app-info', - templateUrl: './info.component.html', - styleUrls: ['./info.component.scss'], + templateUrl: './info-page.component.html', + styleUrls: ['./info-page.component.scss'], standalone: true, imports: [MatButton], }) -export class InfoComponent { +export class InfoPageComponent { datasetString = 'Nullstill treningssett til originalen'; datasetBool = false; retrainString = 'Tren maskinlæringsmodellen'; @@ -34,49 +34,7 @@ export class InfoComponent { private pairing: PairingService, private loggingService: LoggingService ) {} - - revertDataset() { - let msg = ''; - if (this.datasetBool) { - this.resetDatasetValues(); - this.loginService.revertDataset().subscribe( - () => { - this.openSnackBar('Suksess! Treningssett tilbakestilles (dette kan ta noen minutter)'); - }, - () => { - msg = this.errorMsg; - this.openSnackBar(msg); - } - ); - this.resetDatasetValues(); - } else { - this.resetHighScoreValues(); - this.resetRetrainValues(); - this.setDatasetValues(); - } - } - - retrain() { - let msg = ''; - if (this.retrainBool) { - this.resetDatasetValues(); - this.loginService.retrain().subscribe( - () => { - this.openSnackBar('Suksess! Modellen blir trent (dette kan ta noen minutter)'); - }, - () => { - msg = this.errorMsg; - this.openSnackBar(msg); - } - ); - this.resetRetrainValues(); - } else { - this.resetDatasetValues(); - this.resetHighScoreValues(); - this.setRetrainValues(); - } - } - + clearHighScore() { let msg = ''; if (this.highScoreBool) { @@ -93,7 +51,6 @@ export class InfoComponent { this.resetHighScoreValues(); } else { this.resetDatasetValues(); - this.resetRetrainValues(); this.setHighScoreValues(); } } @@ -103,37 +60,16 @@ export class InfoComponent { this.highScoreBool = false; } - resetRetrainValues() { - this.retrainString = 'Tren maskinlæringsmodellen'; - this.retrainBool = false; - } - resetDatasetValues() { this.datasetString = 'Nullstill treningssett til originalen'; this.datasetBool = false; } - resetAll() { - this.resetHighScoreValues(); - this.resetRetrainValues(); - this.resetDatasetValues(); - } - setHighScoreValues() { this.highScoreString = this.secondMsg; this.highScoreBool = true; } - setRetrainValues() { - this.retrainString = this.secondMsg; - this.retrainBool = true; - } - - setDatasetValues() { - this.datasetString = this.secondMsg; - this.datasetBool = true; - } - signOut() { this.loginService.signOut().subscribe( () => { @@ -148,7 +84,6 @@ export class InfoComponent { } getInformation() { - this.resetAll(); this.loginService.getStatus().subscribe( (res: StatusData) => { const name = res.CV_iteration_name; @@ -192,12 +127,4 @@ export class InfoComponent { duration: 6000, }); } - - pair(id: string) { - this.pairing.setPairID(id); - } - - getPairID() { - return this.pairing.getPairID(); - } } diff --git a/src/app/admin/info/info.component.html b/src/app/admin/info/info.component.html deleted file mode 100644 index 9efd216f..00000000 --- a/src/app/admin/info/info.component.html +++ /dev/null @@ -1,29 +0,0 @@ -

Administrative handlinger

-

Advarsel!

-

Før du utfører en administrativ handling, vær helt sikker på at du vil gjøre den.

-

Hvis en handling først gjennomføres, vil du IKKE være i stand til å gjøre om på den.

-
- -

- -

- -

- -
-
-
-
- - -

- -

-
-
-

-
- -
diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 755fd735..53398f9b 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -3,7 +3,7 @@ import { Subject } from 'rxjs'; import { Router } from '@angular/router'; import { MatDialog } from '@angular/material/dialog'; import { RouterOutlet } from '@angular/router'; -import { IdleTimeoutComponent } from './game/idle-timeout/idle-timeout.component'; +import { IdleTimeoutComponent } from './game/shared-components/idle-timeout/idle-timeout.component'; import { routeTransitionAnimations } from './route-transition-animations'; import { environment } from '../environments/environment'; import { GameStateService } from './game/services/game-state-service'; diff --git a/src/app/game/game-draw/game-draw.component.ts b/src/app/game/game-draw/game-draw.component.ts index f9fadb96..405e7be6 100644 --- a/src/app/game/game-draw/game-draw.component.ts +++ b/src/app/game/game-draw/game-draw.component.ts @@ -22,7 +22,7 @@ import { TranslationService } from '@/app/core/translation.service'; import { TranslatePipe } from '@/app/core/translation.pipe'; import { GameStateService } from '../services/game-state-service'; import { CustomColorsIO } from '@/app/shared/customColors'; -import { SpeechBubbleComponent } from '../speech-bubble/speech-bubble.component'; +import { SpeechBubbleComponent } from '../shared-components/speech-bubble/speech-bubble.component'; import { OAvatarComponent } from '@/assets/avatars/o-avatar/o-avatar.component'; import { IAvatarComponent } from '@/assets/avatars/i-avatar/i-avatar.component'; import { ViewChild } from '@angular/core'; @@ -250,6 +250,11 @@ export class GameDrawComponent implements OnInit, OnDestroy { if (this.gameStateService.isSingleplayer() && !this.drawingService.hasAddedSingleplayerResult) { let res; let hasWon = false; + + if (this.isBlankImage) { + return; + } + if (!this.drawingService.pred) { res = this.drawingService.createDefaultResult(); } else { @@ -338,12 +343,13 @@ export class GameDrawComponent implements OnInit, OnDestroy { if (sortedCertaintyArr && sortedCertaintyArr.length > 1) { const guess = sortedCertaintyArr[0].label; this.AI_GUESS = guess === this.guessWord ? sortedCertaintyArr[1].label : guess; + } else if (sortedCertaintyArr[0].label === "blank") { + this.AI_GUESS = ""; } } handleSinglePlayerClassification(dataUrl: string, croppedCoordinates: number[]) { const formData: FormData = this.createFormData(dataUrl); - this.drawingService.classify(formData).subscribe((res) => { const sortedCertaintyArr = this.sortOnCertainty(res); this.updateAiGuess(sortedCertaintyArr); @@ -375,7 +381,6 @@ export class GameDrawComponent implements OnInit, OnDestroy { } classify(isMultiplayer = false) { - //TODO: rename? this.drawnPixelsAtLastGuess = this.drawnPixels; const b64Image = this.canvas.nativeElement.toDataURL('image/png'); const croppedCoordinates: number[] = this.imageService.crop( diff --git a/src/app/game/game-intermediate-result/game-drawing-feedback/game-drawing-feedback.component.ts b/src/app/game/game-intermediate-result/game-drawing-feedback/game-drawing-feedback.component.ts index 94f5d311..3d8eca6f 100644 --- a/src/app/game/game-intermediate-result/game-drawing-feedback/game-drawing-feedback.component.ts +++ b/src/app/game/game-intermediate-result/game-drawing-feedback/game-drawing-feedback.component.ts @@ -1,5 +1,5 @@ import { TranslatePipe } from '@/app/core/translation.pipe'; -import { SpeechBubbleComponent } from '../../speech-bubble/speech-bubble.component'; +import { SpeechBubbleComponent } from '../../shared-components/speech-bubble/speech-bubble.component'; import { Component, OnInit } from '@angular/core'; import { ArrowAlignment, PointerSide } from '@/app/shared/models/interfaces'; import { CustomColorsIO } from '../../../shared/customColors'; diff --git a/src/app/game/game-intermediate-result/game-example-drawings/correct-guess/correct-guess.component.ts b/src/app/game/game-intermediate-result/game-example-drawings/correct-guess/correct-guess.component.ts index 2ef3a556..b9edf267 100644 --- a/src/app/game/game-intermediate-result/game-example-drawings/correct-guess/correct-guess.component.ts +++ b/src/app/game/game-intermediate-result/game-example-drawings/correct-guess/correct-guess.component.ts @@ -1,5 +1,5 @@ import { Component, OnInit } from '@angular/core'; -import { SpeechBubbleComponent } from '@/app/game/speech-bubble/speech-bubble.component'; +import { SpeechBubbleComponent } from '@/app/game/shared-components/speech-bubble/speech-bubble.component'; import { OAvatarComponent } from '@/assets/avatars/o-avatar/o-avatar.component'; import { ArrowAlignment, PointerSide } from '@/app/shared/models/interfaces'; import { CustomColorsIO } from '@/app/shared/customColors'; diff --git a/src/app/game/game-intermediate-result/game-example-drawings/game-example-drawings.component.ts b/src/app/game/game-intermediate-result/game-example-drawings/game-example-drawings.component.ts index 15622316..c208f519 100644 --- a/src/app/game/game-intermediate-result/game-example-drawings/game-example-drawings.component.ts +++ b/src/app/game/game-intermediate-result/game-example-drawings/game-example-drawings.component.ts @@ -1,5 +1,5 @@ import { Component, OnInit } from '@angular/core'; -import { SpeechBubbleComponent } from '../../speech-bubble/speech-bubble.component'; +import { SpeechBubbleComponent } from '../../shared-components/speech-bubble/speech-bubble.component'; import { TranslatePipe } from '@/app/core/translation.pipe'; import { DrawingService } from '../../services/drawing.service'; import { OAvatarComponent } from '@/assets/avatars/o-avatar/o-avatar.component'; diff --git a/src/app/game/game-intermediate-result/game-example-drawings/wrong-guess/wrong-guess.component.ts b/src/app/game/game-intermediate-result/game-example-drawings/wrong-guess/wrong-guess.component.ts index 86e4c516..58b255c6 100644 --- a/src/app/game/game-intermediate-result/game-example-drawings/wrong-guess/wrong-guess.component.ts +++ b/src/app/game/game-intermediate-result/game-example-drawings/wrong-guess/wrong-guess.component.ts @@ -1,5 +1,5 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; -import { SpeechBubbleComponent } from '@/app/game/speech-bubble/speech-bubble.component'; +import { SpeechBubbleComponent } from '@/app/game/shared-components/speech-bubble/speech-bubble.component'; import { OAvatarComponent } from '@/assets/avatars/o-avatar/o-avatar.component'; import { ArrowAlignment, Certainty, PointerSide } from '@/app/shared/models/interfaces'; import { CustomColorsIO } from '@/app/shared/customColors'; @@ -40,7 +40,6 @@ export class WrongGuessComponent implements OnInit, OnDestroy { ngOnInit(): void { this.label = this.drawingService.lastResult.word; this.updateAiGuess(this.drawingService.sortedCertainty); - if (this.gameStateService.isSingleplayer()) { this.exampleDrawings = this.exampleDrawingService.getExampleDrawings(2); this.getSingleplayerExamples(); @@ -55,6 +54,9 @@ export class WrongGuessComponent implements OnInit, OnDestroy { } getSingleplayerExamples() { + if (this.guess === "") { + return + } this.aiGuessSubscription.add( this.exampleDrawingService .getExampleDrawingsFromLabel(2, this.guess, this.translationService.getCurrentLang()) diff --git a/src/app/game/game-intermediate-result/game-intermediate-result-footer/game-intermediate-result-footer.component.html b/src/app/game/game-intermediate-result/game-intermediate-result-footer/game-intermediate-result-footer.component.html index ebcb6175..69b73b6b 100644 --- a/src/app/game/game-intermediate-result/game-intermediate-result-footer/game-intermediate-result-footer.component.html +++ b/src/app/game/game-intermediate-result/game-intermediate-result-footer/game-intermediate-result-footer.component.html @@ -1,11 +1,13 @@ diff --git a/src/app/game/game-intermediate-result/game-intermediate-result-footer/game-intermediate-result-footer.component.ts b/src/app/game/game-intermediate-result/game-intermediate-result-footer/game-intermediate-result-footer.component.ts index ebd63799..32fa1880 100644 --- a/src/app/game/game-intermediate-result/game-intermediate-result-footer/game-intermediate-result-footer.component.ts +++ b/src/app/game/game-intermediate-result/game-intermediate-result-footer/game-intermediate-result-footer.component.ts @@ -6,18 +6,27 @@ import { MultiplayerService } from '../../services/multiplayer.service'; import { GameStateService } from '../../services/game-state-service'; import { CustomButtonComponent } from '../../shared-components/custom-button/custom-button.component'; import { ButtonStyleClass } from '@/app/shared/buttonStyles'; +import { animate, state, style, transition, trigger } from '@angular/animations'; @Component({ selector: 'app-game-intermediate-result-footer', standalone: true, imports: [TranslatePipe, MatIcon, CustomButtonComponent], templateUrl: './game-intermediate-result-footer.component.html', styleUrl: './game-intermediate-result-footer.component.scss', + animations: [ + trigger('makeVisible', [ + state('hidden', style({ opacity: 0 })), + state('visible', style({ opacity: 1 })), + transition('hidden => visible', animate('1s')), + ]), + ] }) export class GameIntermediateResultFooterComponent implements OnInit { buttonTextKey = ''; waitingForPlayerState = 'WAITING'; isWaitingForPlayer = false; - + progressionButton = 'hidden'; + buttonsAreDisabled = true; buttonStyleClass = ButtonStyleClass.forward; constructor(private gameStateService: GameStateService, private multiplayerService: MultiplayerService) {} @@ -25,8 +34,12 @@ export class GameIntermediateResultFooterComponent implements OnInit { ngOnInit(): void { this.buttonTextKey = this.getButtonTextKey(); - if (this.gameStateService.isSingleplayer()) return; + this.startAnimation(); + + if (this.gameStateService.isSingleplayer()) { + return; + } this.isWaitingForPlayer = true; // default in multiplayer set to true this.multiplayerService.stateInfo$.subscribe((res) => { if (res.ready) { @@ -72,4 +85,11 @@ export class GameIntermediateResultFooterComponent implements OnInit { } return 'button-container'; } + + startAnimation() { + setTimeout(() => { + this.progressionButton = 'visible'; + this.buttonsAreDisabled = false; + }, 800); + }; } diff --git a/src/app/game/game-multiplayer/lobby/lobby.component.html b/src/app/game/game-multiplayer/lobby/lobby.component.html index b2f3d15a..6b5e2def 100644 --- a/src/app/game/game-multiplayer/lobby/lobby.component.html +++ b/src/app/game/game-multiplayer/lobby/lobby.component.html @@ -7,13 +7,10 @@ - group + diff --git a/src/app/game/game-multiplayer/lobby/lobby.component.ts b/src/app/game/game-multiplayer/lobby/lobby.component.ts index d717167d..53cb173e 100644 --- a/src/app/game/game-multiplayer/lobby/lobby.component.ts +++ b/src/app/game/game-multiplayer/lobby/lobby.component.ts @@ -8,7 +8,7 @@ import { MatProgressSpinner } from '@angular/material/progress-spinner'; import { TranslationService } from '@/app/core/translation.service'; import { TranslatePipe } from '@/app/core/translation.pipe'; import { GameStateService } from '../../services/game-state-service'; -import { SpeechBubbleComponent } from '../../speech-bubble/speech-bubble.component'; +import { SpeechBubbleComponent } from '../../shared-components/speech-bubble/speech-bubble.component'; import { CustomColorsIO } from '@/app/shared/customColors'; import { PointerSide, ArrowAlignment } from '@/app/shared/models/interfaces'; import { IAvatarComponent } from '@/assets/avatars/i-avatar/i-avatar.component'; diff --git a/src/app/game/game-pick-difficulty/game-pick-difficulty.component.html b/src/app/game/game-pick-difficulty/game-pick-difficulty.component.html index 5e5afbc0..3cb5eeaf 100644 --- a/src/app/game/game-pick-difficulty/game-pick-difficulty.component.html +++ b/src/app/game/game-pick-difficulty/game-pick-difficulty.component.html @@ -38,7 +38,7 @@ [disabled]="buttonsAreDisabled" [buttonStyle]="buttonStyleClass" [buttonText]="'EASY_BUTTON' | translate" - (click)="startDrawing('easy')" + (buttonClicked)="startDrawing('easy')" alt="" aria-label="" > @@ -54,7 +54,7 @@ [disabled]="buttonsAreDisabled" [buttonStyle]="buttonStyleClass" [buttonText]="'MEDIUM_BUTTON' | translate" - (click)="startDrawing('medium')" + (buttonClicked)="startDrawing('medium')" alt="" aria-label="" > @@ -70,7 +70,7 @@ [disabled]="buttonsAreDisabled" [buttonStyle]="buttonStyleClass" [buttonText]="'HARD_BUTTON' | translate" - (click)="startDrawing('hard')" + (buttonClicked)="startDrawing('hard')" alt="" aria-label="" > diff --git a/src/app/game/game-pick-difficulty/game-pick-difficulty.component.ts b/src/app/game/game-pick-difficulty/game-pick-difficulty.component.ts index 657f0979..9205aecf 100644 --- a/src/app/game/game-pick-difficulty/game-pick-difficulty.component.ts +++ b/src/app/game/game-pick-difficulty/game-pick-difficulty.component.ts @@ -8,7 +8,7 @@ import { TranslationService } from '@/app/core/translation.service'; import { TranslatePipe } from '@/app/core/translation.pipe'; import { GameLevelConfig, GAMESTATE } from '@/app/shared/models/interfaces'; import { GameStateService } from '../services/game-state-service'; -import { SpeechBubbleComponent } from '../../game/speech-bubble/speech-bubble.component'; +import { SpeechBubbleComponent } from '../shared-components/speech-bubble/speech-bubble.component'; import { CustomColorsIO } from '../../shared/customColors'; import { ArrowAlignment, PointerSide } from '@/app/shared/models/interfaces'; import { trigger, state, style, animate, transition } from '@angular/animations'; @@ -99,11 +99,16 @@ export class GamePickDifficultyComponent implements OnInit { { delay: 350, action: () => { - this.stateButtons = 'visible'; - this.buttonsAreDisabled = false; this.stateFirstBubbleI = 'visible'; }, }, + { + delay: 450, + action: () => { + this.stateButtons = 'visible'; + this.buttonsAreDisabled = false; + } + } ]; let totalDelay = 0; steps.forEach((step) => { diff --git a/src/app/game/game-result/game-result.component.html b/src/app/game/game-result/game-result.component.html index 01faf516..8196252b 100644 --- a/src/app/game/game-result/game-result.component.html +++ b/src/app/game/game-result/game-result.component.html @@ -106,20 +106,21 @@

-
+
diff --git a/src/app/game/game-result/game-result.component.ts b/src/app/game/game-result/game-result.component.ts index 407be41b..291400c8 100644 --- a/src/app/game/game-result/game-result.component.ts +++ b/src/app/game/game-result/game-result.component.ts @@ -18,7 +18,7 @@ import { // ... } from '@angular/animations'; import { HighscoreData } from '@/app/shared/models/backend-interfaces'; -import { SpeechBubbleComponent } from '../speech-bubble/speech-bubble.component'; +import { SpeechBubbleComponent } from '../shared-components/speech-bubble/speech-bubble.component'; import { CustomColorsIO } from '@/app/shared/customColors'; import { MatIcon } from '@angular/material/icon'; import { GameStateService } from '../services/game-state-service'; @@ -72,12 +72,14 @@ export class GameResultComponent implements OnInit, OnDestroy { IState = 'hidden'; OState = 'hidden'; + buttonState = 'hidden'; + buttonsAreDisabled = true; CustomColorsIO = CustomColorsIO; PointerSide = PointerSide; ArrowAlignment = ArrowAlignment; - homeButtonStyleClass = ButtonStyleClass.home; + homeButtonStyleClass = ButtonStyleClass.end; playAgainButtonStyleClass = ButtonStyleClass.playAgain; constructor( @@ -177,12 +179,14 @@ export class GameResultComponent implements OnInit, OnDestroy { } playAgain(): void { + this.gameStateService.restartGame(); + this.drawingService.clearState(); if (this.ismultiplayer) { this.multiplayerService.clearState(); + this.router.navigateByUrl('/welcome').then(() => { + this.router.navigateByUrl('/playgame/multiplayer'); + }); } - - this.drawingService.clearState(); - this.gameStateService.restartGame(); } endGame(): void { @@ -200,5 +204,9 @@ export class GameResultComponent implements OnInit, OnDestroy { setTimeout(() => { this.OState = 'visible'; }, 1500); + setTimeout(() => { + this.buttonState = 'visible'; + this.buttonsAreDisabled = false; + }, 3000); } } diff --git a/src/app/game/game-word-to-draw/game-word-to-draw.component.html b/src/app/game/game-word-to-draw/game-word-to-draw.component.html index 070ba1fc..67d30026 100644 --- a/src/app/game/game-word-to-draw/game-word-to-draw.component.html +++ b/src/app/game/game-word-to-draw/game-word-to-draw.component.html @@ -64,7 +64,7 @@

{{ label | uppercase }}

[buttonStyle]="forwardButtonStyleClass" [buttonText]="'DRAW_BUTTON' | translate" (keydown)="toDrawingBoard()" - (click)="toDrawingBoard()" + (buttonClicked)="toDrawingBoard()" id="draw-btn" > { - this.label = res.label; + next: () => { + this.label = this.drawingService.label; this.loading = false; }, error: (error) => { diff --git a/src/app/game/services/drawing.service.ts b/src/app/game/services/drawing.service.ts index 9157c271..b8288594 100644 --- a/src/app/game/services/drawing.service.ts +++ b/src/app/game/services/drawing.service.ts @@ -25,7 +25,6 @@ export class DrawingService { config = this.gameConfigService.getConfig; playerid = ''; - labels = []; label = ''; gameHasStarted = false; classificationDone = false; @@ -142,9 +141,6 @@ export class DrawingService { ); } - - - getLabel(): Observable { const currentLang = this.translationService.getCurrentLang(); return this.http diff --git a/src/app/game/services/web-socket.service.ts b/src/app/game/services/web-socket.service.ts index 80006a3d..23c1e3a9 100644 --- a/src/app/game/services/web-socket.service.ts +++ b/src/app/game/services/web-socket.service.ts @@ -13,7 +13,7 @@ import { GameStateService } from '../services/game-state-service'; export class WebSocketService { socket: Socket | undefined; private retryAttempts = 0; - private maxRetries = 5; + private maxRetries = 2; private retryDelay = 3000; playerDisconnectedData: PlayerDisconnectedData | undefined; @@ -78,19 +78,14 @@ export class WebSocketService { } disconnect() { - if (this.socket && ! this.socket.disconnected) { - console.warn('socket disconnecting and removing listener'); + if (this.socket) { this.socket.removeAllListeners(); this.socket.disconnect(); this.socket = undefined; this.isConnected = false; this.isRetrying = false; - console.log("Websocket closed properly") this.retryAttempts = 0; - } else if (this.socket) { - this.socket.removeAllListeners(); - this.socket.disconnect(); - console.log("Websocket closed properly without ever being connected") + console.log("Websocket closed properly"); } } diff --git a/src/app/game/shared-components/confirm-exit-dialog/confirm-exit-dialog.component.html b/src/app/game/shared-components/confirm-exit-dialog/confirm-exit-dialog.component.html index f815dc9b..2ed67c10 100644 --- a/src/app/game/shared-components/confirm-exit-dialog/confirm-exit-dialog.component.html +++ b/src/app/game/shared-components/confirm-exit-dialog/confirm-exit-dialog.component.html @@ -4,12 +4,12 @@

- - diff --git a/src/app/game/shared-components/confirm-exit-dialog/confirm-exit-dialog.component.ts b/src/app/game/shared-components/confirm-exit-dialog/confirm-exit-dialog.component.ts index 91cf9f67..46815b25 100644 --- a/src/app/game/shared-components/confirm-exit-dialog/confirm-exit-dialog.component.ts +++ b/src/app/game/shared-components/confirm-exit-dialog/confirm-exit-dialog.component.ts @@ -8,6 +8,7 @@ import { MatButton } from '@angular/material/button'; import { MatDialogActions, MatDialogContent, MatDialogRef } from '@angular/material/dialog'; import { MatIcon } from '@angular/material/icon'; import { DrawingService } from '@/app/game/services/drawing.service'; +import { animate, state, style, transition, trigger } from '@angular/animations'; @Component({ selector: 'app-confirm-exit-dialog', templateUrl: './confirm-exit-dialog.component.html', @@ -15,6 +16,14 @@ import { DrawingService } from '@/app/game/services/drawing.service'; encapsulation: ViewEncapsulation.None, standalone: true, imports: [MatDialogActions, MatDialogContent, MatButton, MatIcon, TranslatePipe], + animations: [ + trigger('buttonClickEffect', [ + state('normal', style({transform: 'scale(1)',})), + state('clicked', style({transform: 'scale(1.1)',})), + transition('normal => clicked', [animate('0.1s ease-out')]), + transition('clicked => normal', [animate('0.1s ease-in')]), + ]) + ] }) export class ConfirmExitDialogComponent implements OnInit, OnDestroy{ readonly dialogRef = inject(MatDialogRef); @@ -22,6 +31,8 @@ export class ConfirmExitDialogComponent implements OnInit, OnDestroy{ timer = 0; startTime = 10; countdownInterval = 0; + buttonStateHome = 'normal'; + buttonStateCancel = "normal"; constructor( private router: Router, @@ -61,21 +72,30 @@ export class ConfirmExitDialogComponent implements OnInit, OnDestroy{ } closeDialog() { - this.dialogRef.close(); + this.buttonStateCancel = "clicked"; + + setTimeout(() => { + this.buttonStateCancel = "normal"; + setTimeout(() => { + this.dialogRef.close(); + }, 100) + }, 100); } goToWelcomePage() { - this.clearCountdown(); - this.dialogRef.close(); - this.gameStateService.clearState(); - this.drawingService.clearState(); - - if (this.gameStateService.isMultiplayer()) { - this.multiplayerService.clearState(); - } - + this.buttonStateHome = "clicked"; + setTimeout(() => { + this.buttonStateHome = "normal"; + setTimeout(() => { + this.clearCountdown(); + this.dialogRef.close(); + this.gameStateService.clearState(); + this.drawingService.clearState(); + if (this.gameStateService.isMultiplayer()) { + this.multiplayerService.clearState(); + } this.router.navigate([routes.WELCOME]); + }, 100) + }, 100); } - - } diff --git a/src/app/game/shared-components/custom-button/custom-button.component.html b/src/app/game/shared-components/custom-button/custom-button.component.html index 7d11340c..db395423 100644 --- a/src/app/game/shared-components/custom-button/custom-button.component.html +++ b/src/app/game/shared-components/custom-button/custom-button.component.html @@ -3,7 +3,9 @@ @if (buttonStyle === 'select-mode-button' || buttonStyle === 'select-mode-button-large' || buttonStyle === 'forward-button' || buttonStyle === 'play-again-button') {
- -
diff --git a/src/app/game/idle-timeout/idle-timeout.component.scss b/src/app/game/shared-components/idle-timeout/idle-timeout.component.scss similarity index 92% rename from src/app/game/idle-timeout/idle-timeout.component.scss rename to src/app/game/shared-components/idle-timeout/idle-timeout.component.scss index ab1ff365..33d41131 100644 --- a/src/app/game/idle-timeout/idle-timeout.component.scss +++ b/src/app/game/shared-components/idle-timeout/idle-timeout.component.scss @@ -1,4 +1,4 @@ -@import '../../../variables.scss'; +@import '../../../../variables.scss'; .cdk-overlay-backdrop.cdk-overlay-dark-backdrop.cdk-overlay-backdrop-showing { background: rgba(20, 33, 61, 0.8); diff --git a/src/app/game/idle-timeout/idle-timeout.component.ts b/src/app/game/shared-components/idle-timeout/idle-timeout.component.ts similarity index 59% rename from src/app/game/idle-timeout/idle-timeout.component.ts rename to src/app/game/shared-components/idle-timeout/idle-timeout.component.ts index 38c8cd60..95a6eed9 100644 --- a/src/app/game/idle-timeout/idle-timeout.component.ts +++ b/src/app/game/shared-components/idle-timeout/idle-timeout.component.ts @@ -2,12 +2,14 @@ import { Component, OnInit, OnDestroy } from '@angular/core'; import { Router } from '@angular/router'; import { MatDialogRef, MatDialogContent, MatDialogActions } from '@angular/material/dialog'; import { ViewEncapsulation } from '@angular/core'; -import { routes } from '../../shared/models/routes'; +import { routes } from '../../../shared/models/routes'; import { MatIcon } from '@angular/material/icon'; import { MatButton } from '@angular/material/button'; import { CdkScrollable } from '@angular/cdk/scrolling'; import { TranslationService } from '@/app/core/translation.service'; import { TranslatePipe } from '@/app/core/translation.pipe'; +import { animate, state, style, transition, trigger } from '@angular/animations'; + @Component({ selector: 'app-idle-timeout', templateUrl: './idle-timeout.component.html', @@ -15,6 +17,14 @@ import { TranslatePipe } from '@/app/core/translation.pipe'; encapsulation: ViewEncapsulation.None, standalone: true, imports: [CdkScrollable, MatDialogContent, MatDialogActions, MatButton, MatIcon, TranslatePipe], + animations: [ + trigger('buttonClickEffect', [ + state('normal', style({transform: 'scale(1)',})), + state('clicked', style({transform: 'scale(1.1)',})), + transition('normal => clicked', [animate('0.1s ease-out')]), + transition('clicked => normal', [animate('0.1s ease-in')]), + ]) + ] }) export class IdleTimeoutComponent implements OnInit, OnDestroy { constructor( @@ -26,6 +36,8 @@ export class IdleTimeoutComponent implements OnInit, OnDestroy { startTime = 15; timer = 0; countdown = 0; + buttonStateHome = 'normal'; + buttonStateCancel = "normal"; ngOnInit(): void { this.timer = this.startTime; @@ -40,13 +52,26 @@ export class IdleTimeoutComponent implements OnInit, OnDestroy { } goHome() { - this.closeDialog(); - this.router.navigate([routes.LANDING]); + this.buttonStateHome = "clicked"; + setTimeout(() => { + this.buttonStateHome = "normal"; + setTimeout(() => { + clearInterval(this.countdown); + this.dialogRef.close(); + this.router.navigate([routes.LANDING]); + }, 100) + }, 100); } closeDialog() { - clearInterval(this.countdown); - this.dialogRef.close(); + this.buttonStateCancel = "clicked"; + setTimeout(() => { + this.buttonStateCancel = "normal"; + setTimeout(() => { + clearInterval(this.countdown); + this.dialogRef.close(); + }, 100) + }, 100); } resetTimer() { diff --git a/src/app/game/speech-bubble/speech-bubble.component.html b/src/app/game/shared-components/speech-bubble/speech-bubble.component.html similarity index 100% rename from src/app/game/speech-bubble/speech-bubble.component.html rename to src/app/game/shared-components/speech-bubble/speech-bubble.component.html diff --git a/src/app/game/speech-bubble/speech-bubble.component.scss b/src/app/game/shared-components/speech-bubble/speech-bubble.component.scss similarity index 94% rename from src/app/game/speech-bubble/speech-bubble.component.scss rename to src/app/game/shared-components/speech-bubble/speech-bubble.component.scss index 1ae092bb..c7a5aa27 100644 --- a/src/app/game/speech-bubble/speech-bubble.component.scss +++ b/src/app/game/shared-components/speech-bubble/speech-bubble.component.scss @@ -1,4 +1,4 @@ -@import '../../../variables.scss'; +@import '../../../../variables.scss'; * { text-align: center; diff --git a/src/app/game/speech-bubble/speech-bubble.component.ts b/src/app/game/shared-components/speech-bubble/speech-bubble.component.ts similarity index 100% rename from src/app/game/speech-bubble/speech-bubble.component.ts rename to src/app/game/shared-components/speech-bubble/speech-bubble.component.ts diff --git a/src/app/routes.ts b/src/app/routes.ts index eb8285d2..c61030da 100644 --- a/src/app/routes.ts +++ b/src/app/routes.ts @@ -6,7 +6,7 @@ import { routes as r } from './shared/models/routes'; import { GameResultComponent } from './game/game-result/game-result.component'; import { GameDrawComponent } from './game/game-draw/game-draw.component'; import { AdminComponent } from './admin/admin.component'; -import { InfoComponent } from './admin/info/info.component'; +import { InfoPageComponent } from './admin/info-page/info-page.component'; import { authGuard } from './admin/auth-guard'; import { MultiplayerComponent } from './game/game-multiplayer/multiplayer.component'; @@ -48,7 +48,7 @@ export const routes: Routes = [ }, { path: 'admin/info', - component: InfoComponent, + component: InfoPageComponent, canActivate: [authGuard], }, ]; diff --git a/src/app/shared/buttonStyles.ts b/src/app/shared/buttonStyles.ts index fe9b38fa..6a397390 100644 --- a/src/app/shared/buttonStyles.ts +++ b/src/app/shared/buttonStyles.ts @@ -3,6 +3,7 @@ export enum ButtonStyleClass { idle = 'idle-button', back = 'back-button', home = 'home-button', + end = 'end-button', forward = 'forward-button', select = 'select-mode-button', selectLarge = 'select-mode-button-large', diff --git a/src/app/splash/splash.component.ts b/src/app/splash/splash.component.ts index d54cdd2d..134b9427 100644 --- a/src/app/splash/splash.component.ts +++ b/src/app/splash/splash.component.ts @@ -2,7 +2,7 @@ import { Component, OnInit, OnDestroy } from '@angular/core'; import { Router } from '@angular/router'; import { CommonModule } from '@angular/common'; import { HttpClient } from '@angular/common/http'; -import { SpeechBubbleComponent } from '../game/speech-bubble/speech-bubble.component'; +import { SpeechBubbleComponent } from '../game/shared-components/speech-bubble/speech-bubble.component'; import { CustomColorsIO } from '../shared/customColors'; import { ArrowAlignment, PointerSide } from '../shared/models/interfaces'; import { trigger, state, style, animate, transition } from '@angular/animations'; diff --git a/src/app/welcome/welcome.component.html b/src/app/welcome/welcome.component.html index 24237cd9..46a7f482 100644 --- a/src/app/welcome/welcome.component.html +++ b/src/app/welcome/welcome.component.html @@ -107,9 +107,7 @@ [buttonStyle]="buttonStyleClass" [buttonText]="'PLAYER_MODE_SINGLE' | translate" [disabled]="!buttonIsVisible" - routerLink="/playgame/singleplayer" - routerLinkActive="active" - (click)="setSingleplayer()" + (buttonClicked)="setSingleplayer()" > person @@ -117,9 +115,7 @@ [buttonStyle]="buttonStyleClass" [buttonText]="'PLAYER_MODE_MULTI' | translate" [disabled]="!buttonIsVisible" - routerLink="/playgame/multiplayer" - routerLinkActive="active" - (click)="setMultiplayer()" + (buttonClicked)="setMultiplayer()" > group diff --git a/src/app/welcome/welcome.component.ts b/src/app/welcome/welcome.component.ts index 8f09e075..6694f3fd 100644 --- a/src/app/welcome/welcome.component.ts +++ b/src/app/welcome/welcome.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, OnDestroy } from '@angular/core'; +import { Component, OnInit, OnDestroy, inject } from '@angular/core'; import { MultiplayerService } from '../game/services/multiplayer.service'; import { DrawingService } from '../game/services/drawing.service'; import { Router, RouterLink, RouterLinkActive } from '@angular/router'; @@ -13,7 +13,7 @@ import { GameStateService } from '../game/services/game-state-service'; import { SupportedLanguages } from '../shared/models/interfaces'; import { ArrowAlignment, PointerSide } from '@/app/shared/models/interfaces'; import { trigger, state, style, animate, transition } from '@angular/animations'; -import { SpeechBubbleComponent } from '../game/speech-bubble/speech-bubble.component'; +import { SpeechBubbleComponent } from '../game/shared-components/speech-bubble/speech-bubble.component'; import { CustomColorsIO } from '../shared/customColors'; import { CustomButtonComponent } from '../game/shared-components/custom-button/custom-button.component'; import { ButtonStyleClass } from '@/app/shared/buttonStyles'; @@ -194,13 +194,20 @@ export class WelcomeComponent implements OnInit, OnDestroy { this.destroy$.complete(); } + + readonly singleplayerRouter = inject(Router); + readonly multiplayerRouter = inject(Router); + setSingleplayer() { this.gameStateService.setSingleplayer(); this.gameStateService.goToPage(GAMESTATE.difficultyPicker); + this.singleplayerRouter.navigate(["/playgame/singleplayer"]) + } setMultiplayer() { this.gameStateService.setMultiplayer(); this.gameStateService.goToPage(GAMESTATE.lobby); + this.multiplayerRouter.navigate(["/playgame/multiplayer"]); } }