diff --git a/src/app/admin/admin.component.ts b/src/app/admin/admin.component.ts index 876e1f13..ed48e45e 100644 --- a/src/app/admin/admin.component.ts +++ b/src/app/admin/admin.component.ts @@ -13,7 +13,7 @@ export class AdminComponent implements OnInit { ngOnInit(): void {} - login(username, password) { + login(username: string, password: string) { // Call on login service to authorize user this.loginService.login(username, password).subscribe( (res: any) => { diff --git a/src/app/admin/login.service.ts b/src/app/admin/login.service.ts index c4e31b3f..4427a061 100644 --- a/src/app/admin/login.service.ts +++ b/src/app/admin/login.service.ts @@ -10,7 +10,7 @@ export class LoginService { private _loggedIn = false; constructor(private http: HttpClient) {} - login(username, password) { + login(username: string, password: string) { const formData = new FormData(); formData.append('password', password); formData.append('username', username); @@ -46,7 +46,7 @@ export class LoginService { ); } - attemptLogin(formData) { + attemptLogin(formData: FormData) { return this.http.post(`${endpoints.TEKNISKBACKEND}/${endpoints.AUTH}`, formData, { withCredentials: true, }); diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 472592b8..84342530 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -17,7 +17,7 @@ import { environment } from '../environments/environment'; export class AppComponent implements OnInit { title = 'Teknisk Museum'; - userActivity; + userActivity = 0; userInactive: Subject = new Subject(); isDialogOpen = false; @@ -47,7 +47,7 @@ export class AppComponent implements OnInit { } setDialogTimeout() { - this.userActivity = setTimeout(() => this.userInactive.next(undefined), this.inactivityTime); + this.userActivity = window.setTimeout(() => this.userInactive.next(undefined), this.inactivityTime); } prepareRoute(outlet: RouterOutlet) { diff --git a/src/app/game/game-draw/game-draw.component.ts b/src/app/game/game-draw/game-draw.component.ts index b0688d28..3a255825 100644 --- a/src/app/game/game-draw/game-draw.component.ts +++ b/src/app/game/game-draw/game-draw.component.ts @@ -1,4 +1,4 @@ -import { Component, ElementRef, OnInit, ViewChild, Output, EventEmitter, OnDestroy } from '@angular/core'; +import { Component, ElementRef, OnInit, Output, EventEmitter, OnDestroy, viewChild } from '@angular/core'; import { BehaviorSubject, interval, Observable, Subscription } from 'rxjs'; import { ImageService } from './services/image.service'; import { take } from 'rxjs/operators'; @@ -13,22 +13,19 @@ import { SoundService } from './services/sound.service'; styleUrls: ['./game-draw.component.scss'], }) export class GameDrawComponent implements OnInit, OnDestroy { - @ViewChild('canvas', { static: true }) - canvas: ElementRef; - @ViewChild('countDown', { static: true }) - countDown: ElementRef; - - private ctx: CanvasRenderingContext2D; + canvas = viewChild.required>('canvas'); + countDown = viewChild.required>('countDown'); + private ctx: CanvasRenderingContext2D | undefined; @Output() isDoneDrawing = new EventEmitter(); x = 0; y = 0; - minX; - minY; - maxX; - maxY; + minX = 0; + minY = 0; + maxX = 0; + maxY = 0; isDrawing = false; hasLeftCanvas = false; @@ -45,11 +42,11 @@ export class GameDrawComponent implements OnInit, OnDestroy { private readonly _timeOut = new BehaviorSubject(false); readonly _timeOut$ = this._timeOut.asObservable(); - guessWord: string; - AI_GUESS: string; + guessWord = ''; + AI_GUESS = ''; prediction: any; - result: Result; + result: Result | undefined; hasAddedResult = false; subscriptions = new Subscription(); @@ -64,13 +61,14 @@ export class GameDrawComponent implements OnInit, OnDestroy { ngOnInit(): void { this.multiplayerService.roundIsOver = false; - const ctx = this.canvas.nativeElement.getContext('2d'); + const ctx = this.canvas().nativeElement.getContext('2d'); if (!ctx) { throw new Error('getContext failed'); } this.ctx = ctx; - this.canvas.nativeElement.width = this.canvas.nativeElement.parentElement?.offsetWidth || document.body.clientWidth; - this.canvas.nativeElement.height = document.body.clientHeight - 100; + this.canvas().nativeElement.width = + this.canvas().nativeElement.parentElement?.offsetWidth || document.body.clientWidth; + this.canvas().nativeElement.height = document.body.clientHeight - 100; this.resetMinMaxMouseValues(); this.drawingService.guessDone = false; if (this.multiplayerService.isMultiplayer) { @@ -109,7 +107,7 @@ export class GameDrawComponent implements OnInit, OnDestroy { }); } - updateResult(won) { + updateResult(won: boolean) { const result: Result = this.createResult(won); this.drawingService.guessUsed++; this.addResultAndResize(result).subscribe({ @@ -120,7 +118,7 @@ export class GameDrawComponent implements OnInit, OnDestroy { }); } - createResult(won) { + createResult(won: boolean) { let score = 0; if (won) { score = this.getScore(); @@ -140,9 +138,15 @@ export class GameDrawComponent implements OnInit, OnDestroy { this.drawingService.label = res.word ? res.word : ''; this.result = this.drawingService.createResult(res); this.drawingService.addResult(this.result); - const croppedCoordinates: any = this.imageService.crop(this.minX, this.minY, this.maxX, this.maxY, this.LINE_WIDTH); + const croppedCoordinates: number[] = this.imageService.crop( + this.minX, + this.minY, + this.maxX, + this.maxY, + this.LINE_WIDTH + ); return this.imageService.resize( - this.canvas.nativeElement.toDataURL('image/png'), + this.canvas().nativeElement.toDataURL('image/png'), croppedCoordinates, this.resultImageSize ); @@ -226,7 +230,7 @@ export class GameDrawComponent implements OnInit, OnDestroy { } } if (this.timeLeft <= 5) { - this.countDown.nativeElement.style.color = color; + this.countDown().nativeElement.style.color = color; color = color === 'white' ? 'red' : 'white'; this.soundService.playTickSound(); this.soundService.playTick = true; @@ -243,7 +247,7 @@ export class GameDrawComponent implements OnInit, OnDestroy { }); } - sortOnCertainty(res) { + sortOnCertainty(res: any) { const arr: any = []; Object.entries(res.certainty).map((keyValue) => { const [label, certainty] = keyValue; @@ -258,14 +262,14 @@ export class GameDrawComponent implements OnInit, OnDestroy { return arr; } - updateAiGuess(sortedCertaintyArr) { + updateAiGuess(sortedCertaintyArr: any[]) { if (sortedCertaintyArr && sortedCertaintyArr.length > 1) { const guess = sortedCertaintyArr[0].label; this.AI_GUESS = guess === this.guessWord ? sortedCertaintyArr[1].label : guess; } } - handleSinglePlayerClassification(dataUrl, croppedCoordinates) { + handleSinglePlayerClassification(dataUrl: string, croppedCoordinates: number[]) { const formData: FormData = this.createFormData(dataUrl); this.drawingService.classify(formData).subscribe((res) => { @@ -276,7 +280,7 @@ export class GameDrawComponent implements OnInit, OnDestroy { const score = this.score > 0 ? this.score : 0; this.drawingService.lastResult.score = Math.round(score); this.imageService - .resize(this.canvas.nativeElement.toDataURL('image/png'), croppedCoordinates, this.resultImageSize) + .resize(this.canvas().nativeElement.toDataURL('image/png'), croppedCoordinates, this.resultImageSize) .subscribe({ next: (dataUrlHighRes) => { this.drawingService.lastResult.imageData = dataUrlHighRes; @@ -284,7 +288,7 @@ export class GameDrawComponent implements OnInit, OnDestroy { }); } else { this.imageService - .resize(this.canvas.nativeElement.toDataURL('image/png'), croppedCoordinates, this.resultImageSize) + .resize(this.canvas().nativeElement.toDataURL('image/png'), croppedCoordinates, this.resultImageSize) .subscribe({ next: (dataUrlHighRes) => { this.drawingService.pred.imageData = dataUrlHighRes; @@ -295,12 +299,18 @@ export class GameDrawComponent implements OnInit, OnDestroy { } classify(isMultiplayer = false) { - const b64Image = this.canvas.nativeElement.toDataURL('image/png'); - const croppedCoordinates: any = this.imageService.crop(this.minX, this.minY, this.maxX, this.maxY, this.LINE_WIDTH); + const b64Image = this.canvas().nativeElement.toDataURL('image/png'); + const croppedCoordinates: number[] = this.imageService.crop( + this.minX, + this.minY, + this.maxX, + this.maxY, + this.LINE_WIDTH + ); this.imageService.resize(b64Image, croppedCoordinates).subscribe({ next: (dataUrl) => { if (isMultiplayer) { - const body = { + const body: { game_id?: string; time_left: number } = { game_id: this.multiplayerService.stateInfo.game_id, time_left: this.timeLeft, }; @@ -313,7 +323,7 @@ export class GameDrawComponent implements OnInit, OnDestroy { }); } - createFormData(dataUrl): FormData { + createFormData(dataUrl: string): FormData { const formData: FormData = this.imageService.createFormData(dataUrl); formData.append('player_id', this.drawingService.playerid); formData.append('time', this.timeLeft.toString()); @@ -321,10 +331,10 @@ export class GameDrawComponent implements OnInit, OnDestroy { return formData; } - getClientOffset(event) { + getClientOffset(event: any) { const { pageX, pageY } = event.touches ? event.touches[0] : event; - const x = pageX - this.canvas.nativeElement.offsetLeft; - const y = pageY - this.canvas.nativeElement.offsetTop; + const x = pageX - this.canvas().nativeElement.offsetLeft; + const y = pageY - this.canvas().nativeElement.offsetTop; return { x, y }; } @@ -358,14 +368,16 @@ export class GameDrawComponent implements OnInit, OnDestroy { this.hasLeftCanvas = false; } - drawLine(currentX, currentY) { - this.ctx.strokeStyle = 'black'; - this.ctx.lineWidth = this.LINE_WIDTH; - this.ctx.lineCap = this.ctx.lineJoin = 'round'; - this.ctx.beginPath(); - this.ctx.moveTo(this.x, this.y); - this.ctx.lineTo(currentX, currentY); - this.ctx.stroke(); + drawLine(currentX: number, currentY: number) { + if (this.ctx) { + this.ctx.strokeStyle = 'black'; + this.ctx.lineWidth = this.LINE_WIDTH; + this.ctx.lineCap = this.ctx.lineJoin = 'round'; + this.ctx.beginPath(); + this.ctx.moveTo(this.x, this.y); + this.ctx.lineTo(currentX, currentY); + this.ctx.stroke(); + } this.isBlankImage = false; @@ -388,30 +400,30 @@ export class GameDrawComponent implements OnInit, OnDestroy { if (this.minY < 0) { this.minY = 0; } - if (this.maxX > this.canvas.nativeElement.width) { - this.maxX = this.canvas.nativeElement.width; + if (this.maxX > this.canvas().nativeElement.width) { + this.maxX = this.canvas().nativeElement.width; } - if (this.maxY > this.canvas.nativeElement.height) { - this.maxY = this.canvas.nativeElement.height; + if (this.maxY > this.canvas().nativeElement.height) { + this.maxY = this.canvas().nativeElement.height; } } clear() { - const canvas = this.canvas.nativeElement; - this.ctx.clearRect(0, 0, canvas.width, canvas.height); + const canvas = this.canvas().nativeElement; + this.ctx?.clearRect(0, 0, canvas.width, canvas.height); this.isBlankImage = true; this.resetMinMaxMouseValues(); } resetMinMaxMouseValues() { - this.minX = this.canvas.nativeElement.width; - this.minY = this.canvas.nativeElement.height; + this.minX = this.canvas().nativeElement.width; + this.minY = this.canvas().nativeElement.height; this.maxX = 0; this.maxY = 0; } - stop(e) { - if (!this.timeOut && this.isDrawing) { + stop(e: MouseEvent | TouchEvent) { + if (!this.timeOut && this.isDrawing && e instanceof MouseEvent) { this.drawLine(e.offsetX, e.offsetY); this.isDrawing = false; } diff --git a/src/app/game/game-draw/services/drawing.service.ts b/src/app/game/game-draw/services/drawing.service.ts index 32ca259d..90038173 100644 --- a/src/app/game/game-draw/services/drawing.service.ts +++ b/src/app/game/game-draw/services/drawing.service.ts @@ -38,7 +38,7 @@ export class DrawingService { classify(answerInfo: FormData): Observable { return this.http.post(`${this.baseUrl}/${endpoints.CLASSIFY}`, answerInfo).pipe( - tap((res) => { + tap((res: any) => { this.pred = res; if (this.guessUsed <= res.serverRound && this.roundIsDone(res) && !this.hasAddedSingleplayerResult) { res.roundIsDone = true; @@ -72,7 +72,7 @@ export class DrawingService { return result; } - createResult(res): Result { + createResult(res: any): Result { const result: Result = { hasWon: res.hasWon, imageData: '', @@ -84,7 +84,7 @@ export class DrawingService { return result; } - roundIsDone(res) { + roundIsDone(res: any) { return res.hasWon || res.gameState === 'Done'; } diff --git a/src/app/game/game-draw/services/image.service.ts b/src/app/game/game-draw/services/image.service.ts index 8754fa69..d9540625 100644 --- a/src/app/game/game-draw/services/image.service.ts +++ b/src/app/game/game-draw/services/image.service.ts @@ -9,7 +9,7 @@ export class ImageService { constructor() {} - b64ToUint8Array(b64Image) { + b64ToUint8Array(b64Image: string) { const img = atob(b64Image.split(',')[1]); const imgBuffer: number[] = []; let i = 0; @@ -20,7 +20,7 @@ export class ImageService { return new Uint8Array(imgBuffer); } - resize(b64Image, croppedCoordinates, imageSize = 256): Observable { + resize(b64Image: string, croppedCoordinates: number[], imageSize = 256): Observable { return new Observable((observer) => { const img = new Image(); const canvas = document.createElement('canvas'); @@ -42,7 +42,7 @@ export class ImageService { }); } - crop(minX, minY, maxX, maxY, userDrawLineWidth) { + crop(minX: number, minY: number, maxX: number, maxY: number, userDrawLineWidth: number) { const paddingForLineWidth = userDrawLineWidth / 2; const paddingExtra = 20; const paddingTotal = paddingForLineWidth + paddingExtra; @@ -62,7 +62,7 @@ export class ImageService { return [sx, sy, sw, sh]; } - createFormData(dataUrl) { + createFormData(dataUrl: string) { const u8Image = this.b64ToUint8Array(dataUrl); const blob = new Blob([u8Image], { type: 'image/png', @@ -73,7 +73,7 @@ export class ImageService { return formData; } - createBlob(dataUrl) { + createBlob(dataUrl: string) { const u8Image = this.b64ToUint8Array(dataUrl); const blob = new Blob([u8Image], { type: 'image/png', diff --git a/src/app/game/game-intermediate-result/game-intermediate-result.component.ts b/src/app/game/game-intermediate-result/game-intermediate-result.component.ts index e3858495..2cae6947 100644 --- a/src/app/game/game-intermediate-result/game-intermediate-result.component.ts +++ b/src/app/game/game-intermediate-result/game-intermediate-result.component.ts @@ -10,10 +10,10 @@ import { routes } from '../../shared/models/routes'; styleUrls: ['./game-intermediate-result.component.scss'], }) export class GameIntermediateResultComponent implements OnInit, OnDestroy { - result: Result; + result: Result | undefined; wonSentence = 'Hurra, jeg klarte å gjette at du tegnet '; lostSentence = 'Beklager, jeg klarte ikke å gjette hva du tegnet'; - gameOver: boolean; + gameOver = false; @Output() nextGuess = new EventEmitter(); @Output() finalResult = new EventEmitter(); waitingForPlayer = true; @@ -54,7 +54,7 @@ export class GameIntermediateResultComponent implements OnInit, OnDestroy { return accumulator + currentValue.score; }, 0); this.multiplayerService.stateInfo = { ...this.multiplayerService.stateInfo, score: totalScore }; - this.multiplayerService.endGame(totalScore); + this.multiplayerService.endGame(); } } } diff --git a/src/app/game/game-multiplayer/services/multiplayer.service.ts b/src/app/game/game-multiplayer/services/multiplayer.service.ts index 9c1603ca..49f8901e 100644 --- a/src/app/game/game-multiplayer/services/multiplayer.service.ts +++ b/src/app/game/game-multiplayer/services/multiplayer.service.ts @@ -87,7 +87,7 @@ export class MultiplayerService { ); } - classify(data, image) { + classify(data: { game_id?: string; time_left: number }, image: Blob) { this.webSocketService.emit(SocketEndpoints.CLASSIFY, data, image); } @@ -103,7 +103,7 @@ export class MultiplayerService { return this.webSocketService.listen(SocketEndpoints.END_GAME); } - endGame(score) { + endGame() { const result = JSON.stringify({ game_id: this.stateInfo.game_id, score: this.stateInfo.score, @@ -117,10 +117,9 @@ export class MultiplayerService { this.webSocketService.disconnect(); } - changestate(gameLevel: GAMELEVEL, ...rest) { + changestate(gameLevel: GAMELEVEL) { this.stateInfo = { ...this.stateInfo, - ...rest, gameLevel, }; } diff --git a/src/app/game/game-multiplayer/services/web-socket.service.ts b/src/app/game/game-multiplayer/services/web-socket.service.ts index fbbef706..22987aa8 100644 --- a/src/app/game/game-multiplayer/services/web-socket.service.ts +++ b/src/app/game/game-multiplayer/services/web-socket.service.ts @@ -12,9 +12,9 @@ export interface PlayerDisconnectedData { providedIn: 'root', }) export class WebSocketService { - socket: Socket; + socket: Socket | undefined; - playerDisconnectedData: PlayerDisconnectedData; + playerDisconnectedData: PlayerDisconnectedData | undefined; private readonly _playerDisconnected = new BehaviorSubject(false); readonly playerDisconnected$ = this._playerDisconnected.asObservable(); @@ -56,16 +56,16 @@ export class WebSocketService { } } - listen(eventName: string) { - return new Observable((subscriber) => { - this.socket.on(eventName, (data) => { + listen(eventName: string) { + return new Observable((subscriber) => { + this.socket?.on(eventName, (data) => { subscriber.next(data); }); }); } emit(eventName: string, ...rest: any) { - this.socket.emit(eventName, ...rest); + this.socket?.emit(eventName, ...rest); } get playerDisconnected(): boolean { diff --git a/src/app/game/game-result/game-result.component.ts b/src/app/game/game-result/game-result.component.ts index 94b73b68..08e2f3de 100644 --- a/src/app/game/game-result/game-result.component.ts +++ b/src/app/game/game-result/game-result.component.ts @@ -11,10 +11,10 @@ import { MultiplayerService } from '../game-multiplayer/services/multiplayer.ser }) export class GameResultComponent implements OnInit { results: Result[] = []; - totalScore: number; - loading: boolean; + totalScore = 0; + loading = false; value = ''; - hasWon: boolean; + hasWon = false; ismultiplayer = false; score = 0; constructor( diff --git a/src/app/game/game-word-to-draw/game-word-to-draw.component.ts b/src/app/game/game-word-to-draw/game-word-to-draw.component.ts index fa528e3e..41ef9020 100644 --- a/src/app/game/game-word-to-draw/game-word-to-draw.component.ts +++ b/src/app/game/game-word-to-draw/game-word-to-draw.component.ts @@ -26,10 +26,10 @@ export class GameWordToDrawComponent implements OnInit, OnDestroy { timeLeft = 5; loading = true; - playernr: string; + playernr = ''; subscriptions = new Subscription(); - timerSubscription: Subscription; + timerSubscription: Subscription | undefined; ngOnInit(): void { if (this.router.url === `/${routes.SINGLEPLAYER}`) { diff --git a/src/app/game/game.component.html b/src/app/game/game.component.html index 7f2bcef6..52f687ef 100644 --- a/src/app/game/game.component.html +++ b/src/app/game/game.component.html @@ -6,10 +6,7 @@
- +
diff --git a/src/app/game/game.component.ts b/src/app/game/game.component.ts index 9f9e9f3c..47b3e07b 100644 --- a/src/app/game/game.component.ts +++ b/src/app/game/game.component.ts @@ -68,12 +68,12 @@ export class GameComponent implements OnInit, OnDestroy { this.newGame = true; } - nextGuess(event) { + nextGuess() { this.clearGameState(); this.showWordToDraw = true; } - finalResult(event) { + finalResult() { this.clearGameState(); this.showFinalResult = this.drawingService.gameOver; } diff --git a/src/app/idle-timeout/idle-timeout.component.ts b/src/app/idle-timeout/idle-timeout.component.ts index fb905626..a0584ccf 100644 --- a/src/app/idle-timeout/idle-timeout.component.ts +++ b/src/app/idle-timeout/idle-timeout.component.ts @@ -14,12 +14,12 @@ export class IdleTimeoutComponent implements OnInit, OnDestroy { constructor(private router: Router, private dialogRef: MatDialogRef) {} startTime = 15; - timer; - countdown; + timer = 0; + countdown = 0; ngOnInit(): void { this.timer = this.startTime; - this.countdown = setInterval(() => { + this.countdown = window.setInterval(() => { this.timer -= 1; if (this.timer === 0) { this.resetTimer(); diff --git a/src/app/shared/models/endpoints.ts b/src/app/shared/models/endpoints.ts index babd4a6f..0bdd9fd2 100644 --- a/src/app/shared/models/endpoints.ts +++ b/src/app/shared/models/endpoints.ts @@ -1,4 +1,5 @@ -import { environment } from 'src/environments/environment'; +import { environment } from '@/environments/environment'; + export const endpoints = { TEKNISKBACKEND: environment.TEKNISKBACKEND_ENDPOINT, ENDGAME: 'endGame', diff --git a/src/app/shared/models/routes.ts b/src/app/shared/models/routes.ts index ab93bc4c..392df147 100644 --- a/src/app/shared/models/routes.ts +++ b/src/app/shared/models/routes.ts @@ -1,4 +1,5 @@ -import { environment } from 'src/environments/environment'; +import { environment } from '@/environments/environment'; + export const routes = { LANDING: '', SINGLEPLAYER: 'playgame/singleplayer', diff --git a/src/app/welcome/welcome.component.html b/src/app/welcome/welcome.component.html index 5bad584c..e429ce9f 100644 --- a/src/app/welcome/welcome.component.html +++ b/src/app/welcome/welcome.component.html @@ -2,11 +2,11 @@
- avatar + avatar
- Hei, jeg heter Kunstig Jens.
+ Hei, jeg heter Kunstig Jens.
Kan du hjelpe meg å lære?
diff --git a/src/app/welcome/welcome.component.ts b/src/app/welcome/welcome.component.ts index 56a6b98d..aac315da 100644 --- a/src/app/welcome/welcome.component.ts +++ b/src/app/welcome/welcome.component.ts @@ -9,7 +9,11 @@ import { Router } from '@angular/router'; }) export class WelcomeComponent implements OnInit { private headerClicks = 0; - constructor(private multiplayerService: MultiplayerService, private drawingService: DrawingService, private router: Router) {} + constructor( + private multiplayerService: MultiplayerService, + private drawingService: DrawingService, + private router: Router + ) {} ngOnInit() { this.multiplayerService.clearState();