From a8835b9a38d04892158d562a747e59a2598c65ac Mon Sep 17 00:00:00 2001 From: Marcin Bator Date: Thu, 11 Jul 2024 21:18:37 +0200 Subject: [PATCH 01/57] refactor: #dev ai-socket service extraction --- .../ai-socket-menu.component.spec.ts | 37 +++--- .../ai-socket-menu.component.ts | 120 ++++++++---------- .../socket-connected-menu.component.ts | 18 ++- .../services/ai-socket.service.ts | 91 +++++++++++++ 4 files changed, 177 insertions(+), 89 deletions(-) create mode 100644 src/app/game/components/ai-socket-menu/services/ai-socket.service.ts diff --git a/src/app/game/components/ai-socket-menu/ai-socket-menu.component.spec.ts b/src/app/game/components/ai-socket-menu/ai-socket-menu.component.spec.ts index f82f2ae..0ee2ab5 100644 --- a/src/app/game/components/ai-socket-menu/ai-socket-menu.component.spec.ts +++ b/src/app/game/components/ai-socket-menu/ai-socket-menu.component.spec.ts @@ -1,13 +1,26 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { AiSocketMenuComponent } from './ai-socket-menu.component'; +import { By } from '@angular/platform-browser'; +import { AiSocketService } from './services/ai-socket.service'; describe('AiSocketMenuComponent', () => { let component: AiSocketMenuComponent; let fixture: ComponentFixture; + let aiSocketServiceStub: Partial; beforeEach(async () => { + aiSocketServiceStub = { + getIsSocketConnected: (): boolean => true, + getIsDataSendingActive: (): boolean => false, + getSocket: (): WebSocket | null => ({}) as WebSocket, + stopDataExchange: (): void => { + void 0; + }, + }; + await TestBed.configureTestingModule({ imports: [AiSocketMenuComponent], + providers: [{ provide: AiSocketService, useValue: aiSocketServiceStub }], }).compileComponents(); }); @@ -17,25 +30,19 @@ describe('AiSocketMenuComponent', () => { fixture.detectChanges(); }); - it('should create the component', () => { + it('should create', () => { expect(component).toBeTruthy(); }); - it('should initialize socket to null', () => { - expect(component.socket).toBeNull(); - }); - - it('should emit logData when logDataEmitter is called', () => { - const logData = { message: 'Test log message' }; - spyOn(component.logDataEmitter, 'emit'); - component.logDataEmitter.emit(logData); - expect(component.logDataEmitter.emit).toHaveBeenCalledWith(logData); + it('should display "Connected" when socket is connected', () => { + const statusSpan = fixture.debugElement.query(By.css('span')).nativeElement; + expect(statusSpan.textContent).toContain('Connected'); }); - it('should connect to the socket when connect is called', () => { - const socketDomain = 'ws://localhost:8080/'; - component.connect(socketDomain); - expect(component.socket).not.toBeNull(); - expect(component.socket?.url).toBe(socketDomain); + it('should display "Connect" button when socket is not connected', () => { + aiSocketServiceStub.getIsSocketConnected = (): boolean => false; + fixture.detectChanges(); + const button = fixture.debugElement.query(By.css('button')).nativeElement; + expect(button.textContent).toContain('Connect'); }); }); diff --git a/src/app/game/components/ai-socket-menu/ai-socket-menu.component.ts b/src/app/game/components/ai-socket-menu/ai-socket-menu.component.ts index a1cfa5c..f3d776c 100644 --- a/src/app/game/components/ai-socket-menu/ai-socket-menu.component.ts +++ b/src/app/game/components/ai-socket-menu/ai-socket-menu.component.ts @@ -6,6 +6,7 @@ import { SocketDomainInputComponent } from './components/socket-domain-input/soc import { SocketConnectedMenuComponent } from './components/socket-connected-menu/socket-connected-menu.component'; import { DebugModeMenuComponent } from './components/debug-mode-menu/debug-mode-menu.component'; import { DebugModePanelComponent } from './components/debug-mode-panel/debug-mode-panel.component'; +import { AiSocketService } from './services/ai-socket.service'; @Component({ selector: 'app-ai-socket-menu', @@ -30,23 +31,27 @@ import { DebugModePanelComponent } from './components/debug-mode-panel/debug-mod [recentPhrases]="recentPhrases">
- @if (isSocketConnected) { - + @if (aiSocketService.getIsSocketConnected()) { + @if (gameDataSendingType === tGameDataSendingType.TimeGame) { } } @else { - + }
@@ -54,98 +59,76 @@ import { DebugModePanelComponent } from './components/debug-mode-panel/debug-mod `, }) export class AiSocketMenuComponent implements OnInit, ILoggableDataComponent { - private _dataToSend: TExchangeData = {}; - @Input({ required: true }) public gameName = ''; @Input({ required: true }) public gameDataSendingType: TGameDataSendingType = TGameDataSendingType.TimeGame; + @Input({ required: true }) public expectedDataToReceive: TExchangeData = {}; @Input({ required: true }) public set setDataToSend(value: TExchangeData) { this._dataToSend = value; if (this.gameDataSendingType === TGameDataSendingType.EventGame) { - this.sendDataToSocket(); + this.aiSocketService.sendDataToSocket( + this._dataToSend, + this.expectedDataToReceive + ); } } - @Input({ required: true }) public expectedDataToReceive: TExchangeData = {}; @Output() public logDataEmitter = new EventEmitter(); @Output() public receivedDataEmitter = new EventEmitter(); + private _dataToSend: TExchangeData = {}; + public isDebugModeActive = false; - public socket: WebSocket | null = null; public recentPhrases: string[] = []; - public isSocketConnected = false; - public isDataSendingActive = false; - public sendingInterval = 500; - public sendingIntervalID: unknown | null = null; + public vSendingInterval = { value: 500 }; public socketUrl = ''; public tGameDataSendingType = TGameDataSendingType; public logData: TExchangeData = { - isSocketConnected: this.isSocketConnected, + isSocketConnected: this.aiSocketService.getIsSocketConnected(), socketURL: this.socketUrl, - sendingInterval: this.sendingInterval, + sendingInterval: this.vSendingInterval.value, }; + public constructor(public aiSocketService: AiSocketService) { + console.log('AiSocketMenuComponent constructor'); + } + public ngOnInit(): void { this.logDataEmitter.emit(this.logData); this.loadRecentPhrases(); } - public connect(socketDomain: string): void { - try { - this.socket = new WebSocket(socketDomain); - this.socket.addEventListener('open', () => { - this.isSocketConnected = true; - this.saveRecentPhrase(socketDomain); + public onStartDataExchangeClick = (): void => { + this.aiSocketService.startDataExchange( + this.vSendingInterval.value, + this._dataToSend, + this.expectedDataToReceive + ); + this.emitLogData(); + }; + + public onConnectButtonClick(): void { + this.aiSocketService.connect( + this.socketUrl, + () => { + this.saveRecentPhrase(this.socketUrl); this.emitLogData(); - }); - this.socket.addEventListener('message', event => { + }, + (event: MessageEvent) => { this.receivedDataEmitter.emit(JSON.parse(event.data)); - }); - this.socket.addEventListener('close', () => { - this.isSocketConnected = false; - this.stopDataExchange(); + }, + () => { this.emitLogData(); - }); - } catch (error) { - this.isSocketConnected = false; - this.stopDataExchange(); - this.emitLogData(); - } + } + ); } - public startDataExchange = (): void => { - this.isDataSendingActive = true; - this.sendingIntervalID = setInterval(() => { - this.sendDataToSocket(); - }, this.sendingInterval); - this.emitLogData(); - }; - - public stopDataExchange = (): void => { - if (this.sendingIntervalID != null) { - this.isDataSendingActive = false; - clearInterval(this.sendingIntervalID as number); - } - }; - public emitDebugSocketInput(data: TExchangeData): void { this.receivedDataEmitter.emit(data); } // - private sendDataToSocket(): void { - if (this.socket && this.isSocketConnected) { - this.socket.send( - JSON.stringify({ - output: this._dataToSend, - expected_input: this.expectedDataToReceive, - }) - ); - console.log('Data sent'); // - } - } - private loadRecentPhrases(): void { const cachedPhrases = localStorage.getItem( 'recentPhrases_' + this.gameName @@ -170,9 +153,10 @@ export class AiSocketMenuComponent implements OnInit, ILoggableDataComponent { } private emitLogData(): void { - this.logData['socketURL'] = this.socket?.url || ''; - this.logData['isSocketConnected'] = this.isSocketConnected; - this.logData['sendingInterval'] = this.sendingInterval; + this.logData['socketURL'] = this.aiSocketService.getSocket()?.url || ''; + this.logData['isSocketConnected'] = + this.aiSocketService.getIsSocketConnected(); + this.logData['sendingInterval'] = this.vSendingInterval; this.logDataEmitter.emit(this.logData); } } diff --git a/src/app/game/components/ai-socket-menu/components/socket-connected-menu/socket-connected-menu.component.ts b/src/app/game/components/ai-socket-menu/components/socket-connected-menu/socket-connected-menu.component.ts index 3c02c36..9abf7e3 100644 --- a/src/app/game/components/ai-socket-menu/components/socket-connected-menu/socket-connected-menu.component.ts +++ b/src/app/game/components/ai-socket-menu/components/socket-connected-menu/socket-connected-menu.component.ts @@ -16,19 +16,25 @@ import { TGameDataSendingType } from '../../../../models/game-data-sending-type. min="10" max="1000" step="10" - [defaultValue]="sendingInterval" - (change)="sendingInterval = sendingIntervalInput.valueAsNumber" /> - + [defaultValue]="vSendingInterval.value" + (change)=" + vSendingInterval.value = sendingIntervalInput.valueAsNumber + " /> + } `, }) export class SocketConnectedMenuComponent { @Input({ required: true }) public isDataSendingActive = false; - @Input({ required: true }) public sendingInterval = 500; + @Input({ required: true }) public vSendingInterval = { value: 500 }; @Input({ required: true }) public socket: WebSocket | null = null; - @Input({ required: true }) public startDataExchange = (): void => { - console.log('startDataExchange'); + @Input({ required: true }) public startDataExchange = ( + sendingInterval: number + ): void => { + console.log(sendingInterval); }; @Input({ required: true }) public stopDataExchange = (): void => { console.log('stopDataExchange'); diff --git a/src/app/game/components/ai-socket-menu/services/ai-socket.service.ts b/src/app/game/components/ai-socket-menu/services/ai-socket.service.ts new file mode 100644 index 0000000..401c851 --- /dev/null +++ b/src/app/game/components/ai-socket-menu/services/ai-socket.service.ts @@ -0,0 +1,91 @@ +import { Injectable } from '@angular/core'; +import { TExchangeData } from '../../../models/exchange-data.type'; + +@Injectable({ + providedIn: 'root', +}) +export class AiSocketService { + private _socket!: WebSocket; + private isSocketConnected = false; + private _sendingIntervalID: unknown | null = null; + private isDataSendingActive = false; + + public sendDataToSocket( + dataToSend: TExchangeData, + expectedDataToReceive: TExchangeData + ): void { + if (this._socket && this.isSocketConnected) { + this._socket.send( + JSON.stringify({ + output: dataToSend, + expected_input: expectedDataToReceive, + }) + ); + console.log('Data sent'); + } + } + + public connect( + socketUrl: string, + onOpen: () => void, + onMessage: (event: MessageEvent) => void, + onClose: () => void + ): void { + try { + this._socket = new WebSocket(socketUrl); + this._socket.addEventListener('open', () => { + this.isSocketConnected = true; + onOpen(); + }); + this._socket.addEventListener('message', event => { + onMessage(event); + }); + this._socket.addEventListener('close', () => { + this.stopDataExchange(); + this.isSocketConnected = false; + onClose(); + }); + } catch (error) { + this.stopDataExchange(); + this.isSocketConnected = false; + onClose(); + } + } + + public startDataExchange = ( + sendingInterval: number, + dataToSend: TExchangeData, + expectedDataToReceive: TExchangeData + ): void => { + console.log(sendingInterval); + this.isDataSendingActive = true; + this._sendingIntervalID = setInterval(() => { + this.sendDataToSocket(dataToSend, expectedDataToReceive); + }, sendingInterval); + }; + + public stopDataExchange = (): void => { + if (this._sendingIntervalID != null) { + this.isDataSendingActive = false; + clearInterval(this._sendingIntervalID as number); + } + }; + + // + + public getSocket(): WebSocket | null { + return this._socket; + } + + public getIsSocketConnected(): boolean { + return this.isSocketConnected; + } + + public getIsDataSendingActive(): boolean { + return this.isDataSendingActive; + } + + public getSendingInterval(): number { + return this._sendingIntervalID as number; + } +} From b0c33997ab2a787f39f071d350cc34a112346393 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Buczek?= Date: Sun, 14 Jul 2024 20:22:43 +0200 Subject: [PATCH 02/57] feat: #18 initial styling changes, it will be different --- angular.json | 3 ++- src/app/game/components/console/console.component.ts | 4 ++-- src/app/game/game.page.component.ts | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/angular.json b/angular.json index a05f7ad..a06dea7 100644 --- a/angular.json +++ b/angular.json @@ -157,6 +157,7 @@ "schematicCollections": [ "@angular-eslint/schematics", "@schematics/angular" - ] + ], + "analytics": false } } diff --git a/src/app/game/components/console/console.component.ts b/src/app/game/components/console/console.component.ts index 97cdcd8..93a6c84 100644 --- a/src/app/game/components/console/console.component.ts +++ b/src/app/game/components/console/console.component.ts @@ -8,10 +8,10 @@ import { ExchangeDataPipe } from '../../../../utils/pipes/exchange-data.pipe'; standalone: true, template: ` @for (data of logData | keyvalue; track data.key) { -

+

{{ data.key }}: @if (isTLogData(data.value)) { - + } @else { {{ data.value }} } diff --git a/src/app/game/game.page.component.ts b/src/app/game/game.page.component.ts index 7974a33..b06cc3a 100644 --- a/src/app/game/game.page.component.ts +++ b/src/app/game/game.page.component.ts @@ -56,7 +56,7 @@ import { ExchangeDataPipe } from '../../utils/pipes/exchange-data.pipe'; }

+ class="fixed bottom-0 left-0 w-1/2 p-10 max-h-96 overflow-y-auto bg-white border-y-red-600 border-solid border-2 z-50">
`, From 4679d2e7ad9150c7f0241945f5d1d5ed98b5ca0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Buczek?= Date: Tue, 16 Jul 2024 01:00:12 +0200 Subject: [PATCH 03/57] feat: #18 added show/hide animation and some css effects --- src/app/game/game.page.component.ts | 23 ++++++++++++++++++----- tailwind.config.js | 2 +- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/app/game/game.page.component.ts b/src/app/game/game.page.component.ts index b06cc3a..2637ca0 100644 --- a/src/app/game/game.page.component.ts +++ b/src/app/game/game.page.component.ts @@ -17,7 +17,7 @@ import { ExchangeDataPipe } from '../../utils/pipes/exchange-data.pipe'; selector: 'app-game', standalone: true, template: ` -
+
@if (game) {
-
- +
+ + +
`, imports: [ @@ -82,6 +89,12 @@ export class GamePageComponent implements OnInit { public socketInputData: TExchangeData = {}; public gameWindowOutputData: TExchangeData = {}; + public isConsoleVisible = false; + + public toggleConsole(): void { + this.isConsoleVisible = !this.isConsoleVisible; + } + public ngOnInit(): void { this._route.paramMap.subscribe(params => { this.gameName = params.get('gameName') || ''; diff --git a/tailwind.config.js b/tailwind.config.js index 079ce76..dd8a45a 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -13,7 +13,7 @@ module.exports = { colors: { mainGray: '#353535', lightGray: '#5D5D5D', - darkGray: ' #3C3D42', + darkGray: '#3C3D42', mainOrange: '#FF6000', lightOragne: '#FFA559', mainCreme: '#FFE6C7', From 8e5ea52c2397f65b7d2501455027fae6e494aeee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Buczek?= Date: Wed, 17 Jul 2024 00:39:13 +0200 Subject: [PATCH 04/57] feat: #18 another animations added in console showing --- .../components/console/console.component.ts | 8 ++++---- src/app/game/game.page.component.ts | 18 ++++++++++++------ 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/app/game/components/console/console.component.ts b/src/app/game/components/console/console.component.ts index 93a6c84..b42eba3 100644 --- a/src/app/game/components/console/console.component.ts +++ b/src/app/game/components/console/console.component.ts @@ -8,14 +8,14 @@ import { ExchangeDataPipe } from '../../../../utils/pipes/exchange-data.pipe'; standalone: true, template: ` @for (data of logData | keyvalue; track data.key) { -

- {{ data.key }}: +

+ {{ data.key }}: @if (isTLogData(data.value)) { } @else { - {{ data.value }} + {{ data.value }} } -

+
} `, imports: [KeyValuePipe, ExchangeDataPipe], diff --git a/src/app/game/game.page.component.ts b/src/app/game/game.page.component.ts index 2637ca0..3b0bedd 100644 --- a/src/app/game/game.page.component.ts +++ b/src/app/game/game.page.component.ts @@ -54,16 +54,22 @@ import { ExchangeDataPipe } from '../../utils/pipes/exchange-data.pipe'; } } } -
+
- +
+ +
`, From e45e5eb48c309ca725e0211f5b05d9e3fb84555b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Buczek?= Date: Wed, 17 Jul 2024 00:42:07 +0200 Subject: [PATCH 05/57] feat: #18 added inputs amazing animation --- tailwind.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tailwind.config.js b/tailwind.config.js index dd8a45a..9ba8c2c 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -62,7 +62,7 @@ module.exports = { function ({ addUtilities }) { addUtilities({ '.custom-input': { - '@apply border-[1px] border-mainCreme rounded-md px-2 py-1 bg-mainGray text-sm xs:text-base text-mainCreme focus:outline-none': + '@apply border-[1px] border-mainCreme rounded-md px-2 py-1 bg-mainGray text-sm xs:text-base text-mainCreme transition-all ease-in-out duration-700 focus:outline-none focus:border-mainOrange': {}, }, }); From df676b78addbe115d179df924de9184a7d4148cf Mon Sep 17 00:00:00 2001 From: Marcin Bator Date: Wed, 17 Jul 2024 13:48:47 +0200 Subject: [PATCH 06/57] fix: #18 overflow position and scroll console fix --- .../components/console/console.component.spec.ts | 16 ---------------- src/app/game/game.page.component.ts | 4 ++-- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/src/app/game/components/console/console.component.spec.ts b/src/app/game/components/console/console.component.spec.ts index 7c47c68..2414f22 100644 --- a/src/app/game/components/console/console.component.spec.ts +++ b/src/app/game/components/console/console.component.spec.ts @@ -19,20 +19,4 @@ describe('ConsoleComponent', () => { it('should create', () => { expect(component).toBeTruthy(); }); - - it('should display log data correctly', () => { - const testLogData = { - '2023-04-01': { message: 'Test message 1', level: 'info' }, - '2023-04-02': { message: 'Test message 2', level: 'error' }, - }; - component.logData = testLogData; - fixture.detectChanges(); - - const compiled = fixture.nativeElement as HTMLElement; - expect(compiled.querySelectorAll('p').length).toBeGreaterThan(2); - expect(compiled.textContent).toContain('2023-04-01'); - expect(compiled.textContent).toContain('Test message 1'); - expect(compiled.textContent).toContain('2023-04-02'); - expect(compiled.textContent).toContain('Test message 2'); - }); }); diff --git a/src/app/game/game.page.component.ts b/src/app/game/game.page.component.ts index 3b0bedd..8daa5fc 100644 --- a/src/app/game/game.page.component.ts +++ b/src/app/game/game.page.component.ts @@ -54,7 +54,7 @@ import { ExchangeDataPipe } from '../../utils/pipes/exchange-data.pipe'; } } } -
+
- @if (gameDataSendingType === tGameDataSendingType.TimeGame) { - + }} +
+ @if (aiSocketService.getIsSocketConnected()) { + + @if (gameDataSendingType === tGameDataSendingType.TimeGame) { + + } + } @else { + } - } @else { - - } +
-
- } + } +
`, }) export class AiSocketMenuComponent implements OnInit, ILoggableDataComponent { diff --git a/src/app/game/components/ai-socket-menu/components/debug-mode-menu/debug-mode-menu.component.ts b/src/app/game/components/ai-socket-menu/components/debug-mode-menu/debug-mode-menu.component.ts index 124ba16..586ec8c 100644 --- a/src/app/game/components/ai-socket-menu/components/debug-mode-menu/debug-mode-menu.component.ts +++ b/src/app/game/components/ai-socket-menu/components/debug-mode-menu/debug-mode-menu.component.ts @@ -8,8 +8,11 @@ import { Component, EventEmitter, Output } from '@angular/core'; - Debug Mode + Debug Mode ({{ debugCheckbox.checked ? 'ON' : 'OFF' }}) `, }) export class DebugModeMenuComponent { diff --git a/src/app/game/components/ai-socket-menu/components/debug-mode-panel/debug-mode-panel.component.ts b/src/app/game/components/ai-socket-menu/components/debug-mode-panel/debug-mode-panel.component.ts index fcd3e0b..9f64234 100644 --- a/src/app/game/components/ai-socket-menu/components/debug-mode-panel/debug-mode-panel.component.ts +++ b/src/app/game/components/ai-socket-menu/components/debug-mode-panel/debug-mode-panel.component.ts @@ -11,7 +11,7 @@ import { KeyValuePipe } from '@angular/common'; {{ variable.key }}: + } @else { - } diff --git a/src/app/game/components/ai-socket-menu/components/socket-domain-input/socket-domain-input.component.ts b/src/app/game/components/ai-socket-menu/components/socket-domain-input/socket-domain-input.component.ts index ab7e699..df10aa0 100644 --- a/src/app/game/components/ai-socket-menu/components/socket-domain-input/socket-domain-input.component.ts +++ b/src/app/game/components/ai-socket-menu/components/socket-domain-input/socket-domain-input.component.ts @@ -6,8 +6,9 @@ import { Component, EventEmitter, Input, Output } from '@angular/core'; imports: [], template: ` diff --git a/src/app/game/components/data-menu/components/collect-toggle-button/collect-toggle-button.component.ts b/src/app/game/components/data-menu/components/collect-toggle-button/collect-toggle-button.component.ts index 62d2b9d..a609a4b 100644 --- a/src/app/game/components/data-menu/components/collect-toggle-button/collect-toggle-button.component.ts +++ b/src/app/game/components/data-menu/components/collect-toggle-button/collect-toggle-button.component.ts @@ -5,6 +5,7 @@ import { Component, Input } from '@angular/core'; standalone: true, template: ` - + }
diff --git a/src/app/game/game.page.component.ts b/src/app/game/game.page.component.ts index 8daa5fc..ba46666 100644 --- a/src/app/game/game.page.component.ts +++ b/src/app/game/game.page.component.ts @@ -20,12 +20,32 @@ import { ExchangeDataPipe } from '../../utils/pipes/exchange-data.pipe';
@if (game) {
+ + +
+ }} bg-lightGray overflow-y-scroll z-50"> +
`, diff --git a/src/app/game/components/console/console.component.ts b/src/app/game/components/console/console.component.ts index b42eba3..eadc3e5 100644 --- a/src/app/game/components/console/console.component.ts +++ b/src/app/game/components/console/console.component.ts @@ -8,7 +8,7 @@ import { ExchangeDataPipe } from '../../../../utils/pipes/exchange-data.pipe'; standalone: true, template: ` @for (data of logData | keyvalue; track data.key) { -
+
{{ data.key }}: @if (isTLogData(data.value)) { diff --git a/src/app/game/game.page.component.ts b/src/app/game/game.page.component.ts index ba46666..89f9e7e 100644 --- a/src/app/game/game.page.component.ts +++ b/src/app/game/game.page.component.ts @@ -17,7 +17,7 @@ import { ExchangeDataPipe } from '../../utils/pipes/exchange-data.pipe'; selector: 'app-game', standalone: true, template: ` -
+
@if (game) {
diff --git a/src/app/game/components/ai-socket-menu/components/socket-connected-menu/socket-connected-menu.component.ts b/src/app/game/components/ai-socket-menu/components/socket-connected-menu/socket-connected-menu.component.ts index 706456e..dca0d43 100644 --- a/src/app/game/components/ai-socket-menu/components/socket-connected-menu/socket-connected-menu.component.ts +++ b/src/app/game/components/ai-socket-menu/components/socket-connected-menu/socket-connected-menu.component.ts @@ -9,7 +9,7 @@ import { TGameDataSendingType } from '../../../../models/game-data-sending-type. @if (isDataSendingActive) { } @else { @@ -26,7 +26,7 @@ import { TGameDataSendingType } from '../../../../models/game-data-sending-type. " /> } diff --git a/src/app/game/components/data-menu/data-menu.component.ts b/src/app/game/components/data-menu/data-menu.component.ts index 29e36c0..c0edf8a 100644 --- a/src/app/game/components/data-menu/data-menu.component.ts +++ b/src/app/game/components/data-menu/data-menu.component.ts @@ -35,7 +35,7 @@ import { DataSelectCheckboxComponent } from './components/data-select-checkbox/d } diff --git a/src/app/game/game.page.component.ts b/src/app/game/game.page.component.ts index 89f9e7e..d08f035 100644 --- a/src/app/game/game.page.component.ts +++ b/src/app/game/game.page.component.ts @@ -22,13 +22,16 @@ import { ExchangeDataPipe } from '../../utils/pipes/exchange-data.pipe';
From 0397505ce124e31a17bdc2720ff05236e814e2d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Buczek?= Date: Wed, 31 Jul 2024 16:19:23 +0200 Subject: [PATCH 33/57] feat: #27 small additions --- src/app/shared/components/navbar/game-list.component.ts | 1 + src/app/shared/components/navbar/navbar.component.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/app/shared/components/navbar/game-list.component.ts b/src/app/shared/components/navbar/game-list.component.ts index 78c56b7..16bfa06 100644 --- a/src/app/shared/components/navbar/game-list.component.ts +++ b/src/app/shared/components/navbar/game-list.component.ts @@ -21,6 +21,7 @@ import { RouterModule } from '@angular/router'; class="border-mainOrange w-2/5 group-hover:w-full ease-in-out transition-all duration-500" /> } +
  • Read more about our games...
  • `, }) diff --git a/src/app/shared/components/navbar/navbar.component.ts b/src/app/shared/components/navbar/navbar.component.ts index 4c563f9..a80b755 100644 --- a/src/app/shared/components/navbar/navbar.component.ts +++ b/src/app/shared/components/navbar/navbar.component.ts @@ -15,7 +15,7 @@ import * as feather from 'feather-icons'; class="flex mx-auto w-full flex-row items-center justify-between font-mono text-mainOrange">
    - + Logo Date: Thu, 1 Aug 2024 18:13:02 +0200 Subject: [PATCH 34/57] feat: #27 part of rwd for navbar --- package-lock.json | 21 +++++++++++++-- package.json | 1 + src/app/app.component.ts | 4 +-- .../components/navbar/game-list.component.ts | 8 +++--- .../components/navbar/navbar.component.ts | 27 ++++++++++++------- 5 files changed, 44 insertions(+), 17 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2b902f1..bffd289 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,7 @@ "version": "0.0.0", "dependencies": { "@angular/animations": "^18.0.0", + "@angular/cdk": "^18.1.3", "@angular/common": "^18.0.0", "@angular/compiler": "^18.0.0", "@angular/core": "^18.0.0", @@ -948,6 +949,22 @@ } } }, + "node_modules/@angular/cdk": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-18.1.3.tgz", + "integrity": "sha512-u14xbuXQz+36nBeHSwRcwRoS64WNhOdK97H47nI1WaIZZaGGvKHR1Wwk2XletDRtIHv2622sJm8h+dbaBNeTGQ==", + "dependencies": { + "tslib": "^2.3.0" + }, + "optionalDependencies": { + "parse5": "^7.1.2" + }, + "peerDependencies": { + "@angular/common": "^18.0.0 || ^19.0.0", + "@angular/core": "^18.0.0 || ^19.0.0", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, "node_modules/@angular/cli": { "version": "18.0.5", "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-18.0.5.tgz", @@ -8401,7 +8418,7 @@ "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "dev": true, + "devOptional": true, "engines": { "node": ">=0.12" }, @@ -13735,7 +13752,7 @@ "version": "7.1.2", "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", - "dev": true, + "devOptional": true, "dependencies": { "entities": "^4.4.0" }, diff --git a/package.json b/package.json index e98568e..e11b9c0 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "private": true, "dependencies": { "@angular/animations": "^18.0.0", + "@angular/cdk": "^18.1.3", "@angular/common": "^18.0.0", "@angular/compiler": "^18.0.0", "@angular/core": "^18.0.0", diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 52eb4e9..bdec9be 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -2,8 +2,6 @@ import { Component } from '@angular/core'; import { RouterOutlet } from '@angular/router'; import { NavbarComponent } from './shared/components/navbar/navbar.component'; import { FooterComponent } from './shared/components/footer/footer.component'; -import { HttpClientModule } from '@angular/common/http'; -import { JsonPipe } from '@angular/common'; @Component({ selector: 'app-root', @@ -11,7 +9,7 @@ import { JsonPipe } from '@angular/common'; imports: [RouterOutlet, NavbarComponent, FooterComponent], template: ` -
    +
    diff --git a/src/app/shared/components/navbar/game-list.component.ts b/src/app/shared/components/navbar/game-list.component.ts index 16bfa06..cce4161 100644 --- a/src/app/shared/components/navbar/game-list.component.ts +++ b/src/app/shared/components/navbar/game-list.component.ts @@ -6,7 +6,7 @@ import { RouterModule } from '@angular/router'; standalone: true, imports: [RouterModule], template: ` -
    diff --git a/src/app/shared/components/error-pages/error500.page.component.ts b/src/app/shared/components/error-pages/error500.page.component.ts index 2999bad..aa14f52 100644 --- a/src/app/shared/components/error-pages/error500.page.component.ts +++ b/src/app/shared/components/error-pages/error500.page.component.ts @@ -18,8 +18,7 @@ import { Component } from '@angular/core'; ngSrc="images/rag-2.png" alt="Logo" class="object-contain" - fill - priority /> + fill />
    From e73fbaf90c5ebf884fae6a7780b117b7ab8a67a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Buczek?= Date: Mon, 5 Aug 2024 23:14:32 +0200 Subject: [PATCH 43/57] feat: #27 added HostListener to navbar's game-list --- .../components/navbar/navbar.component.ts | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/app/shared/components/navbar/navbar.component.ts b/src/app/shared/components/navbar/navbar.component.ts index 950e2c4..85bd212 100644 --- a/src/app/shared/components/navbar/navbar.component.ts +++ b/src/app/shared/components/navbar/navbar.component.ts @@ -1,5 +1,11 @@ import { NgOptimizedImage } from '@angular/common'; -import { Component, AfterViewInit, OnInit, OnDestroy } from '@angular/core'; +import { + Component, + AfterViewInit, + OnInit, + OnDestroy, + HostListener, +} from '@angular/core'; import { Router, NavigationStart, RouterModule } from '@angular/router'; import { GameListComponent } from './game-list.component'; import { BreakpointObserver, BreakpointState } from '@angular/cdk/layout'; @@ -30,7 +36,7 @@ import { Subscription } from 'rxjs'; }}
    + class="game-list-container text-xl xs:text-2xl flex flex-col w-3/5 2xs:w-1/2 sm:w-2/5 md:w-[30%] lg:w-1/4 xl:w-1/6 relative items-center justify-center"> }
    +
    + We encourage you to check: + {{ currentChoosenAuthor.githubName }} +
    @@ -82,6 +96,12 @@ import { Component } from '@angular/core';
    `, }) export class HomePageComponent { + public currentChoosenAuthor = { index: -1, githubName: '' }; + + public chooseAuthor(index: number, githubName: string): void { + this.currentChoosenAuthor = { index, githubName }; + } + public authors = [ { name: 'Marcin Bator', From c5a48e6a16608eb9104eaa49652c35e7774b7d36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Buczek?= Date: Fri, 9 Aug 2024 00:03:26 +0200 Subject: [PATCH 50/57] feat: #29 added animation with IntersectionObserver --- src/app/home/home.page.component.ts | 149 ++++++++++++++++------------ 1 file changed, 88 insertions(+), 61 deletions(-) diff --git a/src/app/home/home.page.component.ts b/src/app/home/home.page.component.ts index 18f1ea5..b9bccf0 100644 --- a/src/app/home/home.page.component.ts +++ b/src/app/home/home.page.component.ts @@ -1,73 +1,78 @@ import { NgOptimizedImage } from '@angular/common'; -import { Component } from '@angular/core'; +import { Component, ElementRef, OnInit } from '@angular/core'; @Component({ selector: 'app-home-page', standalone: true, imports: [NgOptimizedImage], template: `
    -
    -
    -

    - What's going on here? -

    - Authors: -
    - @for (author of authors; track author.name) { - + } +
    +
    - We encourage you to check: - {{ currentChoosenAuthor.githubName }} + class="flex w-full pt-24 md:pt-0 md:w-1/3 items-center justify-center"> +
    + Logo +
    -
    - Logo -
    + class="flex w-full text-xl items-end justify-end text-mainCreme font-mono mt-20 xl:mt-10"> + + Explore the world of interactive learning and entertainment with our + innovative web application! Our project is more than just a collection + of mini-games - it's a true fusion of artificial intelligence and + entertainment. We have designed an application that not only provides + great fun but also allows for data collection and strategy learning + for artificial intelligence. +
    - - Explore the world of interactive learning and entertainment with our - innovative web application! Our project is more than just a collection - of mini-games - it's a true fusion of artificial intelligence and - entertainment. We have designed an application that not only provides - great fun but also allows for data collection and strategy learning for - artificial intelligence. - -
    -
    + class="flex flex-row justify-between mt-10 pl-8 md:pl-16 bg-lightGray pt-10 pb-6 md:py-10">
    @@ -86,22 +91,19 @@ import { Component } from '@angular/core'; +4 players
    -
    +
    + id="animatedElement" + class="transform transition-all duration-1000 flex w-full 2xs:w-[97%] xs:w-11/12 sm:w-4/5 md:w-2/3 lg:w-1/2 h-14 xs:h-20 items-center justify-center bg-mainOrange text-2xs 2xs:text-xs xs:text-sm sm:text-base lg:text-lg px-2 xs:px-4 sm:px-10 font-mono mt-0 2xs:mt-4 xs:mt-8 sm:mt-16"> Don't wait any longer - join our community and start your adventure with interactive learning and entertainment today!
    `, }) -export class HomePageComponent { +export class HomePageComponent implements OnInit { public currentChoosenAuthor = { index: -1, githubName: '' }; - public chooseAuthor(index: number, githubName: string): void { - this.currentChoosenAuthor = { index, githubName }; - } - public authors = [ { name: 'Marcin Bator', @@ -116,4 +118,29 @@ export class HomePageComponent { githubName: 'bkrowka', }, ]; + + public constructor(private _el: ElementRef) {} + + public ngOnInit(): void { + const observer = new IntersectionObserver(entries => { + entries.forEach(entry => { + if (entry.isIntersecting) { + entry.target.classList.remove('opacity-0', '-translate-x-96'); + } else { + entry.target.classList.add('opacity-0', '-translate-x-96'); + } + }); + }); + + const element = this._el.nativeElement.querySelector('#animatedElement'); + observer.observe(element); + } + + public chooseAuthor(index: number, githubName: string): void { + if (index === this.currentChoosenAuthor.index) { + this.currentChoosenAuthor = { index: -1, githubName }; + } else { + this.currentChoosenAuthor = { index, githubName }; + } + } } From 8343c6479a33289eb21be6ff051f1a5fec461a18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Buczek?= Date: Sat, 10 Aug 2024 01:21:02 +0200 Subject: [PATCH 51/57] feat: #29 added author-info cards --- src/app/home/home.page.component.ts | 117 ++++++++++++++++++++++++---- 1 file changed, 100 insertions(+), 17 deletions(-) diff --git a/src/app/home/home.page.component.ts b/src/app/home/home.page.component.ts index b9bccf0..c0c373d 100644 --- a/src/app/home/home.page.component.ts +++ b/src/app/home/home.page.component.ts @@ -1,5 +1,13 @@ +/* eslint-disable max-lines */ import { NgOptimizedImage } from '@angular/common'; -import { Component, ElementRef, OnInit } from '@angular/core'; +import { + AfterViewChecked, + AfterViewInit, + Component, + ElementRef, + OnInit, +} from '@angular/core'; +import feather from 'feather-icons'; @Component({ selector: 'app-home-page', @@ -9,7 +17,8 @@ import { Component, ElementRef, OnInit } from '@angular/core';
    -
    +

    What's going on here? @@ -33,22 +42,15 @@ import { Component, ElementRef, OnInit } from '@angular/core'; }

    -
    - We encourage you to check: - {{ currentChoosenAuthor.githubName }} -
    -
    + class="flex w-full pt-24 md:pt-0 md:w-1/3 items-center justify-center relative"> +
    Logo
    + @for (author of authors; track author.name) { +
    +

    {{ author.name }}

    +
    +

    {{ author.role }}

    +

    + Main tech-stack: +

    +
    + @for (stackItem of author.techStack; track stackItem) { + +

    {{ stackItem }}

    + } +
    +

    + Hobbies and interests: +

    +

    + {{ author.hobbies }} +

    + +
    + }
    `, }) -export class HomePageComponent implements OnInit { +export class HomePageComponent + implements OnInit, AfterViewInit, AfterViewChecked +{ public currentChoosenAuthor = { index: -1, githubName: '' }; public authors = [ { name: 'Marcin Bator', githubName: 'marcinbator', + linkedinName: 'mbator', + role: 'Tył-dev', + techStack: [ + 'sranie', + 'pedałowanie', + 'pierdolenie', + 'wpierdalanie', + 'spanie', + ], + hobbies: 'no hobbies', }, { name: 'Paweł Buczek', githubName: 'pablitoo1', + linkedinName: 'pbuczek', + role: 'Frontend Developer', + techStack: [ + 'TypeScript', + 'JavaScript', + 'Angular', + 'React/Next.js', + 'Babylon.js', + 'CSS/TailwindCSS', + ], + hobbies: + 'computer engineering student, creating web pages and apps, practicing and watching sports', }, { name: 'Bartłomiej Krówka', githubName: 'bkrowka', + linkedinName: 'bkrowka', + role: 'sztuczny dev', + techStack: ['Pytong', 'JavaScript', 'CHasz', 'React/Next.js', 'HTML5'], + hobbies: 'jebanie karola', }, ]; @@ -136,6 +211,14 @@ export class HomePageComponent implements OnInit { observer.observe(element); } + public ngAfterViewInit(): void { + feather.replace(); + } + + public ngAfterViewChecked(): void { + feather.replace(); + } + public chooseAuthor(index: number, githubName: string): void { if (index === this.currentChoosenAuthor.index) { this.currentChoosenAuthor = { index: -1, githubName }; From 2e9a2524810f74b30d8252116f6c197adfe46bfb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Buczek?= Date: Sun, 11 Aug 2024 16:39:10 +0200 Subject: [PATCH 52/57] feat: #29 linkedin names --- src/app/home/home.page.component.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/home/home.page.component.ts b/src/app/home/home.page.component.ts index c0c373d..6c4a8aa 100644 --- a/src/app/home/home.page.component.ts +++ b/src/app/home/home.page.component.ts @@ -157,7 +157,7 @@ export class HomePageComponent { name: 'Marcin Bator', githubName: 'marcinbator', - linkedinName: 'mbator', + linkedinName: 'marcin-bator-ofc', role: 'Tył-dev', techStack: [ 'sranie', @@ -187,7 +187,7 @@ export class HomePageComponent { name: 'Bartłomiej Krówka', githubName: 'bkrowka', - linkedinName: 'bkrowka', + linkedinName: '', role: 'sztuczny dev', techStack: ['Pytong', 'JavaScript', 'CHasz', 'React/Next.js', 'HTML5'], hobbies: 'jebanie karola', From 23f6a9db76e5475fa6c87e188de8c503eac70d8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Buczek?= Date: Tue, 13 Aug 2024 22:37:15 +0200 Subject: [PATCH 53/57] refactor: #29 recreate home component structure --- src/app/home/components/.gitkeep | 0 .../components/author-cards.component.spec.ts | 23 ++++ .../home/components/author-cards.component.ts | 73 ++++++++++++ src/app/home/home.page.component.ts | 110 ++---------------- src/app/home/models/.gitkeep | 0 src/app/home/models/author.ts | 43 +++++++ 6 files changed, 146 insertions(+), 103 deletions(-) delete mode 100644 src/app/home/components/.gitkeep create mode 100644 src/app/home/components/author-cards.component.spec.ts create mode 100644 src/app/home/components/author-cards.component.ts delete mode 100644 src/app/home/models/.gitkeep create mode 100644 src/app/home/models/author.ts diff --git a/src/app/home/components/.gitkeep b/src/app/home/components/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/src/app/home/components/author-cards.component.spec.ts b/src/app/home/components/author-cards.component.spec.ts new file mode 100644 index 0000000..e076977 --- /dev/null +++ b/src/app/home/components/author-cards.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { AuthorCardsComponent } from './author-cards.component'; + +describe('AuthorCardsComponent', () => { + let component: AuthorCardsComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [AuthorCardsComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(AuthorCardsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/home/components/author-cards.component.ts b/src/app/home/components/author-cards.component.ts new file mode 100644 index 0000000..378d84f --- /dev/null +++ b/src/app/home/components/author-cards.component.ts @@ -0,0 +1,73 @@ +import { Component, Input } from '@angular/core'; +import { authorsData, IAuthor } from '../models/author'; +import { NgOptimizedImage } from '@angular/common'; + +@Component({ + selector: 'app-author-cards', + standalone: true, + imports: [NgOptimizedImage], + template: ` +
    + Logo +
    + @for (author of authors; track author.name) { +
    +

    {{ author.name }}

    +
    +

    {{ author.role }}

    +

    Main tech-stack:

    +
    + @for (stackItem of author.techStack; track stackItem) { + +

    {{ stackItem }}

    + } +
    +

    + Hobbies and interests: +

    +

    + {{ author.hobbies }} +

    + +
    + } + `, +}) +export class AuthorCardsComponent { + @Input({ required: true }) public currentChoosenAuthor!: { + index: number; + githubName: string; + }; + + public authors: IAuthor[] = authorsData; +} diff --git a/src/app/home/home.page.component.ts b/src/app/home/home.page.component.ts index 6c4a8aa..3626cf9 100644 --- a/src/app/home/home.page.component.ts +++ b/src/app/home/home.page.component.ts @@ -1,4 +1,3 @@ -/* eslint-disable max-lines */ import { NgOptimizedImage } from '@angular/common'; import { AfterViewChecked, @@ -8,11 +7,13 @@ import { OnInit, } from '@angular/core'; import feather from 'feather-icons'; +import { authorsData, IAuthor } from './models/author'; +import { AuthorCardsComponent } from './components/author-cards.component'; @Component({ selector: 'app-home-page', standalone: true, - imports: [NgOptimizedImage], + imports: [NgOptimizedImage, AuthorCardsComponent], template: `
    -
    -
    - Logo -
    - @for (author of authors; track author.name) { -
    -

    {{ author.name }}

    -
    -

    {{ author.role }}

    -

    - Main tech-stack: -

    -
    - @for (stackItem of author.techStack; track stackItem) { - -

    {{ stackItem }}

    - } -
    -

    - Hobbies and interests: -

    -

    - {{ author.hobbies }} -

    - -
    - } -
    +
    @@ -153,46 +96,7 @@ export class HomePageComponent { public currentChoosenAuthor = { index: -1, githubName: '' }; - public authors = [ - { - name: 'Marcin Bator', - githubName: 'marcinbator', - linkedinName: 'marcin-bator-ofc', - role: 'Tył-dev', - techStack: [ - 'sranie', - 'pedałowanie', - 'pierdolenie', - 'wpierdalanie', - 'spanie', - ], - hobbies: 'no hobbies', - }, - { - name: 'Paweł Buczek', - githubName: 'pablitoo1', - linkedinName: 'pbuczek', - role: 'Frontend Developer', - techStack: [ - 'TypeScript', - 'JavaScript', - 'Angular', - 'React/Next.js', - 'Babylon.js', - 'CSS/TailwindCSS', - ], - hobbies: - 'computer engineering student, creating web pages and apps, practicing and watching sports', - }, - { - name: 'Bartłomiej Krówka', - githubName: 'bkrowka', - linkedinName: '', - role: 'sztuczny dev', - techStack: ['Pytong', 'JavaScript', 'CHasz', 'React/Next.js', 'HTML5'], - hobbies: 'jebanie karola', - }, - ]; + public authors: IAuthor[] = authorsData; public constructor(private _el: ElementRef) {} diff --git a/src/app/home/models/.gitkeep b/src/app/home/models/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/src/app/home/models/author.ts b/src/app/home/models/author.ts new file mode 100644 index 0000000..29abd6b --- /dev/null +++ b/src/app/home/models/author.ts @@ -0,0 +1,43 @@ +export interface IAuthor { + name: string; + githubName: string; + linkedinName: string; + role: string; + techStack: string[]; + hobbies: string; +} + +export const authorsData: IAuthor[] = [ + { + name: 'Marcin Bator', + githubName: 'marcinbator', + linkedinName: 'marcin-bator-ofc', + role: 'Tył-dev', + techStack: ['aa', 'bb', 'ee', 'dd', 'ee'], + hobbies: 'no hobbies', + }, + { + name: 'Paweł Buczek', + githubName: 'pablitoo1', + linkedinName: 'pbuczek', + role: 'Frontend Developer', + techStack: [ + 'TypeScript', + 'JavaScript', + 'Angular', + 'React/Next.js', + 'Babylon.js', + 'CSS/TailwindCSS', + ], + hobbies: + 'computer engineering student, creating web pages and apps, practicing and watching sports', + }, + { + name: 'Bartłomiej Krówka', + githubName: 'bkrowka', + linkedinName: '', + role: 'sztuczny dev', + techStack: ['Pytong', 'JavaScript', 'CHasz', 'React/Next.js', 'HTML5'], + hobbies: 'dfgdfg karola', + }, +]; From 5aba743a6a3a6a0fbd9aa57b1abd057e55c89882 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Buczek?= Date: Wed, 14 Aug 2024 00:09:11 +0200 Subject: [PATCH 54/57] feat: #29 rwd for upper home part --- .../home/components/author-cards.component.ts | 38 ++++++++++++------- src/app/home/home.page.component.ts | 21 +++++----- 2 files changed, 35 insertions(+), 24 deletions(-) diff --git a/src/app/home/components/author-cards.component.ts b/src/app/home/components/author-cards.component.ts index 378d84f..00300a8 100644 --- a/src/app/home/components/author-cards.component.ts +++ b/src/app/home/components/author-cards.component.ts @@ -8,9 +8,9 @@ import { NgOptimizedImage } from '@angular/common'; imports: [NgOptimizedImage], template: `
    @for (author of authors; track author.name) {
    -

    {{ author.name }}

    -
    -

    {{ author.role }}

    -

    Main tech-stack:

    +

    + {{ author.name }} +

    +
    +

    + {{ author.role }} +

    +

    + Main tech-stack: +

    @for (stackItem of author.techStack; track stackItem) { -

    {{ stackItem }}

    }
    -

    +

    Hobbies and interests:

    -

    +

    {{ author.hobbies }}

    -
    diff --git a/src/app/home/home.page.component.ts b/src/app/home/home.page.component.ts index 3626cf9..901505d 100644 --- a/src/app/home/home.page.component.ts +++ b/src/app/home/home.page.component.ts @@ -14,21 +14,22 @@ import { AuthorCardsComponent } from './components/author-cards.component'; selector: 'app-home-page', standalone: true, imports: [NgOptimizedImage, AuthorCardsComponent], - template: `
    + template: `
    + class="flex flex-col md:flex-row w-full h-max items-center justify-center md:justify-between lg:justify-evenly text-mainOrange font-mono pb-6">
    + class="flex flex-col space-y-2 2xs:space-y-4 sm:space-y-6 md:space-y-8 mt-4 md:mt-16 pl-0 xs:pl-64 sm:pl-24 md:pl-14 lg:pl-6 pr-0 lg:pr-6 pb-40">

    + class="text-2xl 2xs:text-3xl lg:text-4xl xl:text-5xl h-9 xs:h-10 md:h-12 xl:h-16 relative w-[max-content] font-mono before:absolute before:inset-0 before:animate-typewriter21 before:bg-mainGray after:absolute after:inset-0 after:w-[0.125em] after:animate-caret21 after:bg-black"> What's going on here?

    - Authors:
    + class="grid grid-cols-3 xs:grid-cols-6 md:grid-cols-3 gap-y-10 sm:gap-y-16 lg:flex lg:flex-row w-full gap-x-6 xs:gap-x-36 md:gap-x-3 lg:gap-x-8"> @for (author of authors; track author.name) { @@ -49,9 +50,9 @@ import { AuthorCardsComponent } from './components/author-cards.component'; [currentChoosenAuthor]="currentChoosenAuthor" />
    + class="flex w-full items-end justify-end text-mainCreme font-mono mt-36 2xs:mt-44 sm:mt-40 md:mt-2 xl:mt-10"> + class="w-[97%] lg:w-11/12 xl:w-3/4 pr-2 border-l-2 border-b-2 pl-2 pb-2 border-mainOrange text-justify text-sm md:text-base lg:text-lg xl:text-xl"> Explore the world of interactive learning and entertainment with our innovative web application! Our project is more than just a collection of mini-games - it's a true fusion of artificial intelligence and @@ -84,7 +85,7 @@ import { AuthorCardsComponent } from './components/author-cards.component';
    + class="transform transition-all duration-1000 flex w-full 2xs:w-[97%] xs:w-11/12 sm:w-4/5 md:w-2/3 lg:w-1/2 h-14 xs:h-20 text-justify items-center justify-center bg-mainOrange text-2xs 2xs:text-xs xs:text-sm sm:text-base lg:text-lg px-2 xs:px-4 sm:px-10 font-mono mt-0 2xs:mt-4 xs:mt-8 sm:mt-16"> Don't wait any longer - join our community and start your adventure with interactive learning and entertainment today! From d59481e9873f8b00a0e23f7c7a3c22215a8770ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Buczek?= Date: Wed, 14 Aug 2024 00:25:06 +0200 Subject: [PATCH 55/57] feat: #29 rwd for lower home part --- src/app/home/home.page.component.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/app/home/home.page.component.ts b/src/app/home/home.page.component.ts index 901505d..647c8bc 100644 --- a/src/app/home/home.page.component.ts +++ b/src/app/home/home.page.component.ts @@ -63,10 +63,10 @@ import { AuthorCardsComponent } from './components/author-cards.component';
    + class="flex flex-row justify-between mt-10 pl-2 xs:pl-8 md:pl-16 bg-lightGray pt-10 pb-6 md:py-10">
    + class="h-20 2xs:h-24 xs:h-28 sm:h-36 md:h-52 lg:h-60 xl:h-64 w-44 2xs:w-52 xs:w-64 sm:w-80 md:w-[30rem] lg:w-[34rem] xl:w-[36rem] relative"> Logo
    + class="flex flex-col w-[55%] 2xs:w-2/5 items-start justify-center text-xs 2xs:text-sm xs:text-lg sm:text-2xl md:text-3xl lg:text-4xl space-y-1 md:space-y-5 text-mainOrange border-l-2 border-mainOrange font-mono p-2 md:p-4"> 1 different games 2 gameplays 3 MB of data @@ -85,7 +85,7 @@ import { AuthorCardsComponent } from './components/author-cards.component';
    + class="transform transition-all duration-1000 flex w-full 2xs:w-[97%] xs:w-11/12 sm:w-4/5 md:w-2/3 lg:w-[63%] xl:w-[58%] 2xl:w-1/2 h-14 xs:h-20 text-justify items-center justify-center bg-mainOrange text-2xs 2xs:text-xs xs:text-sm sm:text-base lg:text-lg px-2 xs:px-4 sm:px-10 font-mono mt-0 2xs:mt-4 xs:mt-8 sm:mt-16"> Don't wait any longer - join our community and start your adventure with interactive learning and entertainment today! From 85272fb149a4ac812adf6b0fef0d9b9f94ed525b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Buczek?= Date: Wed, 14 Aug 2024 00:38:16 +0200 Subject: [PATCH 56/57] feat: #29 added correct info about authors --- src/app/home/models/author.ts | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/src/app/home/models/author.ts b/src/app/home/models/author.ts index 29abd6b..b50b3e0 100644 --- a/src/app/home/models/author.ts +++ b/src/app/home/models/author.ts @@ -12,9 +12,17 @@ export const authorsData: IAuthor[] = [ name: 'Marcin Bator', githubName: 'marcinbator', linkedinName: 'marcin-bator-ofc', - role: 'Tył-dev', - techStack: ['aa', 'bb', 'ee', 'dd', 'ee'], - hobbies: 'no hobbies', + role: 'Backend Developer', + techStack: [ + 'Java/Spring Boot', + 'C#/.NET', + 'C++', + 'TypeScript', + 'Angular', + 'SQL/PostgreSQL', + ], + hobbies: + 'developing backend systems, learning new technologies, riding a bike', }, { name: 'Paweł Buczek', @@ -30,14 +38,20 @@ export const authorsData: IAuthor[] = [ 'CSS/TailwindCSS', ], hobbies: - 'computer engineering student, creating web pages and apps, practicing and watching sports', + 'studying computer science, creating web pages and apps, practicing and watching sports', }, { name: 'Bartłomiej Krówka', githubName: 'bkrowka', linkedinName: '', - role: 'sztuczny dev', - techStack: ['Pytong', 'JavaScript', 'CHasz', 'React/Next.js', 'HTML5'], - hobbies: 'dfgdfg karola', + role: 'AI Engineer', + techStack: [ + 'Python', + 'TensorFlow/PyTorch', + 'JavaScript', + 'React/Next.js', + 'CSS/TailwindCSS', + ], + hobbies: 'programming, playing video games, listening to music', }, ]; From 4289e0b1c4c62ef145aa90aa978fcbcec91f67af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Buczek?= Date: Wed, 14 Aug 2024 01:03:56 +0200 Subject: [PATCH 57/57] feat: #29 added new tests --- .../components/author-cards.component.spec.ts | 42 ++++++++++++++-- .../home/components/author-cards.component.ts | 2 +- src/app/home/home.page.component.spec.ts | 49 +++++++++++++++++-- 3 files changed, 84 insertions(+), 9 deletions(-) diff --git a/src/app/home/components/author-cards.component.spec.ts b/src/app/home/components/author-cards.component.spec.ts index e076977..ebc0050 100644 --- a/src/app/home/components/author-cards.component.spec.ts +++ b/src/app/home/components/author-cards.component.spec.ts @@ -1,6 +1,8 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; - +import { By } from '@angular/platform-browser'; import { AuthorCardsComponent } from './author-cards.component'; +import { authorsData, IAuthor } from '../models/author'; +import { NgOptimizedImage } from '@angular/common'; describe('AuthorCardsComponent', () => { let component: AuthorCardsComponent; @@ -8,16 +10,46 @@ describe('AuthorCardsComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [AuthorCardsComponent] - }) - .compileComponents(); + imports: [NgOptimizedImage, AuthorCardsComponent], + }).compileComponents(); fixture = TestBed.createComponent(AuthorCardsComponent); component = fixture.componentInstance; - fixture.detectChanges(); }); it('should create', () => { expect(component).toBeTruthy(); }); + + it('should hide the author card when no author is selected', () => { + component.currentChoosenAuthor = { index: -1, githubName: '' }; + fixture.detectChanges(); + + const cardElements = fixture.debugElement.queryAll(By.css('.author-card')); + const targetCardElement = cardElements[0].nativeElement; + + const computedStyle = window.getComputedStyle(targetCardElement); + + expect(computedStyle.opacity).toBe('0'); + expect(computedStyle.right).toContain('-800px'); + }); + + it('should display the correct GitHub and LinkedIn links for the selected author', () => { + component.currentChoosenAuthor = { index: 0, githubName: 'marcinbator' }; + fixture.detectChanges(); + + const githubLink = fixture.debugElement.query( + By.css('a[href^="https://github.com/"]') + ).nativeElement; + const linkedinLink = fixture.debugElement.query( + By.css('a[href^="https://linkedin.com/in/"]') + ).nativeElement; + + expect(githubLink.getAttribute('href')).toBe( + `https://github.com/${authorsData[0].githubName}` + ); + expect(linkedinLink.getAttribute('href')).toBe( + `https://linkedin.com/in/${authorsData[0].linkedinName}` + ); + }); }); diff --git a/src/app/home/components/author-cards.component.ts b/src/app/home/components/author-cards.component.ts index 00300a8..e331279 100644 --- a/src/app/home/components/author-cards.component.ts +++ b/src/app/home/components/author-cards.component.ts @@ -22,7 +22,7 @@ import { NgOptimizedImage } from '@angular/common';
    @for (author of authors; track author.name) {
    { let component: HomePageComponent; @@ -8,7 +11,7 @@ describe('HomePageComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [HomePageComponent], + imports: [NgOptimizedImage, AuthorCardsComponent, HomePageComponent], }).compileComponents(); fixture = TestBed.createComponent(HomePageComponent); @@ -16,7 +19,47 @@ describe('HomePageComponent', () => { fixture.detectChanges(); }); - it('should create', () => { + it('should create the component', () => { expect(component).toBeTruthy(); }); + + it('should have initial currentChoosenAuthor as index -1 and empty githubName', () => { + expect(component.currentChoosenAuthor).toEqual({ + index: -1, + githubName: '', + }); + }); + + it('should update currentChoosenAuthor when chooseAuthor is called', () => { + component.chooseAuthor(0, 'testGithubName'); + expect(component.currentChoosenAuthor).toEqual({ + index: 0, + githubName: 'testGithubName', + }); + + component.chooseAuthor(0, 'testGithubName'); + expect(component.currentChoosenAuthor).toEqual({ + index: -1, + githubName: 'testGithubName', + }); + }); + + it('should call feather.replace() in ngAfterViewInit and ngAfterViewChecked', () => { + const featherReplaceSpy = spyOn(feather, 'replace'); + + component.ngAfterViewInit(); + expect(featherReplaceSpy).toHaveBeenCalled(); + + component.ngAfterViewChecked(); + expect(featherReplaceSpy).toHaveBeenCalledTimes(2); + }); + + it('should pass currentChoosenAuthor to AuthorCardsComponent', () => { + const authorCardsComponent = fixture.debugElement.query( + By.directive(AuthorCardsComponent) + ).componentInstance; + expect(authorCardsComponent.currentChoosenAuthor).toEqual( + component.currentChoosenAuthor + ); + }); });