From 0667b49669c3e21e16dcd820346c76fcb80b8ec4 Mon Sep 17 00:00:00 2001 From: Danaorlov1005 Date: Thu, 1 Apr 2021 15:19:45 +0300 Subject: [PATCH 01/21] added service --- package-lock.json | 2 +- .../@ansyn/ansyn/assets/important/Capture.JPG | Bin 0 -> 40416 bytes .../@ansyn/ansyn/assets/important/aviv.JPG | Bin 0 -> 8309 bytes .../@ansyn/ansyn/assets/important/dana.JPG | Bin 0 -> 8130 bytes .../@ansyn/ansyn/assets/important/elor.JPG | Bin 0 -> 8338 bytes .../@ansyn/ansyn/assets/important/pini.JPG | Bin 0 -> 8356 bytes src/app/@ansyn/ansyn/assets/important/rom.JPG | Bin 0 -> 8275 bytes .../click-outside/click-outside.service.ts | 2 +- .../@ansyn/ansyn/modules/core/core.module.ts | 4 +- .../services/keys-listener.service.spec.ts | 16 + .../core/services/keys-listener.service.ts | 45 +++ .../pacman-popup/pacman-popup.component.html | 2 + .../pacman-popup/pacman-popup.component.less | 65 ++++ .../pacman-popup.component.spec.ts | 25 ++ .../pacman-popup/pacman-popup.component.ts | 315 ++++++++++++++++++ .../overlay-navigation-bar.component.ts | 127 ++++--- .../components/tools/tools.module.ts | 3 +- .../components/tools/tools/tools.component.ts | 33 +- 18 files changed, 586 insertions(+), 53 deletions(-) create mode 100644 src/app/@ansyn/ansyn/assets/important/Capture.JPG create mode 100644 src/app/@ansyn/ansyn/assets/important/aviv.JPG create mode 100644 src/app/@ansyn/ansyn/assets/important/dana.JPG create mode 100644 src/app/@ansyn/ansyn/assets/important/elor.JPG create mode 100644 src/app/@ansyn/ansyn/assets/important/pini.JPG create mode 100644 src/app/@ansyn/ansyn/assets/important/rom.JPG create mode 100644 src/app/@ansyn/ansyn/modules/core/services/keys-listener.service.spec.ts create mode 100644 src/app/@ansyn/ansyn/modules/core/services/keys-listener.service.ts create mode 100644 src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.html create mode 100644 src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.less create mode 100644 src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.spec.ts create mode 100644 src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.ts diff --git a/package-lock.json b/package-lock.json index 9dfb38a810..5a110fa47e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9670,7 +9670,7 @@ "dependencies": { "ansi-colors": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", + "resolved": "http://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==", "dev": true, "requires": { diff --git a/src/app/@ansyn/ansyn/assets/important/Capture.JPG b/src/app/@ansyn/ansyn/assets/important/Capture.JPG new file mode 100644 index 0000000000000000000000000000000000000000..06f051750c20b4fd6a906c067e278656affc0867 GIT binary patch literal 40416 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 z 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 WvYdxY3c_;4IpRDlSG#(fzUfbADDGka literal 0 HcmV?d00001 diff --git a/src/app/@ansyn/ansyn/assets/important/dana.JPG b/src/app/@ansyn/ansyn/assets/important/dana.JPG new file mode 100644 index 0000000000000000000000000000000000000000..76bf234e427a312eff59b9859d7f3a4127ad083a GIT binary patch literal 8130 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 VT;!i`%{mk4b1ONjxahQ_`cJ(l2ABW< literal 0 HcmV?d00001 diff --git a/src/app/@ansyn/ansyn/assets/important/rom.JPG b/src/app/@ansyn/ansyn/assets/important/rom.JPG new file mode 100644 index 0000000000000000000000000000000000000000..ed64683a10cc63dc7fc500c673d5c41a5e2a8497 GIT binary patch literal 8275 zcmeI1dr%Wc9LM*#goFS}5J9L41`tKU|~8MjLpC*IB0PYKoA7vzy}yxtnM!`5GnvdLV!B}fC=b`H9(<-zy~1nfC;qe zup@F40cb<*fVujs0o{veB7eELUAI?ZF zdcEFLFZ4{*#$tT2Sd8%mm_WdV9^8~PjSe?(H7U*`69g(#Br06xB~vK8xH4R*;PUwjoQo@je6B($RCs&w=L%GO8D}KCLOvQjDOH;=6k8$3 zlnF|;Qlm?OH24??8&3Ll#e|4PgT53$)Chef0a_)lQwGB7OD-svC*%sm5q~YRr%>cA z#a{4}VkC^`5`DdyzY;B9sX{K1les5qhr=&ZCjYzDP9S{Aqw}yj_%Uq2Y2ltTGc%K7 z&qw?_f}s|;<>0u{4GKp({Rf2#GA_szE(+JU2#m{_+FcZ`aS<4oGqt<^XSl`=xk?Q@ z+3MjD*4P9BfC++-??^%EC|OKtG?dOTWiZIfG&472GFeOpgJsELnOnfZFq<&Z(qaN> zlar9c$x-mNU^1Ab$M}k|3b2`AGO$4r4lrROC>t?W14noVNr%^!K}=8@-4v$8 zGKUVwtzh~nY66p`)8PFi@)7I@G&bFO27kWkq%fSpNwyJe$Sq(85KFgO^3T8yU5H#Y(wCsfvvw-cQk`exNs` zrEmNsGi%f4EuZFn{>AqE9bfL;Ra~-n-`D#O96WTi?AY=06DPm@?#$WhbLVSnFI>EG z^;-S)h8vAHTUzh^^z;1(zdUT~deZ${Pw&&d{@+Pm2tbErjVgOV7aQs_fonixkh%~P zJ*+63MxVhqwVofwz>_C&1RIz({<%e^r_G#&;hmFZ+RH3k7g39A7b$H>*{cc5_(#e{ zg^lUD2`o?qE*{DTexPT4pU08*wXNG4%c^!UHa;^ybgNHaJ>5MkB)B{J*aAY-H05?! zIHxKzFU@?S&^|D;D=Ssm`D356-}#O$m9zgSd28YI!C8iiYKM75gIzmu(8IfQb#3Mn zJCBE$d*~WJ{uwdg_KL)=A)x~m9qS5R`wG{tyX@GR#I31{*(!OO z+1eLdbY~@@Z?Nq>G0Bj%-nVtigFM%~i0m7OL+`9viWh3ubro06>)Y4m*?q>*P8tJjPrv>&G&*1AE@w+ ztpByAthA+&F2z$@3(fC(JZ_RNZ;q~6i`8asc1f;qXBxqKsnUicgXbdih?uGQs@>mP zH?3av&F$LS2J_zNfurl%ekdrhZ`%5CTyf>}y%Fxg?53Ctjwv~hG8_6&)%M3%dq)*o n^i&i$*sE39^;y%@8R&LKk;lTAm9vT~>qNME+s6Ft8e`+1!U^0p literal 0 HcmV?d00001 diff --git a/src/app/@ansyn/ansyn/modules/core/click-outside/click-outside.service.ts b/src/app/@ansyn/ansyn/modules/core/click-outside/click-outside.service.ts index 0ab48dede3..200e16ab59 100644 --- a/src/app/@ansyn/ansyn/modules/core/click-outside/click-outside.service.ts +++ b/src/app/@ansyn/ansyn/modules/core/click-outside/click-outside.service.ts @@ -23,7 +23,7 @@ export class ClickOutsideService { ) } - // for chrome44 + // for chrome44 - AD MATAY private getPath(event) { const currentElement = event.target; const eventTarget = [currentElement]; diff --git a/src/app/@ansyn/ansyn/modules/core/core.module.ts b/src/app/@ansyn/ansyn/modules/core/core.module.ts index 1e3504cc35..2f677ce8d4 100644 --- a/src/app/@ansyn/ansyn/modules/core/core.module.ts +++ b/src/app/@ansyn/ansyn/modules/core/core.module.ts @@ -17,6 +17,7 @@ import { HTTP_INTERCEPTORS } from '@angular/common/http'; import { CacheInterceptorsService } from './services/http-request-cache/cache-interceptors.service'; import { CacheRequestService } from './services/http-request-cache/cache-request.service'; import { CredentialsService } from './services/credentials/credentials.service'; +import { KeysListenerService } from "./services/keys-listener.service"; @NgModule({ imports: [ @@ -33,7 +34,8 @@ import { CredentialsService } from './services/credentials/credentials.service'; AreaToCredentialsService, CredentialsService, CacheRequestService, - { provide: HTTP_INTERCEPTORS, useClass: CacheInterceptorsService, multi: true} + KeysListenerService, + {provide: HTTP_INTERCEPTORS, useClass: CacheInterceptorsService, multi: true} ], exports: [ AnsynTranslationModule, diff --git a/src/app/@ansyn/ansyn/modules/core/services/keys-listener.service.spec.ts b/src/app/@ansyn/ansyn/modules/core/services/keys-listener.service.spec.ts new file mode 100644 index 0000000000..99f9ac1de2 --- /dev/null +++ b/src/app/@ansyn/ansyn/modules/core/services/keys-listener.service.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { KeysListenerService } from './keys-listener.service'; + +describe('KeysListenerService', () => { + let service: KeysListenerService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(KeysListenerService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/src/app/@ansyn/ansyn/modules/core/services/keys-listener.service.ts b/src/app/@ansyn/ansyn/modules/core/services/keys-listener.service.ts new file mode 100644 index 0000000000..2c8c6e7e78 --- /dev/null +++ b/src/app/@ansyn/ansyn/modules/core/services/keys-listener.service.ts @@ -0,0 +1,45 @@ +import { Injectable, Output, EventEmitter, HostListener, OnInit } from '@angular/core'; +import { fromEvent } from "rxjs"; +import { take } from "rxjs/operators"; + +@Injectable({providedIn: 'any'}) +export class KeysListenerService { + + @Output() keyup = new EventEmitter(); + @Output() keypress = new EventEmitter(); + @Output() keydown = new EventEmitter(); + events: string[] = ['keypress', 'keyup', 'keydown']; + + constructor() { + console.log("medabeg im hadpasot"); + this.events.forEach(eventName => fromEvent(document, eventName).subscribe(($event: KeyboardEvent ) => + { + if (this.isElementNotValid($event)) { + return; + } + this[`${eventName}`].emit($event) + })) + } + + isElementNotValid($event: KeyboardEvent) { + const {activeElement} = ($event.view).document; + return this.isElementInput(activeElement) || this.isTimePicker(activeElement); + } + + isElementInput(activeElement) { + return activeElement instanceof HTMLInputElement; + } + + isTimePicker(activeElement) { + const {className} = activeElement; + return className.includes('owl') || className.includes('title'); + } + + keyWasUsed(event: KeyboardEvent, key: string, keycode: number = key.charCodeAt(0)): boolean { + return event.key === key;// tslint:disable-line + } + + keysWereUsed(event: KeyboardEvent, keys: string[]): boolean { + return keys.some(key => this.keyWasUsed(event, key)); + } +} diff --git a/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.html b/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.html new file mode 100644 index 0000000000..2f7f47af75 --- /dev/null +++ b/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.html @@ -0,0 +1,2 @@ +
+

Score:0

\ No newline at end of file diff --git a/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.less b/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.less new file mode 100644 index 0000000000..d70e18433f --- /dev/null +++ b/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.less @@ -0,0 +1,65 @@ +.grid { + display: flex; + flex-wrap: wrap; + width: 560px; + height: 560px; + border: solid black; + background-color: black; +} + +.grid div { + width: 20px; + height: 20px; +} + +.pac-dot { + background-color: white; + border: 7px solid black; + box-sizing: border-box; + border-radius: 50%; +} + +.wall { + background-color: blue; +} + +.power-pellet { + background-color: rgb(140, 206, 255); + border-radius: 50%; + border: 3px solid black; + box-sizing: border-box; +} + +.Elor { + background: url('../../../assets/important/elor.JPG'); + box-sizing: border-box; + background-color: darkred; +} + +.Pini { + background: url('../../../assets/important/aviv.JPG'); + box-sizing: border-box; + background-color: purple; +} + +.Aviv { + background: url('../../../assets/important/rom.JPG'); + box-sizing: border-box; + background-color: cyan; +} + +.Rom { + background: url('../../../assets/important/pini.JPG'); + box-sizing: border-box; + background-color: orange; +} + + +.pac-man { + background-color: yellow; + border-radius: 50%; +} + +.scared-ghost { + background: url('../../../assets/important/dana.JPG'); +} \ No newline at end of file diff --git a/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.spec.ts b/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.spec.ts new file mode 100644 index 0000000000..7d5aaeeaa5 --- /dev/null +++ b/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { PacmanPopupComponent } from './pacman-popup.component'; + +describe('PacmanPopupComponent', () => { + let component: PacmanPopupComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ PacmanPopupComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(PacmanPopupComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.ts b/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.ts new file mode 100644 index 0000000000..d3e473740e --- /dev/null +++ b/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.ts @@ -0,0 +1,315 @@ +import { Component, OnInit, ViewChild, ElementRef, Renderer2, HostListener, OnDestroy } from '@angular/core'; + +export enum KEY_CODE { + RIGHT_ARROW = 39, + LEFT_ARROW = 37, + DOWN_ARROW = 40, + UP_ARROW = 38 +} + +class Ghost { + className: string; + startIndex: number; + speed: number; + currentIndex: number; + previousIndex: number; + isScared: boolean; + timerId: number; + + constructor(className, startIndex, speed) { + this.className = className; + this.startIndex = startIndex; + this.speed = speed; + this.currentIndex = startIndex; + this.previousIndex = startIndex; + this.isScared = false + this.timerId = NaN + } +} + +@Component({ + selector: 'ansyn-pacman-popup', + templateUrl: './pacman-popup.component.html', + styleUrls: ['./pacman-popup.component.less'] +}) +export class PacmanPopupComponent implements OnInit, OnDestroy { + + title = 'angular-pacman'; + width: number = 28; + scoreValue = 0; + + // layout + // legend + // 0 - pac dot + // 1 wall + // 2 - ghost lair + // 3 - power pellet + // 4 - empty + layout = [ + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1, + 1,0,1,1,1,1,0,1,1,1,1,1,0,1,1,0,1,1,1,1,1,0,1,1,1,1,0,1, + 1,3,1,1,1,1,0,1,1,1,1,1,0,1,1,0,1,1,1,1,1,0,1,1,1,1,3,1, + 1,0,1,1,1,1,0,1,1,1,1,1,0,1,1,0,1,1,1,1,1,0,1,1,1,1,0,1, + 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, + 1,0,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,0,1, + 1,0,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,0,1, + 1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1, + 1,1,1,1,1,1,0,1,1,1,1,1,0,1,1,0,1,1,1,1,1,0,1,1,1,1,1,1, + 1,1,1,1,1,1,0,1,1,4,4,4,4,4,4,4,4,4,4,1,1,0,1,1,1,1,1,1, + 1,1,1,1,1,1,0,1,1,4,1,1,1,2,2,1,1,1,4,1,1,0,1,1,1,1,1,1, + 1,1,1,1,1,1,0,1,1,4,1,2,2,2,2,2,2,1,4,1,1,0,1,1,1,1,1,1, + 4,4,4,4,4,4,0,0,0,4,1,2,2,2,2,2,2,1,4,0,0,0,4,4,4,4,4,4, + 1,1,1,1,1,1,0,1,1,4,1,2,2,2,2,2,2,1,4,1,1,0,1,1,1,1,1,1, + 1,1,1,1,1,1,0,1,1,4,1,1,1,1,1,1,1,1,4,1,1,0,1,1,1,1,1,1, + 1,1,1,1,1,1,0,1,1,4,1,1,1,1,1,1,1,1,4,1,1,0,1,1,1,1,1,1, + 1,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,1, + 1,0,1,1,1,1,0,1,1,1,1,1,0,1,1,0,1,1,1,1,1,0,1,1,1,1,0,1, + 1,0,1,1,1,1,0,1,1,1,1,1,0,1,1,0,1,1,1,1,1,0,1,1,1,1,0,1, + 1,3,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,3,1, + 1,1,1,0,1,1,0,1,1,0,1,1,1,1,1,1,1,1,0,1,1,0,1,1,0,1,1,1, + 1,1,1,0,1,1,0,1,1,0,1,1,1,1,1,1,1,1,0,1,1,0,1,1,0,1,1,1, + 1,0,0,0,0,0,0,1,1,0,0,0,0,1,1,0,0,0,0,1,1,0,0,0,0,0,0,1, + 1,0,1,1,1,1,1,1,1,1,1,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,0,1, + 1,0,1,1,1,1,1,1,1,1,1,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,0,1, + 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 + ] + + squares = []; + pacmanCurrentIndex = 490; + // define all the 4 ghosts + ghosts = [ + new Ghost('Elor', 348, 300), + new Ghost('Pini', 376, 400), + new Ghost('Aviv', 351, 320), + new Ghost('Rom', 379, 500) + ] + + @ViewChild('grid') grid: ElementRef; + @ViewChild('score') score: ElementRef; + @ViewChild('result') result: ElementRef; + + /** + * Actively listen to the keyup event in order to move the pacman + */ + @HostListener('document:keyup', ['$event']) + KeyUpEvent(event: KeyboardEvent) { + this.renderer.removeClass(this.squares[this.pacmanCurrentIndex], 'pac-man'); + if (event.keyCode === KEY_CODE.RIGHT_ARROW) { + if( + this.pacmanCurrentIndex - this.width >= 0 && + !this.squares[this.pacmanCurrentIndex + 1].classList.contains('wall') && + !this.squares[this.pacmanCurrentIndex + 1].classList.contains('ghost-lair') + ) + this.pacmanCurrentIndex += 1 + if ( this.squares[this.pacmanCurrentIndex +1] === this.squares[392]) { + this.pacmanCurrentIndex = 364 + } + } + + if (event.keyCode === KEY_CODE.LEFT_ARROW) { + if( + this.pacmanCurrentIndex % this.width !== 0 && + !this.squares[this.pacmanCurrentIndex - 1].classList.contains('wall') && + !this.squares[this.pacmanCurrentIndex - 1].classList.contains('ghost-lair') + ) + this.pacmanCurrentIndex -= 1 + if ( this.squares[this.pacmanCurrentIndex -1] === this.squares[363]){ + this.pacmanCurrentIndex = 391 + } + } + + if (event.keyCode === KEY_CODE.DOWN_ARROW) { + if ( + this.pacmanCurrentIndex + this.width < this.width * this.width && + !this.squares[this.pacmanCurrentIndex + this.width].classList.contains('wall') && + !this.squares[this.pacmanCurrentIndex + this.width].classList.contains('ghost-lair') + ) + this.pacmanCurrentIndex += this.width + } + + if (event.keyCode === KEY_CODE.UP_ARROW) { + if( + this.pacmanCurrentIndex - this.width >= 0 && + !this.squares[this.pacmanCurrentIndex - this.width].classList.contains('wall') && + !this.squares[this.pacmanCurrentIndex - this.width].classList.contains('ghost-lair') + ) + this.pacmanCurrentIndex -= this.width + } + this.renderer.addClass(this.squares[this.pacmanCurrentIndex], 'pac-man'); + this.pacDotEaten(); + this.powerPelletEaten(); + this.checkForGameOver(this.squares, this.pacmanCurrentIndex); + this.checkforWin(); + } + + constructor(private renderer: Renderer2, private elem: ElementRef){ + + } + + + /** + * Generate the 28x28 grid board + * Colour all the element with the array define on the layout + */ + createBoard(){ + for (let i = 0; i < this.layout.length; i++){ + const square = this.renderer.createElement('div'); + this.renderer.appendChild(this.grid.nativeElement, square); + this.squares.push(square) + + if(this.layout[i] === 0){ + this.renderer.addClass(this.squares[i], 'pac-dot'); + } else if (this.layout[i] === 1){ + this.renderer.addClass(this.squares[i], 'wall'); + } else if (this.layout[i] === 2) { + this.renderer.addClass(this.squares[i], 'ghost-lair'); + } else if (this.layout[i] === 3){ + this.renderer.addClass(this.squares[i], 'power-pellet'); + } + } + } + + ngOnInit(): void { + + } + + ngOnDestroy(): void { + } + + // init all the ghosts from the array + // randonmy set interval to move the ghost around. + initGhosts(){ + this.ghosts.forEach(ghost =>{ + this.squares[ghost.currentIndex].classList.add('ghost'); + this.squares[ghost.currentIndex].classList.add(ghost.className); + this.moveGhost(ghost); + }); + + } + + /** + * Randomly move the ghost + * Check whether those ghost are afraid of the pacman + * Anti collision + * @param ghost + */ + moveGhost(ghost) { + // please implement this. + var widthX = this.width; + var squaresY = this.squares; + var scoreValX = this.scoreValue; + var pacmanCurrentIndexX = this.pacmanCurrentIndex; + var checkForGameOverX = this.checkForGameOver; + ghost.timerId = setInterval(function() { + const directions = [-1 , +1, +widthX, -widthX]; + let direction = directions[Math.floor(Math.random() * directions.length)]; + if (!squaresY[ghost.currentIndex + direction].classList.contains('ghost') && + !squaresY[ghost.currentIndex + direction].classList.contains('wall') + ) { + squaresY[ghost.currentIndex].classList.remove(ghost.className); + squaresY[ghost.currentIndex].classList.remove('ghost', 'scared-ghost'); + ghost.currentIndex += direction + ghost.previousIndex = ghost.currentIndex; + squaresY[ghost.currentIndex].classList.add(ghost.className, 'ghost'); + }else { + direction = directions[Math.floor(Math.random() * directions.length)]; + } + if (ghost.isScared) { + squaresY[ghost.currentIndex].classList.add('scared-ghost') + } + + if(ghost.isScared && squaresY[ghost.currentIndex].classList.contains('pac-man')) { + squaresY[ghost.currentIndex].classList.remove(ghost.className, 'ghost', 'scared-ghost') + ghost.currentIndex = ghost.startIndex + scoreValX +=100 + squaresY[ghost.currentIndex].classList.add(ghost.className, 'ghost') + } + checkForGameOverX(squaresY, pacmanCurrentIndexX); + }, ghost.speed); + } + + /** + * Check whether the game is over. if the pacman touches the ghost when it is not isScared + * then end the game by removing the keyUp event from the window/document. + */ + checkForGameOver(squaresX, pacmanCurrentIndexX) { + if (squaresX[pacmanCurrentIndexX].classList.contains('ghost') && + !squaresX[pacmanCurrentIndexX].classList.contains('scared-ghost') + ) { + this.ghosts.forEach(ghost=> clearInterval(ghost.timerId)) + this.KeyUpEvent = function() : void {}; + this.result.nativeElement.innerHTML = "Game Over!"; + } + + } + + + /** + * Check whether has pacman consume all the pellet from the grid + * if yes then display the winning message + */ + checkforWin() { + if(this.scoreValue === 274) { + this.ghosts.forEach(ghost => clearInterval(ghost.timerId)) + this.KeyUpEvent = function() : void {}; + this.result.nativeElement.innerHTML = "You have Won!"; + } + } + + /** + * Initialize the board by generating 28x28 grid + * Render the initial start position of the pacman + * Also render the all the ghosts within the array list + */ + ngAfterViewInit() { + // create the pac man board + this.createBoard(); + this.renderer.addClass(this.squares[this.pacmanCurrentIndex], 'pac-man'); + this.initGhosts(); + } + + /** + * What happens when pacman is busy eating the small pellet + * Increment the score + * Remove the small pellet from the grid once is consume by pacman + */ + pacDotEaten() { + if( this.squares[this.pacmanCurrentIndex].classList.contains('pac-dot')) { + this.scoreValue++ + this.score.nativeElement.innerHTML = this.scoreValue; + this.squares[this.pacmanCurrentIndex].classList.remove('pac-dot'); + } + } + + /** + * Once pacman consume the power pellet it gain super power + * All the ghost will be afraid of em. + * By right the ghost should run away from pacman as much as possible + * Set an timeout for the ghost to turn back to hunting mode rather than + * scare of pacman. + */ + powerPelletEaten() { + if( this.squares[this.pacmanCurrentIndex].classList.contains('power-pellet')) { + this.scoreValue+=10 + this.score.nativeElement.innerHTML = this.scoreValue; + this.ghosts.forEach(ghost => { + ghost.isScared = true; + console.log("turn to scared of pacman"); + // turn the ghost colour to aquamarine. + this.squares[ghost.currentIndex].classList.add(ghost.className, 'ghost', 'scared-ghost'); + }); + setTimeout(()=>{ + this.ghosts.forEach(ghost => { + ghost.isScared = false + this.squares[ghost.currentIndex].classList.remove(ghost.className, 'ghost', 'scared-ghost') + ghost.currentIndex = ghost.startIndex + this.squares[ghost.currentIndex].classList.add(ghost.className, 'ghost') + }) + }, 10000) + this.squares[this.pacmanCurrentIndex].classList.remove('power-pellet'); + } + } +} + diff --git a/src/app/@ansyn/ansyn/modules/overlays/components/overlay-navigation-bar/overlay-navigation-bar.component.ts b/src/app/@ansyn/ansyn/modules/overlays/components/overlay-navigation-bar/overlay-navigation-bar.component.ts index 31ae1e9241..058a15731e 100644 --- a/src/app/@ansyn/ansyn/modules/overlays/components/overlay-navigation-bar/overlay-navigation-bar.component.ts +++ b/src/app/@ansyn/ansyn/modules/overlays/components/overlay-navigation-bar/overlay-navigation-bar.component.ts @@ -12,6 +12,7 @@ import { selectDropsAscending, selectFilteredOveralys } from '../../reducers/ove import { combineLatest } from 'rxjs'; import { IOverlay, IOverlayDrop } from '../../models/overlay.model'; import { TranslateService } from '@ngx-translate/core'; +import { KeysListenerService } from "../../../core/services/keys-listener.service"; @Component({ selector: 'ansyn-overlay-navigation-bar', @@ -27,6 +28,47 @@ export class OverlayNavigationBarComponent implements OnInit, OnDestroy { isLastOverlay: boolean; overlaysLength: number; + @AutoSubscription + onKeyDown$ = () => this.keyListenerService.keydown.pipe( + tap($event => { + if (this.keyListenerService.keyWasUsed($event, 'ArrowRight', 39)) { + this.goNextActive = true; + } else if (this.keyWasUsed($event, 'ArrowLeft', 37)) { + this.goPrevActive = true; + } + + if (this.keyListenerService.keysWereUsed($event, this._overlayHackKeys)) { + this.store.dispatch(new EnableCopyOriginalOverlayDataAction(true)); + } + }) + ) + + @AutoSubscription + onKeyUp$ = () => this.keyListenerService.keyup.pipe( + tap($event => { + if (this.keyListenerService.isElementNotValid($event)) { + return; + } + + if (this.keyListenerService.keyWasUsed($event, 'ArrowRight', 39)) { + this.clickGoAdjacent(true); + this.goNextActive = false; + } else if (this.keyListenerService.keyWasUsed($event, 'ArrowLeft', 37)) { + this.clickGoAdjacent(false); + this.goPrevActive = false; + } + + if (this.keysWereUsed($event, this._overlayHackKeys)) { + this.store.dispatch(new EnableCopyOriginalOverlayDataAction(false)); + } + + if (this.keysWereUsed($event, this._toggleDirectionKeys)) { + const direction = this.translateService.instant('direction'); + this.translateService.set('direction', direction === 'rtl' ? 'ltr' : 'rtl', 'default'); + } + }) + ); + @AutoSubscription hasOverlayDisplay$ = this.store.select(selectOverlayOfActiveMap).pipe( tap(overlay => this.hasOverlayDisplay = Boolean(overlay)) @@ -39,7 +81,7 @@ export class OverlayNavigationBarComponent implements OnInit, OnDestroy { this.store.select(selectFilteredOveralys) ]).pipe( filter(([activeMapOverlay, overlays, filtered]: [IOverlay, IOverlayDrop[], any[]]) => Boolean(activeMapOverlay) && Boolean(overlays.length)), - tap(([activeMapOverlay, overlays, filtered]: [IOverlay, IOverlayDrop[], IOverlay[]]) => { + tap(([activeMapOverlay, overlays, filtered]: [IOverlay, IOverlayDrop[], IOverlay[]]) => { this.overlaysLength = filtered.length; this.isFirstOverlay = activeMapOverlay.id === overlays[0].id; this.isLastOverlay = activeMapOverlay.id === overlays[overlays.length - 1].id; @@ -52,13 +94,14 @@ export class OverlayNavigationBarComponent implements OnInit, OnDestroy { constructor( protected store: Store, + public keyListenerService: KeysListenerService, @Inject(StatusBarConfig) public statusBarConfig: IStatusBarConfig, protected translateService: TranslateService ) { } isElementNotValid($event: KeyboardEvent) { - const { activeElement } = ($event.currentTarget).document; + const {activeElement} = ($event.currentTarget).document; return this.isElementInput(activeElement) || this.isTimePicker(activeElement); } @@ -67,50 +110,46 @@ export class OverlayNavigationBarComponent implements OnInit, OnDestroy { } isTimePicker(activeElement) { - const { className } = activeElement; + const {className} = activeElement; return className.includes('owl') || className.includes('title'); } - @HostListener('window:keyup', ['$event']) - onkeyup($event: KeyboardEvent) { - if (this.isElementNotValid($event)) { - return; - } - - if (this.keyWasUsed($event, 'ArrowRight', 39)) { - this.clickGoAdjacent(true); - this.goNextActive = false; - } else if (this.keyWasUsed($event, 'ArrowLeft', 37)) { - this.clickGoAdjacent(false); - this.goPrevActive = false; - } - - if (this.keysWereUsed($event, this._overlayHackKeys)) { - this.store.dispatch(new EnableCopyOriginalOverlayDataAction(false)); - } - - if (this.keysWereUsed($event, this._toggleDirectionKeys)) { - const direction = this.translateService.instant('direction'); - this.translateService.set('direction', direction === 'rtl' ? 'ltr' : 'rtl', 'default'); - } - } - - @HostListener('window:keydown', ['$event']) - onkeydown($event: KeyboardEvent) { - if (this.isElementNotValid($event)) { - return; - } - - if (this.keyWasUsed($event, 'ArrowRight', 39)) { - this.goNextActive = true; - } else if (this.keyWasUsed($event, 'ArrowLeft', 37)) { - this.goPrevActive = true; - } - - if (this.keysWereUsed($event, this._overlayHackKeys)) { - this.store.dispatch(new EnableCopyOriginalOverlayDataAction(true)); - } - } + // @HostListener('window:keyup', ['$event']) + // onkeyup($event: KeyboardEvent) { + // if (this.keyWasUsed($event, 'ArrowRight', 39)) { + // this.clickGoAdjacent(true); + // this.goNextActive = false; + // } else if (this.keyWasUsed($event, 'ArrowLeft', 37)) { + // this.clickGoAdjacent(false); + // this.goPrevActive = false; + // } + // + // if (this.keysWereUsed($event, this._overlayHackKeys)) { + // this.store.dispatch(new EnableCopyOriginalOverlayDataAction(false)); + // } + // + // if (this.keysWereUsed($event, this._toggleDirectionKeys)) { + // const direction = this.translateService.instant('direction'); + // this.translateService.set('direction', direction === 'rtl' ? 'ltr' : 'rtl', 'default'); + // } + // } + // + // @HostListener('window:keydown', ['$event']) + // onkeydown($event: KeyboardEvent) { + // if (this.isElementNotValid($event)) { + // return; + // } + // + // if (this.keyWasUsed($event, 'ArrowRight', 39)) { + // this.goNextActive = true; + // } else if (this.keyWasUsed($event, 'ArrowLeft', 37)) { + // this.goPrevActive = true; + // } + // + // if (this.keysWereUsed($event, this._overlayHackKeys)) { + // this.store.dispatch(new EnableCopyOriginalOverlayDataAction(true)); + // } + // } @HostListener('window:keypress', ['$event']) onkeypress($event: KeyboardEvent) { @@ -133,7 +172,7 @@ export class OverlayNavigationBarComponent implements OnInit, OnDestroy { } clickGoAdjacent(isNext): void { - this.store.dispatch(new GoAdjacentOverlay({ isNext })); + this.store.dispatch(new GoAdjacentOverlay({isNext})); } clickScannedArea(): void { diff --git a/src/app/@ansyn/ansyn/modules/status-bar/components/tools/tools.module.ts b/src/app/@ansyn/ansyn/modules/status-bar/components/tools/tools.module.ts index 7e43ee89d9..1af11b5f71 100644 --- a/src/app/@ansyn/ansyn/modules/status-bar/components/tools/tools.module.ts +++ b/src/app/@ansyn/ansyn/modules/status-bar/components/tools/tools.module.ts @@ -16,6 +16,7 @@ import { MatButtonModule } from '@angular/material/button'; import { MatFormFieldModule } from '@angular/material/form-field'; import { MatSelectModule } from '@angular/material/select'; import { CoreModule } from '../../../core/core.module'; +import { PacmanPopupComponent } from '../../../easter-eggs/pacman-popup/pacman-popup.component'; // @dynamic @NgModule({ @@ -39,7 +40,7 @@ import { CoreModule } from '../../../core/core.module'; MatSelectModule ], providers: [ProjectionConverterService], - declarations: [ToolsComponent, AnnotationsControlComponent, MeasureControlComponent, ExportMapsPopupComponent], + declarations: [ToolsComponent, AnnotationsControlComponent, MeasureControlComponent, ExportMapsPopupComponent, PacmanPopupComponent], entryComponents: [ToolsComponent, MeasureControlComponent, ExportMapsPopupComponent], exports: [ToolsComponent, MatDialogModule] }) diff --git a/src/app/@ansyn/ansyn/modules/status-bar/components/tools/tools/tools.component.ts b/src/app/@ansyn/ansyn/modules/status-bar/components/tools/tools/tools.component.ts index 3087590436..1186de8ba8 100644 --- a/src/app/@ansyn/ansyn/modules/status-bar/components/tools/tools/tools.component.ts +++ b/src/app/@ansyn/ansyn/modules/status-bar/components/tools/tools/tools.component.ts @@ -1,4 +1,4 @@ -import { Component, OnDestroy, OnInit } from '@angular/core'; +import { Component, OnDestroy, OnInit, HostListener } from '@angular/core'; import { ClearActiveInteractionsAction, SetSubMenu, @@ -17,6 +17,8 @@ import { SubMenuEnum, toolsFlags } from '../models/tools.model'; import { selectActiveAnnotationLayer } from '../../../../menu-items/layers-manager/reducers/layers.reducer'; import { ComponentVisibilityService } from '../../../../../app-providers/component-visibility.service'; import { ComponentVisibilityItems } from '../../../../../app-providers/component-mode'; +import { PacmanPopupComponent } from '../../../../easter-eggs/pacman-popup/pacman-popup.component'; +import { KeysListenerService } from "../../../../core/services/keys-listener.service"; @Component({ selector: 'ansyn-tools', @@ -44,6 +46,15 @@ export class ToolsComponent implements OnInit, OnDestroy { tap((flags: Map) => this.flags = flags) ); + @AutoSubscription + onKeyUp$ = () => this.keyListenerService.keyup.pipe( + tap($event => { + if (this.keyListenerService.keysWereUsed($event, this._pacmanKeys)) { + this.togglePacmanDialog(); + } + }) + ); + isActiveAnnotationLayer$ = this.store$.select(selectActiveAnnotationLayer).pipe( map(Boolean) ); @@ -75,9 +86,12 @@ export class ToolsComponent implements OnInit, OnDestroy { return this.flags?.get(toolsFlags.isMeasureToolActive); } + private _pacmanKeys = 'Ppפ'.split(''); + constructor( protected store$: Store, public dialog: MatDialog, + public keyListenerService: KeysListenerService, componentVisibilityService: ComponentVisibilityService ) { this.isExportShow = componentVisibilityService.get(ComponentVisibilityItems.EXPORT); @@ -98,15 +112,15 @@ export class ToolsComponent implements OnInit, OnDestroy { const value = this.onShadowMouse; if (value) { - this.store$.dispatch(new StopMouseShadow({ fromUser: true })); + this.store$.dispatch(new StopMouseShadow({fromUser: true})); } else { - this.store$.dispatch(new StartMouseShadow({ fromUser: true })); + this.store$.dispatch(new StartMouseShadow({fromUser: true})); } } toggleMeasureDistanceTool() { const value = !this.onMeasureTool; - this.store$.dispatch(new ClearActiveInteractionsAction({ skipClearFor: [UpdateMeasureDataOptionsAction] })); + this.store$.dispatch(new ClearActiveInteractionsAction({skipClearFor: [UpdateMeasureDataOptionsAction]})); this.store$.dispatch(new UpdateToolsFlags([{key: toolsFlags.isMeasureToolActive, value}])); } @@ -130,9 +144,18 @@ export class ToolsComponent implements OnInit, OnDestroy { toggleExportMapsDialog() { if (!this.isDialogShowing) { - const dialogRef = this.dialog.open(ExportMapsPopupComponent, { panelClass: 'custom-dialog' }); + const dialogRef = this.dialog.open(ExportMapsPopupComponent, {panelClass: 'custom-dialog'}); dialogRef.afterClosed().pipe(take(1), tap(() => this.isDialogShowing = false)).subscribe(); this.isDialogShowing = !this.isDialogShowing; } } + + togglePacmanDialog() { + if (!this.isDialogShowing) { + const dialogRef = this.dialog.open(PacmanPopupComponent, {panelClass: 'custom-dialog'}); + dialogRef.afterClosed().pipe(take(1), tap(() => this.isDialogShowing = false)).subscribe(); + this.isDialogShowing = !this.isDialogShowing; + } + } + } From 2468c4c6e69a703c90dad820d04964b2b0d04742 Mon Sep 17 00:00:00 2001 From: Danaorlov1005 Date: Mon, 5 Apr 2021 18:20:16 +0300 Subject: [PATCH 02/21] fixed some css and autosubscription --- .../@ansyn/ansyn/assets/important/Capture.JPG | Bin 40416 -> 0 bytes .../@ansyn/ansyn/assets/important/adani.jpg | Bin 0 -> 1101 bytes .../@ansyn/ansyn/assets/important/elor.JPG | Bin 8338 -> 8262 bytes .../@ansyn/ansyn/assets/important/tzahi.jpg | Bin 0 -> 1151 bytes .../ansyn/assets/important/yehonatan.jpg | Bin 0 -> 1165 bytes .../@ansyn/ansyn/assets/important/yuval.jpg | Bin 0 -> 1152 bytes .../pacman-popup/pacman-popup.component.less | 47 +- .../pacman-popup/pacman-popup.component.ts | 611 +++++++++--------- .../overlay-navigation-bar.component.ts | 92 +-- 9 files changed, 359 insertions(+), 391 deletions(-) delete mode 100644 src/app/@ansyn/ansyn/assets/important/Capture.JPG create mode 100644 src/app/@ansyn/ansyn/assets/important/adani.jpg create mode 100644 src/app/@ansyn/ansyn/assets/important/tzahi.jpg create mode 100644 src/app/@ansyn/ansyn/assets/important/yehonatan.jpg create mode 100644 src/app/@ansyn/ansyn/assets/important/yuval.jpg diff --git a/src/app/@ansyn/ansyn/assets/important/Capture.JPG b/src/app/@ansyn/ansyn/assets/important/Capture.JPG deleted file mode 100644 index 06f051750c20b4fd6a906c067e278656affc0867..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 40416 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 z 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 literal 0 HcmV?d00001 diff --git a/src/app/@ansyn/ansyn/assets/important/elor.JPG b/src/app/@ansyn/ansyn/assets/important/elor.JPG index a080df4ecab024897ee9291b695f3c66a55e76b8..7faade1593d9b799cae9f9ce6ec1f908b4c19d30 100644 GIT binary patch delta 554 zcmV+_0@eMJLB>F^oCppxF#rIPk^lk#0009sF|(=&EC?AeH99gf05UK#F*-0aIx;yR zF*Q0cH99gfv+oeh0SPcQIx;dYGchx>#1i2N0TZ*P9LfQI_;2jf{t4gk{{Z4f zt~CDuho52a@5HYO+1xe8onxduy`HoYOrqGn5k$jls!XAjvw3d71u6MO;XjLhAn-1i zs99+G=BuQC+v-vyPaTEJTlw1qZQRO3V0n+maC68!SJi(Ct-owP*wf)&rQ@3|55{^| zfg_4*i}?IcYK^DC3qurwcT2oIymvxikWUee-ANpg!qQ0_Am+qEs>CYMovor*vi`r% zb)o8EaWrFwcxh9=cWqbW{VV9tn&a`M!$BI!b8# z%NuQ6o=yNC&oo!FDs81kCVPhV)6{(fmK+&lK2c8m6CP zZ56#)y!JMR_3f<{5kQUzp4t{jquPqdNC2~BqP|x$lm5`78|nW51s?teG5VEhTU|dU sejw?Zd^2Ba(X?vIYpBm}7DwHU8)}U8I0LEXiYTw3a+UW!Zd;%K*$>JQga7~l delta 631 zcmV--0*L*_K$1bQoCpp$G5`RQk^lk#0009xGP9}(EC?AgIXW~r05UK#F*-0aIx;yR zF*Q0eIXW~rv+oeh0SPiWIy5*gI5IG^#1i2N0T#2S9LfQI=6~RvpYT=PAK<6#h4F(_ zp8gfqweK0rccTdiTs+W20FjOW0gQ2N13P|pBMJj?w;mMuBjb+%=>8_w{Ac5D5O||n zmF*zb;=R>mxVXBD=9q}l7(`QWJ3O$6rFbKg>Ru=R0D><3CHMjV00iQ__<^f`!e`=t z6lwZpma%ewpKe=QD|Kn%6R?If4YeV89gE1!He?m(JcHopkGvjLd^@OoGrH9N6#cc% zfb#fyXU+R83oNg2%w*fTDKjqI5g6Q6K`r_IB3#qPk zT2h5*!cVUS zFwJXoDKd=6Vwq5!Wchg{l1&xmU$dv|rK$eiJ`TO{U&Fm73w;MkzB&^|65cggVTKnW zRpyL^2`pd@xZ|&(T{6T{z2_Mx*G{K_ES@~ilM_zYcD$ACe>Z=;>3kpm00mWt$A7a% zp{Q$rKMnND%@*TK{?4CF{?TtL?HxRsV~`ln?wwhN+~f{79OQmI_-FQt@kfL8tyjYO zJUUz#wdm-bO=_?5MDh%t6;u<0_d)C^qOUKf7b=l!ME?LIY*gh*LR8(HmbO0V z{hfR*t$0J=_K#z0uj-caEM{wyX?rECa?K+q85y>&bN7Pe^MxLiQAK>Ed|hv8FM00I Rw55W>s6}!umro>r|Jh)yFsA?j diff --git a/src/app/@ansyn/ansyn/assets/important/tzahi.jpg b/src/app/@ansyn/ansyn/assets/important/tzahi.jpg new file mode 100644 index 0000000000000000000000000000000000000000..9ecfc54855ddd7f4714039284f18d6ae25c02ff6 GIT binary patch literal 1151 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 literal 0 HcmV?d00001 diff --git a/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.less b/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.less index d70e18433f..5e677eaabf 100644 --- a/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.less +++ b/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.less @@ -30,30 +30,43 @@ box-sizing: border-box; } -.Elor { - background: url('../../../assets/important/elor.JPG'); - box-sizing: border-box; - background-color: darkred; +.ghost { + box-sizing: border-box; + background-color: darkred; + border-radius: 0px !important; + border: none !important; } -.Pini { - background: url('../../../assets/important/aviv.JPG'); - box-sizing: border-box; - background-color: purple; +@length: 2; +@random: `Math.ceil(Math.random() * (@{length}))`; + +@blinkyImages: 'yehonatan.jpg', 'tzahi.jpg'; +@randomBlinkyimage: extract(@blinkyImages,@random); + +.blinky { + background: url('../../../assets/important/@{randomBlinkyimage}'); } -.Aviv { - background: url('../../../assets/important/rom.JPG'); - box-sizing: border-box; - background-color: cyan; +@pinkyImages: 'aviv.jpg', 'pini.jpg'; +@randomPinkyimage: extract(@pinkyImages,@random); + +.pinky { + background: url('../../../assets/important/@{randomPinkyimage}'); } -.Rom { - background: url('../../../assets/important/pini.JPG'); - box-sizing: border-box; - background-color: orange; +@inkyImages: 'elor.jpg', 'yuval.jpg'; +@randominkyimage: extract(@inkyImages,@random); + +.inky { + background: url('../../../assets/important/@{randominkyimage}'); } +@clydeImages: 'adani.jpg', 'rom.jpg'; +@randomClydeimage: extract(@clydeImages,@random); + +.clyde { + background: url('../../../assets/important/@{randomClydeimage}'); +} .pac-man { background-color: yellow; @@ -62,4 +75,4 @@ .scared-ghost { background: url('../../../assets/important/dana.JPG'); -} \ No newline at end of file +} diff --git a/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.ts b/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.ts index d3e473740e..6e8b38f469 100644 --- a/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.ts +++ b/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.ts @@ -1,315 +1,328 @@ import { Component, OnInit, ViewChild, ElementRef, Renderer2, HostListener, OnDestroy } from '@angular/core'; +import { KeysListenerService } from "../../core/services/keys-listener.service"; +import { AutoSubscription, AutoSubscriptions } from "auto-subscriptions"; +import { filter, tap } from "rxjs/operators"; export enum KEY_CODE { - RIGHT_ARROW = 39, - LEFT_ARROW = 37, - DOWN_ARROW = 40, - UP_ARROW = 38 + RIGHT_ARROW = 39, + LEFT_ARROW = 37, + DOWN_ARROW = 40, + UP_ARROW = 38 } class Ghost { - className: string; - startIndex: number; - speed: number; - currentIndex: number; - previousIndex: number; - isScared: boolean; - timerId: number; - - constructor(className, startIndex, speed) { - this.className = className; - this.startIndex = startIndex; - this.speed = speed; - this.currentIndex = startIndex; - this.previousIndex = startIndex; - this.isScared = false - this.timerId = NaN - } + className: string; + startIndex: number; + speed: number; + currentIndex: number; + previousIndex: number; + isScared: boolean; + timerId: number; + + constructor(className, startIndex, speed) { + this.className = className; + this.startIndex = startIndex; + this.speed = speed; + this.currentIndex = startIndex; + this.previousIndex = startIndex; + this.isScared = false + this.timerId = NaN + } } @Component({ - selector: 'ansyn-pacman-popup', - templateUrl: './pacman-popup.component.html', - styleUrls: ['./pacman-popup.component.less'] + selector: 'ansyn-pacman-popup', + templateUrl: './pacman-popup.component.html', + styleUrls: ['./pacman-popup.component.less'] }) +@AutoSubscriptions() export class PacmanPopupComponent implements OnInit, OnDestroy { - title = 'angular-pacman'; - width: number = 28; - scoreValue = 0; - - // layout - // legend - // 0 - pac dot - // 1 wall - // 2 - ghost lair - // 3 - power pellet - // 4 - empty - layout = [ - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1, - 1,0,1,1,1,1,0,1,1,1,1,1,0,1,1,0,1,1,1,1,1,0,1,1,1,1,0,1, - 1,3,1,1,1,1,0,1,1,1,1,1,0,1,1,0,1,1,1,1,1,0,1,1,1,1,3,1, - 1,0,1,1,1,1,0,1,1,1,1,1,0,1,1,0,1,1,1,1,1,0,1,1,1,1,0,1, - 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, - 1,0,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,0,1, - 1,0,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,0,1, - 1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1, - 1,1,1,1,1,1,0,1,1,1,1,1,0,1,1,0,1,1,1,1,1,0,1,1,1,1,1,1, - 1,1,1,1,1,1,0,1,1,4,4,4,4,4,4,4,4,4,4,1,1,0,1,1,1,1,1,1, - 1,1,1,1,1,1,0,1,1,4,1,1,1,2,2,1,1,1,4,1,1,0,1,1,1,1,1,1, - 1,1,1,1,1,1,0,1,1,4,1,2,2,2,2,2,2,1,4,1,1,0,1,1,1,1,1,1, - 4,4,4,4,4,4,0,0,0,4,1,2,2,2,2,2,2,1,4,0,0,0,4,4,4,4,4,4, - 1,1,1,1,1,1,0,1,1,4,1,2,2,2,2,2,2,1,4,1,1,0,1,1,1,1,1,1, - 1,1,1,1,1,1,0,1,1,4,1,1,1,1,1,1,1,1,4,1,1,0,1,1,1,1,1,1, - 1,1,1,1,1,1,0,1,1,4,1,1,1,1,1,1,1,1,4,1,1,0,1,1,1,1,1,1, - 1,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,1, - 1,0,1,1,1,1,0,1,1,1,1,1,0,1,1,0,1,1,1,1,1,0,1,1,1,1,0,1, - 1,0,1,1,1,1,0,1,1,1,1,1,0,1,1,0,1,1,1,1,1,0,1,1,1,1,0,1, - 1,3,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,3,1, - 1,1,1,0,1,1,0,1,1,0,1,1,1,1,1,1,1,1,0,1,1,0,1,1,0,1,1,1, - 1,1,1,0,1,1,0,1,1,0,1,1,1,1,1,1,1,1,0,1,1,0,1,1,0,1,1,1, - 1,0,0,0,0,0,0,1,1,0,0,0,0,1,1,0,0,0,0,1,1,0,0,0,0,0,0,1, - 1,0,1,1,1,1,1,1,1,1,1,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,0,1, - 1,0,1,1,1,1,1,1,1,1,1,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,0,1, - 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 - ] - - squares = []; - pacmanCurrentIndex = 490; - // define all the 4 ghosts - ghosts = [ - new Ghost('Elor', 348, 300), - new Ghost('Pini', 376, 400), - new Ghost('Aviv', 351, 320), - new Ghost('Rom', 379, 500) - ] - - @ViewChild('grid') grid: ElementRef; - @ViewChild('score') score: ElementRef; - @ViewChild('result') result: ElementRef; - - /** - * Actively listen to the keyup event in order to move the pacman - */ - @HostListener('document:keyup', ['$event']) - KeyUpEvent(event: KeyboardEvent) { - this.renderer.removeClass(this.squares[this.pacmanCurrentIndex], 'pac-man'); - if (event.keyCode === KEY_CODE.RIGHT_ARROW) { - if( - this.pacmanCurrentIndex - this.width >= 0 && - !this.squares[this.pacmanCurrentIndex + 1].classList.contains('wall') && - !this.squares[this.pacmanCurrentIndex + 1].classList.contains('ghost-lair') - ) - this.pacmanCurrentIndex += 1 - if ( this.squares[this.pacmanCurrentIndex +1] === this.squares[392]) { - this.pacmanCurrentIndex = 364 - } - } - - if (event.keyCode === KEY_CODE.LEFT_ARROW) { - if( - this.pacmanCurrentIndex % this.width !== 0 && - !this.squares[this.pacmanCurrentIndex - 1].classList.contains('wall') && - !this.squares[this.pacmanCurrentIndex - 1].classList.contains('ghost-lair') - ) - this.pacmanCurrentIndex -= 1 - if ( this.squares[this.pacmanCurrentIndex -1] === this.squares[363]){ - this.pacmanCurrentIndex = 391 - } - } - - if (event.keyCode === KEY_CODE.DOWN_ARROW) { - if ( - this.pacmanCurrentIndex + this.width < this.width * this.width && - !this.squares[this.pacmanCurrentIndex + this.width].classList.contains('wall') && - !this.squares[this.pacmanCurrentIndex + this.width].classList.contains('ghost-lair') - ) - this.pacmanCurrentIndex += this.width - } - - if (event.keyCode === KEY_CODE.UP_ARROW) { - if( - this.pacmanCurrentIndex - this.width >= 0 && - !this.squares[this.pacmanCurrentIndex - this.width].classList.contains('wall') && - !this.squares[this.pacmanCurrentIndex - this.width].classList.contains('ghost-lair') - ) - this.pacmanCurrentIndex -= this.width - } - this.renderer.addClass(this.squares[this.pacmanCurrentIndex], 'pac-man'); - this.pacDotEaten(); - this.powerPelletEaten(); - this.checkForGameOver(this.squares, this.pacmanCurrentIndex); - this.checkforWin(); - } - - constructor(private renderer: Renderer2, private elem: ElementRef){ - - } - - - /** - * Generate the 28x28 grid board - * Colour all the element with the array define on the layout - */ - createBoard(){ - for (let i = 0; i < this.layout.length; i++){ - const square = this.renderer.createElement('div'); - this.renderer.appendChild(this.grid.nativeElement, square); - this.squares.push(square) - - if(this.layout[i] === 0){ - this.renderer.addClass(this.squares[i], 'pac-dot'); - } else if (this.layout[i] === 1){ - this.renderer.addClass(this.squares[i], 'wall'); - } else if (this.layout[i] === 2) { - this.renderer.addClass(this.squares[i], 'ghost-lair'); - } else if (this.layout[i] === 3){ - this.renderer.addClass(this.squares[i], 'power-pellet'); - } - } - } - - ngOnInit(): void { - - } + title = 'angular-pacman'; + width = 28; + scoreValue = 0; + + // layout + // legend + // 0 - pac dot + // 1 wall + // 2 - ghost lair + // 3 - power pellet + // 4 - empty + layout = [ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, + 1, 3, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 3, 1, + 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, + 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 0, 1, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1, 0, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 0, 1, 1, 4, 1, 1, 1, 2, 2, 1, 1, 1, 4, 1, 1, 0, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 0, 1, 1, 4, 1, 2, 2, 2, 2, 2, 2, 1, 4, 1, 1, 0, 1, 1, 1, 1, 1, 1, + 4, 4, 4, 4, 4, 4, 0, 0, 0, 4, 1, 2, 2, 2, 2, 2, 2, 1, 4, 0, 0, 0, 4, 4, 4, 4, 4, 4, + 1, 1, 1, 1, 1, 1, 0, 1, 1, 4, 1, 2, 2, 2, 2, 2, 2, 1, 4, 1, 1, 0, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 0, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, 1, 0, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 0, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, 1, 0, 1, 1, 1, 1, 1, 1, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, + 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, + 1, 3, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 3, 1, + 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, + 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, + 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 + ] + + squares = []; + pacmanCurrentIndex = 490; + // define all the 4 ghosts + ghosts = [ + new Ghost('blinky', 348, 150), + new Ghost('pinky', 376, 200), + new Ghost('inky', 351, 120), + new Ghost('clyde', 379, 300) + ] + + @ViewChild('grid') grid: ElementRef; + @ViewChild('score') score: ElementRef; + @ViewChild('result') result: ElementRef; + isPacmanAlive = true; + + constructor(private renderer: Renderer2, + public keyListenerService: KeysListenerService, + private elem: ElementRef) { + + } + + /** + * Actively listen to the keyup event in order to move the pacman + */ + @AutoSubscription + KeyUpEvent$ = () => this.keyListenerService.keyup.pipe( + filter(() => this.isPacmanAlive), + tap($event => { + this.renderer.removeClass(this.squares[this.pacmanCurrentIndex], 'pac-man'); + if ($event.keyCode === KEY_CODE.RIGHT_ARROW) { + if ( + this.pacmanCurrentIndex - this.width >= 0 && + !this.squares[this.pacmanCurrentIndex + 1].classList.contains('wall') && + !this.squares[this.pacmanCurrentIndex + 1].classList.contains('ghost-lair') + ) { + this.pacmanCurrentIndex += 1 + } + if (this.squares[this.pacmanCurrentIndex + 1] === this.squares[392]) { + this.pacmanCurrentIndex = 364 + } + } + + if ($event.keyCode === KEY_CODE.LEFT_ARROW) { + if ( + this.pacmanCurrentIndex % this.width !== 0 && + !this.squares[this.pacmanCurrentIndex - 1].classList.contains('wall') && + !this.squares[this.pacmanCurrentIndex - 1].classList.contains('ghost-lair') + ) { + this.pacmanCurrentIndex -= 1 + } + if (this.squares[this.pacmanCurrentIndex - 1] === this.squares[363]) { + this.pacmanCurrentIndex = 391 + } + } + + if ($event.keyCode === KEY_CODE.DOWN_ARROW) { + if ( + this.pacmanCurrentIndex + this.width < this.width * this.width && + !this.squares[this.pacmanCurrentIndex + this.width].classList.contains('wall') && + !this.squares[this.pacmanCurrentIndex + this.width].classList.contains('ghost-lair') + ) { + this.pacmanCurrentIndex += this.width + } + } + + if ($event.keyCode === KEY_CODE.UP_ARROW) { + if ( + this.pacmanCurrentIndex - this.width >= 0 && + !this.squares[this.pacmanCurrentIndex - this.width].classList.contains('wall') && + !this.squares[this.pacmanCurrentIndex - this.width].classList.contains('ghost-lair') + ) { + this.pacmanCurrentIndex -= this.width + } + } + this.renderer.addClass(this.squares[this.pacmanCurrentIndex], 'pac-man'); + this.pacDotEaten(); + this.powerPelletEaten(); + this.checkForGameOver(this.squares, this.pacmanCurrentIndex); + this.checkforWin(); + })); + + + /** + * Generate the 28x28 grid board + * Colour all the element with the array define on the layout + */ + createBoard() { + for (let i = 0; i < this.layout.length; i++) { + const square = this.renderer.createElement('div'); + this.renderer.appendChild(this.grid.nativeElement, square); + this.squares.push(square) + + if (this.layout[i] === 0) { + this.renderer.addClass(this.squares[i], 'pac-dot'); + } else if (this.layout[i] === 1) { + this.renderer.addClass(this.squares[i], 'wall'); + } else if (this.layout[i] === 2) { + this.renderer.addClass(this.squares[i], 'ghost-lair'); + } else if (this.layout[i] === 3) { + this.renderer.addClass(this.squares[i], 'power-pellet'); + } + } + } + + ngOnInit(): void { + + } ngOnDestroy(): void { - } - - // init all the ghosts from the array - // randonmy set interval to move the ghost around. - initGhosts(){ - this.ghosts.forEach(ghost =>{ - this.squares[ghost.currentIndex].classList.add('ghost'); - this.squares[ghost.currentIndex].classList.add(ghost.className); - this.moveGhost(ghost); - }); - - } - - /** - * Randomly move the ghost - * Check whether those ghost are afraid of the pacman - * Anti collision - * @param ghost - */ - moveGhost(ghost) { - // please implement this. - var widthX = this.width; - var squaresY = this.squares; - var scoreValX = this.scoreValue; - var pacmanCurrentIndexX = this.pacmanCurrentIndex; - var checkForGameOverX = this.checkForGameOver; - ghost.timerId = setInterval(function() { - const directions = [-1 , +1, +widthX, -widthX]; - let direction = directions[Math.floor(Math.random() * directions.length)]; - if (!squaresY[ghost.currentIndex + direction].classList.contains('ghost') && - !squaresY[ghost.currentIndex + direction].classList.contains('wall') - ) { - squaresY[ghost.currentIndex].classList.remove(ghost.className); - squaresY[ghost.currentIndex].classList.remove('ghost', 'scared-ghost'); - ghost.currentIndex += direction - ghost.previousIndex = ghost.currentIndex; - squaresY[ghost.currentIndex].classList.add(ghost.className, 'ghost'); - }else { - direction = directions[Math.floor(Math.random() * directions.length)]; - } - if (ghost.isScared) { - squaresY[ghost.currentIndex].classList.add('scared-ghost') - } - - if(ghost.isScared && squaresY[ghost.currentIndex].classList.contains('pac-man')) { - squaresY[ghost.currentIndex].classList.remove(ghost.className, 'ghost', 'scared-ghost') - ghost.currentIndex = ghost.startIndex - scoreValX +=100 - squaresY[ghost.currentIndex].classList.add(ghost.className, 'ghost') - } - checkForGameOverX(squaresY, pacmanCurrentIndexX); - }, ghost.speed); - } - - /** - * Check whether the game is over. if the pacman touches the ghost when it is not isScared - * then end the game by removing the keyUp event from the window/document. - */ - checkForGameOver(squaresX, pacmanCurrentIndexX) { - if (squaresX[pacmanCurrentIndexX].classList.contains('ghost') && - !squaresX[pacmanCurrentIndexX].classList.contains('scared-ghost') - ) { - this.ghosts.forEach(ghost=> clearInterval(ghost.timerId)) - this.KeyUpEvent = function() : void {}; - this.result.nativeElement.innerHTML = "Game Over!"; - } - - } - - - /** - * Check whether has pacman consume all the pellet from the grid - * if yes then display the winning message - */ - checkforWin() { - if(this.scoreValue === 274) { - this.ghosts.forEach(ghost => clearInterval(ghost.timerId)) - this.KeyUpEvent = function() : void {}; - this.result.nativeElement.innerHTML = "You have Won!"; - } - } - - /** - * Initialize the board by generating 28x28 grid - * Render the initial start position of the pacman - * Also render the all the ghosts within the array list - */ - ngAfterViewInit() { - // create the pac man board - this.createBoard(); - this.renderer.addClass(this.squares[this.pacmanCurrentIndex], 'pac-man'); - this.initGhosts(); - } - - /** - * What happens when pacman is busy eating the small pellet - * Increment the score - * Remove the small pellet from the grid once is consume by pacman - */ - pacDotEaten() { - if( this.squares[this.pacmanCurrentIndex].classList.contains('pac-dot')) { - this.scoreValue++ - this.score.nativeElement.innerHTML = this.scoreValue; - this.squares[this.pacmanCurrentIndex].classList.remove('pac-dot'); - } - } - - /** - * Once pacman consume the power pellet it gain super power - * All the ghost will be afraid of em. - * By right the ghost should run away from pacman as much as possible - * Set an timeout for the ghost to turn back to hunting mode rather than - * scare of pacman. - */ - powerPelletEaten() { - if( this.squares[this.pacmanCurrentIndex].classList.contains('power-pellet')) { - this.scoreValue+=10 - this.score.nativeElement.innerHTML = this.scoreValue; - this.ghosts.forEach(ghost => { - ghost.isScared = true; - console.log("turn to scared of pacman"); - // turn the ghost colour to aquamarine. - this.squares[ghost.currentIndex].classList.add(ghost.className, 'ghost', 'scared-ghost'); - }); - setTimeout(()=>{ - this.ghosts.forEach(ghost => { - ghost.isScared = false - this.squares[ghost.currentIndex].classList.remove(ghost.className, 'ghost', 'scared-ghost') - ghost.currentIndex = ghost.startIndex - this.squares[ghost.currentIndex].classList.add(ghost.className, 'ghost') - }) - }, 10000) - this.squares[this.pacmanCurrentIndex].classList.remove('power-pellet'); - } - } + } + + // init all the ghosts from the array + // set interval to move the ghost around. + initGhosts() { + this.ghosts.forEach(ghost => { + this.squares[ghost.currentIndex].classList.add('ghost'); + this.squares[ghost.currentIndex].classList.add(ghost.className); + this.moveGhost(ghost); + }); + + } + + /** + * Randomly move the ghost + * Check whether those ghost are afraid of the pacman + * Anti collision + * @param ghost + */ + moveGhost(ghost) { + // please implement this. + let widthX = this.width; + let squaresY = this.squares; + let scoreValX = this.scoreValue; + let pacmanCurrentIndexX = this.pacmanCurrentIndex; + let checkForGameOverX = this.checkForGameOver; + ghost.timerId = setInterval(function () { + const directions = [-1, +1, +widthX, -widthX]; + let direction = directions[Math.floor(Math.random() * directions.length)]; + if (!squaresY[ghost.currentIndex + direction].classList.contains('ghost') && + !squaresY[ghost.currentIndex + direction].classList.contains('wall') + ) { + squaresY[ghost.currentIndex].classList.remove(ghost.className); + squaresY[ghost.currentIndex].classList.remove('ghost', 'scared-ghost'); + ghost.currentIndex += direction + ghost.previousIndex = ghost.currentIndex; + squaresY[ghost.currentIndex].classList.add(ghost.className, 'ghost'); + } else { + direction = directions[Math.floor(Math.random() * directions.length)]; + } + if (ghost.isScared) { + squaresY[ghost.currentIndex].classList.add('scared-ghost') + } + + if (ghost.isScared && squaresY[ghost.currentIndex].classList.contains('pac-man')) { + squaresY[ghost.currentIndex].classList.remove(ghost.className, 'ghost', 'scared-ghost') + ghost.currentIndex = ghost.startIndex + scoreValX += 100 + squaresY[ghost.currentIndex].classList.add(ghost.className, 'ghost') + } + checkForGameOverX(squaresY, pacmanCurrentIndexX); + }, ghost.speed); + } + + /** + * Check whether the game is over. if the pacman touches the ghost when it is not isScared + * then end the game by removing the keyUp event from the window/document. + */ + checkForGameOver(squaresX, pacmanCurrentIndexX) { + if (squaresX[pacmanCurrentIndexX].classList.contains('ghost') && + !squaresX[pacmanCurrentIndexX].classList.contains('scared-ghost') + ) { + this.ghosts.forEach(ghost => clearInterval(ghost.timerId)); + this.isPacmanAlive = false; + this.result.nativeElement.innerHTML = "Game Over!"; + } + + } + + + /** + * Check whether has pacman consume all the pellet from the grid + * if yes then display the winning message + */ + checkforWin() { + if (this.scoreValue === 274) { + this.ghosts.forEach(ghost => clearInterval(ghost.timerId)); + this.isPacmanAlive = false; + this.result.nativeElement.innerHTML = "You have Won!"; + } + } + + /** + * Initialize the board by generating 28x28 grid + * Render the initial start position of the pacman + * Also render the all the ghosts within the array list + */ + ngAfterViewInit() { + // create the pac man board + this.createBoard(); + this.renderer.addClass(this.squares[this.pacmanCurrentIndex], 'pac-man'); + this.initGhosts(); + } + + /** + * What happens when pacman is busy eating the small pellet + * Increment the score + * Remove the small pellet from the grid once is consume by pacman + */ + pacDotEaten() { + if (this.squares[this.pacmanCurrentIndex].classList.contains('pac-dot')) { + this.scoreValue++ + this.score.nativeElement.innerHTML = this.scoreValue; + this.squares[this.pacmanCurrentIndex].classList.remove('pac-dot'); + } + } + + /** + * Once pacman consume the power pellet it gain super power + * All the ghost will be afraid of em. + * By right the ghost should run away from pacman as much as possible + * Set an timeout for the ghost to turn back to hunting mode rather than + * scare of pacman. + */ + powerPelletEaten() { + if (this.squares[this.pacmanCurrentIndex].classList.contains('power-pellet')) { + this.scoreValue += 10 + this.score.nativeElement.innerHTML = this.scoreValue; + this.ghosts.forEach(ghost => { + ghost.isScared = true; + console.log("turn to scared of pacman"); + // turn the ghost colour to aquamarine. + this.squares[ghost.currentIndex].classList.add(ghost.className, 'ghost', 'scared-ghost'); + }); + setTimeout(() => { + this.ghosts.forEach(ghost => { + ghost.isScared = false + this.squares[ghost.currentIndex].classList.remove(ghost.className, 'ghost', 'scared-ghost') + ghost.currentIndex = ghost.startIndex + this.squares[ghost.currentIndex].classList.add(ghost.className, 'ghost') + }) + }, 10000) + this.squares[this.pacmanCurrentIndex].classList.remove('power-pellet'); + } + } } diff --git a/src/app/@ansyn/ansyn/modules/overlays/components/overlay-navigation-bar/overlay-navigation-bar.component.ts b/src/app/@ansyn/ansyn/modules/overlays/components/overlay-navigation-bar/overlay-navigation-bar.component.ts index 058a15731e..cdcdd13604 100644 --- a/src/app/@ansyn/ansyn/modules/overlays/components/overlay-navigation-bar/overlay-navigation-bar.component.ts +++ b/src/app/@ansyn/ansyn/modules/overlays/components/overlay-navigation-bar/overlay-navigation-bar.component.ts @@ -33,7 +33,7 @@ export class OverlayNavigationBarComponent implements OnInit, OnDestroy { tap($event => { if (this.keyListenerService.keyWasUsed($event, 'ArrowRight', 39)) { this.goNextActive = true; - } else if (this.keyWasUsed($event, 'ArrowLeft', 37)) { + } else if (this.keyListenerService.keyWasUsed($event, 'ArrowLeft', 37)) { this.goPrevActive = true; } @@ -41,7 +41,20 @@ export class OverlayNavigationBarComponent implements OnInit, OnDestroy { this.store.dispatch(new EnableCopyOriginalOverlayDataAction(true)); } }) - ) + ); + + @AutoSubscription + onkeypress$ = () => this.keyListenerService.keyup.pipe( + tap($event => { + if (this.keyListenerService.isElementNotValid($event)) { + return; + } + + if (this.keyListenerService.keysWereUsed($event, this._scannedAreaKeys)) { + this.clickScannedArea(); + } + } + )); @AutoSubscription onKeyUp$ = () => this.keyListenerService.keyup.pipe( @@ -58,11 +71,11 @@ export class OverlayNavigationBarComponent implements OnInit, OnDestroy { this.goPrevActive = false; } - if (this.keysWereUsed($event, this._overlayHackKeys)) { + if (this.keyListenerService.keysWereUsed($event, this._overlayHackKeys)) { this.store.dispatch(new EnableCopyOriginalOverlayDataAction(false)); } - if (this.keysWereUsed($event, this._toggleDirectionKeys)) { + if (this.keyListenerService.keysWereUsed($event, this._toggleDirectionKeys)) { const direction = this.translateService.instant('direction'); this.translateService.set('direction', direction === 'rtl' ? 'ltr' : 'rtl', 'default'); } @@ -100,77 +113,6 @@ export class OverlayNavigationBarComponent implements OnInit, OnDestroy { ) { } - isElementNotValid($event: KeyboardEvent) { - const {activeElement} = ($event.currentTarget).document; - return this.isElementInput(activeElement) || this.isTimePicker(activeElement); - } - - isElementInput(activeElement) { - return activeElement instanceof HTMLInputElement; - } - - isTimePicker(activeElement) { - const {className} = activeElement; - return className.includes('owl') || className.includes('title'); - } - - // @HostListener('window:keyup', ['$event']) - // onkeyup($event: KeyboardEvent) { - // if (this.keyWasUsed($event, 'ArrowRight', 39)) { - // this.clickGoAdjacent(true); - // this.goNextActive = false; - // } else if (this.keyWasUsed($event, 'ArrowLeft', 37)) { - // this.clickGoAdjacent(false); - // this.goPrevActive = false; - // } - // - // if (this.keysWereUsed($event, this._overlayHackKeys)) { - // this.store.dispatch(new EnableCopyOriginalOverlayDataAction(false)); - // } - // - // if (this.keysWereUsed($event, this._toggleDirectionKeys)) { - // const direction = this.translateService.instant('direction'); - // this.translateService.set('direction', direction === 'rtl' ? 'ltr' : 'rtl', 'default'); - // } - // } - // - // @HostListener('window:keydown', ['$event']) - // onkeydown($event: KeyboardEvent) { - // if (this.isElementNotValid($event)) { - // return; - // } - // - // if (this.keyWasUsed($event, 'ArrowRight', 39)) { - // this.goNextActive = true; - // } else if (this.keyWasUsed($event, 'ArrowLeft', 37)) { - // this.goPrevActive = true; - // } - // - // if (this.keysWereUsed($event, this._overlayHackKeys)) { - // this.store.dispatch(new EnableCopyOriginalOverlayDataAction(true)); - // } - // } - - @HostListener('window:keypress', ['$event']) - onkeypress($event: KeyboardEvent) { - if (this.isElementNotValid($event)) { - return; - } - - if (this.keysWereUsed($event, this._scannedAreaKeys)) { - this.clickScannedArea(); - } - } - - private keyWasUsed(event: KeyboardEvent, key: string, keycode: number = key.charCodeAt(0)): boolean { - return event.key === key || event.which === keycode; // tslint:disable-line - // We need to check also on the old field event.which, for Chrome 44 - } - - private keysWereUsed(event: KeyboardEvent, keys: string[]): boolean { - return keys.some(key => this.keyWasUsed(event, key)); - } - clickGoAdjacent(isNext): void { this.store.dispatch(new GoAdjacentOverlay({isNext})); } From aa1e4611a45ff9f0242a169c7509041d5aead8ba Mon Sep 17 00:00:00 2001 From: Danaorlov1005 Date: Mon, 5 Apr 2021 18:38:36 +0300 Subject: [PATCH 03/21] added little bit k --- .../core/components/angle-filter/angle-filter.component.ts | 1 - .../ansyn/modules/core/services/keys-listener.service.ts | 3 +-- .../easter-eggs/pacman-popup/pacman-popup.component.ts | 2 +- .../overlay-navigation-bar.component.ts | 2 +- .../ansyn/modules/status-bar/reducers/status-bar.reducer.ts | 4 +++- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/app/@ansyn/ansyn/modules/core/components/angle-filter/angle-filter.component.ts b/src/app/@ansyn/ansyn/modules/core/components/angle-filter/angle-filter.component.ts index 29ee09080f..4cb6603ced 100644 --- a/src/app/@ansyn/ansyn/modules/core/components/angle-filter/angle-filter.component.ts +++ b/src/app/@ansyn/ansyn/modules/core/components/angle-filter/angle-filter.component.ts @@ -2,7 +2,6 @@ import { Component, ElementRef, HostBinding, HostListener, OnDestroy, OnInit, Re import { ImageryCommunicatorService, toDegrees, - toRadians } from '@ansyn/imagery'; import { ContextMenuShowAngleFilter, diff --git a/src/app/@ansyn/ansyn/modules/core/services/keys-listener.service.ts b/src/app/@ansyn/ansyn/modules/core/services/keys-listener.service.ts index 2c8c6e7e78..2cee9fbdf7 100644 --- a/src/app/@ansyn/ansyn/modules/core/services/keys-listener.service.ts +++ b/src/app/@ansyn/ansyn/modules/core/services/keys-listener.service.ts @@ -1,6 +1,5 @@ -import { Injectable, Output, EventEmitter, HostListener, OnInit } from '@angular/core'; +import { Injectable, Output, EventEmitter } from '@angular/core'; import { fromEvent } from "rxjs"; -import { take } from "rxjs/operators"; @Injectable({providedIn: 'any'}) export class KeysListenerService { diff --git a/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.ts b/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.ts index 6e8b38f469..4360241651 100644 --- a/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.ts +++ b/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, ViewChild, ElementRef, Renderer2, HostListener, OnDestroy } from '@angular/core'; +import { Component, OnInit, ViewChild, ElementRef, Renderer2, OnDestroy } from '@angular/core'; import { KeysListenerService } from "../../core/services/keys-listener.service"; import { AutoSubscription, AutoSubscriptions } from "auto-subscriptions"; import { filter, tap } from "rxjs/operators"; diff --git a/src/app/@ansyn/ansyn/modules/overlays/components/overlay-navigation-bar/overlay-navigation-bar.component.ts b/src/app/@ansyn/ansyn/modules/overlays/components/overlay-navigation-bar/overlay-navigation-bar.component.ts index cdcdd13604..0245dd748c 100644 --- a/src/app/@ansyn/ansyn/modules/overlays/components/overlay-navigation-bar/overlay-navigation-bar.component.ts +++ b/src/app/@ansyn/ansyn/modules/overlays/components/overlay-navigation-bar/overlay-navigation-bar.component.ts @@ -1,4 +1,4 @@ -import { Component, HostListener, Inject, OnDestroy, OnInit } from '@angular/core'; +import { Component, Inject, OnDestroy, OnInit } from '@angular/core'; import { Store } from '@ngrx/store'; import { IStatusBarState } from '../../../status-bar/reducers/status-bar.reducer'; import { ExpandAction, GoAdjacentOverlay } from '../../../status-bar/actions/status-bar.actions'; diff --git a/src/app/@ansyn/ansyn/modules/status-bar/reducers/status-bar.reducer.ts b/src/app/@ansyn/ansyn/modules/status-bar/reducers/status-bar.reducer.ts index 6e6e164fc8..c3c8c9240a 100644 --- a/src/app/@ansyn/ansyn/modules/status-bar/reducers/status-bar.reducer.ts +++ b/src/app/@ansyn/ansyn/modules/status-bar/reducers/status-bar.reducer.ts @@ -14,6 +14,7 @@ export interface IStatusBarState { IsSimpleSearchOpen?: boolean; IsOpenedFromOutside?: boolean; markSecondSearchSensors?: boolean; + isPacmanMode?: boolean; } export const StatusBarInitialState: IStatusBarState = { @@ -25,7 +26,8 @@ export const StatusBarInitialState: IStatusBarState = { isAdvancedSearchOpen: false, IsSimpleSearchOpen: false, IsOpenedFromOutside: false, - markSecondSearchSensors: false + markSecondSearchSensors: false, + isPacmanMode: false// add action to status-bar actions that changes this ok? }; export const statusBarFeatureKey = 'statusBar'; From 192b434e84ba1897a47a11bfce8ab3bc48785ac6 Mon Sep 17 00:00:00 2001 From: Danaorlov1005 Date: Mon, 12 Apr 2021 15:04:50 +0300 Subject: [PATCH 04/21] fixed moving overlays bug --- .../pacman-popup/pacman-popup.component.ts | 10 +++++++--- .../overlay-navigation-bar.component.ts | 19 ++++++++++++++----- .../status-bar/actions/status-bar.actions.ts | 11 ++++++++++- .../status-bar/reducers/status-bar.reducer.ts | 8 +++++++- 4 files changed, 38 insertions(+), 10 deletions(-) diff --git a/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.ts b/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.ts index 4360241651..0a8af2bb8b 100644 --- a/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.ts +++ b/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.ts @@ -2,6 +2,8 @@ import { Component, OnInit, ViewChild, ElementRef, Renderer2, OnDestroy } from ' import { KeysListenerService } from "../../core/services/keys-listener.service"; import { AutoSubscription, AutoSubscriptions } from "auto-subscriptions"; import { filter, tap } from "rxjs/operators"; +import { PacnManModeAction } from "../../status-bar/actions/status-bar.actions"; +import { Store } from "@ngrx/store"; export enum KEY_CODE { RIGHT_ARROW = 39, @@ -25,7 +27,7 @@ class Ghost { this.speed = speed; this.currentIndex = startIndex; this.previousIndex = startIndex; - this.isScared = false + this.isScared = false, this.timerId = NaN } } @@ -97,7 +99,8 @@ export class PacmanPopupComponent implements OnInit, OnDestroy { constructor(private renderer: Renderer2, public keyListenerService: KeysListenerService, - private elem: ElementRef) { + private elem: ElementRef, + protected store$: Store) { } @@ -185,10 +188,11 @@ export class PacmanPopupComponent implements OnInit, OnDestroy { } ngOnInit(): void { - + this.store$.dispatch(new PacnManModeAction(true)); } ngOnDestroy(): void { + this.store$.dispatch(new PacnManModeAction(false)); } // init all the ghosts from the array diff --git a/src/app/@ansyn/ansyn/modules/overlays/components/overlay-navigation-bar/overlay-navigation-bar.component.ts b/src/app/@ansyn/ansyn/modules/overlays/components/overlay-navigation-bar/overlay-navigation-bar.component.ts index 0245dd748c..845e1e5f96 100644 --- a/src/app/@ansyn/ansyn/modules/overlays/components/overlay-navigation-bar/overlay-navigation-bar.component.ts +++ b/src/app/@ansyn/ansyn/modules/overlays/components/overlay-navigation-bar/overlay-navigation-bar.component.ts @@ -1,18 +1,23 @@ import { Component, Inject, OnDestroy, OnInit } from '@angular/core'; -import { Store } from '@ngrx/store'; -import { IStatusBarState } from '../../../status-bar/reducers/status-bar.reducer'; +import { select, Store } from '@ngrx/store'; +import { + IStatusBarState, + selectMarkedSecondSearchSensors, + selectPacmanMode +} from '../../../status-bar/reducers/status-bar.reducer'; import { ExpandAction, GoAdjacentOverlay } from '../../../status-bar/actions/status-bar.actions'; import { IStatusBarConfig } from '../../../status-bar/models/statusBar-config.model'; import { StatusBarConfig } from '../../../status-bar/models/statusBar.config'; import { EnableCopyOriginalOverlayDataAction, selectOverlayOfActiveMap } from '@ansyn/map-facade'; import { ActivateScannedAreaAction } from '../../overlay-status/actions/overlay-status.actions'; import { AutoSubscription, AutoSubscriptions } from 'auto-subscriptions'; -import { tap, filter } from 'rxjs/operators'; +import { tap, filter, withLatestFrom } from 'rxjs/operators'; import { selectDropsAscending, selectFilteredOveralys } from '../../reducers/overlays.reducer'; import { combineLatest } from 'rxjs'; import { IOverlay, IOverlayDrop } from '../../models/overlay.model'; import { TranslateService } from '@ngx-translate/core'; import { KeysListenerService } from "../../../core/services/keys-listener.service"; +import { LoadOverlaysAction } from "../../actions/overlays.actions"; @Component({ selector: 'ansyn-overlay-navigation-bar', @@ -30,7 +35,9 @@ export class OverlayNavigationBarComponent implements OnInit, OnDestroy { @AutoSubscription onKeyDown$ = () => this.keyListenerService.keydown.pipe( - tap($event => { + withLatestFrom(this.store.select(selectPacmanMode)), + filter(([$event, isPacmanMode]: [KeyboardEvent, boolean]) => !isPacmanMode), + tap(([$event, isPacmanMode]: [KeyboardEvent, boolean]) => { if (this.keyListenerService.keyWasUsed($event, 'ArrowRight', 39)) { this.goNextActive = true; } else if (this.keyListenerService.keyWasUsed($event, 'ArrowLeft', 37)) { @@ -58,7 +65,9 @@ export class OverlayNavigationBarComponent implements OnInit, OnDestroy { @AutoSubscription onKeyUp$ = () => this.keyListenerService.keyup.pipe( - tap($event => { + withLatestFrom(this.store.select(selectPacmanMode)), + filter(([$event, isPacmanMode]: [KeyboardEvent, boolean]) => !isPacmanMode), + tap(([$event, isPacmanMode]: [KeyboardEvent, boolean]) => { if (this.keyListenerService.isElementNotValid($event)) { return; } diff --git a/src/app/@ansyn/ansyn/modules/status-bar/actions/status-bar.actions.ts b/src/app/@ansyn/ansyn/modules/status-bar/actions/status-bar.actions.ts index df315a38ce..e3d1a3effe 100644 --- a/src/app/@ansyn/ansyn/modules/status-bar/actions/status-bar.actions.ts +++ b/src/app/@ansyn/ansyn/modules/status-bar/actions/status-bar.actions.ts @@ -15,7 +15,8 @@ export const StatusBarActionsTypes = { TOGGLE_SIMPLE_SEARCH: 'TOGGLE_SIMPLE_SEARCH', OPENED_FROM_OUTSIDE: 'OPENED_FROM_OUTSIDE', SEARCH_ACTION: 'SEARCH_ACTION', - MARK_SECOND_SEARCH: 'MARK_SECOND_SEARCH' + MARK_SECOND_SEARCH: 'MARK_SECOND_SEARCH', + PACMAN_MODE: 'PACMAN_MODE' }; export class CopySnapshotShareLinkAction implements Action, ILogMessage { @@ -65,6 +66,14 @@ export class MarkSecondSearchSensorsAction implements Action { } } + +export class PacnManModeAction implements Action { + type: string = StatusBarActionsTypes.PACMAN_MODE; + + constructor(public payload: boolean) { + } +} + export class ExpandAction implements Action { type: string = StatusBarActionsTypes.EXPAND; diff --git a/src/app/@ansyn/ansyn/modules/status-bar/reducers/status-bar.reducer.ts b/src/app/@ansyn/ansyn/modules/status-bar/reducers/status-bar.reducer.ts index c3c8c9240a..5f8221222a 100644 --- a/src/app/@ansyn/ansyn/modules/status-bar/reducers/status-bar.reducer.ts +++ b/src/app/@ansyn/ansyn/modules/status-bar/reducers/status-bar.reducer.ts @@ -27,7 +27,7 @@ export const StatusBarInitialState: IStatusBarState = { IsSimpleSearchOpen: false, IsOpenedFromOutside: false, markSecondSearchSensors: false, - isPacmanMode: false// add action to status-bar actions that changes this ok? + isPacmanMode: false }; export const statusBarFeatureKey = 'statusBar'; @@ -64,6 +64,10 @@ export function StatusBarReducer(state = StatusBarInitialState, action: StatusBa const { payload } = action; return { ...state, markSecondSearchSensors: payload} } + case StatusBarActionsTypes.PACMAN_MODE: { + const { payload } = action; + return { ...state, isPacmanMode: payload} + } default: return state; @@ -76,6 +80,8 @@ export const selectCalenderStatus = createSelector(statusBarStateSelector, (stat export const selectAdvancedSearchStatus = createSelector(statusBarStateSelector, (statusBar: IStatusBarState) => statusBar ? statusBar.isAdvancedSearchOpen : StatusBarInitialState.isAdvancedSearchOpen); export const selectSimpledSearchStatus = createSelector(statusBarStateSelector, (statusBar: IStatusBarState) => statusBar ? statusBar.IsSimpleSearchOpen : StatusBarInitialState.IsSimpleSearchOpen); export const selectIsOpenedFromOutside = createSelector(statusBarStateSelector, (statusBar: IStatusBarState) => statusBar ? statusBar.IsOpenedFromOutside : StatusBarInitialState.IsOpenedFromOutside); +export const selectPacmanMode = createSelector(statusBarStateSelector, (statusBar: IStatusBarState) => statusBar ? statusBar.isPacmanMode : StatusBarInitialState.isPacmanMode); export const selectMarkedSecondSearchSensors = createSelector(statusBarStateSelector, (statusBar: IStatusBarState) => statusBar?.markSecondSearchSensors); export const selectGeoFilterActive = createSelector(selectGeoFilterStatus, (geoFilterStatus: IGeoFilterStatus) => geoFilterStatus.active); export const selectGeoFilterType = createSelector(selectGeoFilterStatus, (geoFilterStatus: IGeoFilterStatus) => geoFilterStatus.type); + From c14a59d7e5beff25580a09038aaf9639eaac6f58 Mon Sep 17 00:00:00 2001 From: Danaorlov1005 Date: Mon, 12 Apr 2021 16:41:44 +0300 Subject: [PATCH 05/21] fix lint --- package-lock.json | 2 +- .../pacman-popup/pacman-popup.component.ts | 4 +- .../overlay-navigation-bar.component.ts | 66 +++++++++---------- .../components/tools/tools/tools.component.ts | 64 +++++++++--------- 4 files changed, 68 insertions(+), 68 deletions(-) diff --git a/package-lock.json b/package-lock.json index bb20b5aad4..7a691c4dab 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "ansyn-src", - "version": "4.1.1", + "version": "5.0.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.ts b/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.ts index 0a8af2bb8b..bc98187d6f 100644 --- a/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.ts +++ b/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, ViewChild, ElementRef, Renderer2, OnDestroy } from '@angular/core'; +import { Component, OnInit, ViewChild, ElementRef, Renderer2, OnDestroy, AfterViewInit } from '@angular/core'; import { KeysListenerService } from "../../core/services/keys-listener.service"; import { AutoSubscription, AutoSubscriptions } from "auto-subscriptions"; import { filter, tap } from "rxjs/operators"; @@ -38,7 +38,7 @@ class Ghost { styleUrls: ['./pacman-popup.component.less'] }) @AutoSubscriptions() -export class PacmanPopupComponent implements OnInit, OnDestroy { +export class PacmanPopupComponent implements OnInit, OnDestroy, AfterViewInit { title = 'angular-pacman'; width = 28; diff --git a/src/app/@ansyn/ansyn/modules/overlays/components/overlay-navigation-bar/overlay-navigation-bar.component.ts b/src/app/@ansyn/ansyn/modules/overlays/components/overlay-navigation-bar/overlay-navigation-bar.component.ts index a24e813c91..5e1432cf31 100644 --- a/src/app/@ansyn/ansyn/modules/overlays/components/overlay-navigation-bar/overlay-navigation-bar.component.ts +++ b/src/app/@ansyn/ansyn/modules/overlays/components/overlay-navigation-bar/overlay-navigation-bar.component.ts @@ -1,8 +1,7 @@ import { Component, Inject, OnDestroy, OnInit } from '@angular/core'; -import { select, Store } from '@ngrx/store'; +import { Store } from '@ngrx/store'; import { IStatusBarState, - selectMarkedSecondSearchSensors, selectPacmanMode } from '../../../status-bar/reducers/status-bar.reducer'; import { ExpandAction, GoAdjacentOverlay } from '../../../status-bar/actions/status-bar.actions'; @@ -17,7 +16,6 @@ import { combineLatest } from 'rxjs'; import { IOverlay, IOverlayDrop } from '../../models/overlay.model'; import { TranslateService } from '@ngx-translate/core'; import { KeysListenerService } from "../../../core/services/keys-listener.service"; -import { LoadOverlaysAction } from "../../actions/overlays.actions"; @Component({ selector: 'ansyn-overlay-navigation-bar', @@ -33,6 +31,37 @@ export class OverlayNavigationBarComponent implements OnInit, OnDestroy { isLastOverlay: boolean; overlaysLength: number; + private _scannedAreaKeys = '`~;'.split(''); + private _overlayHackKeys = 'Eeק'.split(''); + private _toggleDirectionKeys = 'Ddג'.split(''); + + @AutoSubscription + hasOverlayDisplay$ = this.store.select(selectOverlayOfActiveMap).pipe( + tap(overlay => this.hasOverlayDisplay = Boolean(overlay)) + ); + + @AutoSubscription + isLastOrFirstOverlay$ = combineLatest([ + this.store.select(selectOverlayOfActiveMap), + this.store.select(selectDropsAscending), + this.store.select(selectFilteredOverlays) + ]).pipe( + filter(([activeMapOverlay, overlays, filtered]: [IOverlay, IOverlayDrop[], any[]]) => Boolean(activeMapOverlay) && Boolean(overlays.length)), + tap(([activeMapOverlay, overlays, filtered]: [IOverlay, IOverlayDrop[], IOverlay[]]) => { + this.overlaysLength = filtered.length; + this.isFirstOverlay = activeMapOverlay.id === overlays[0].id; + this.isLastOverlay = activeMapOverlay.id === overlays[overlays.length - 1].id; + }) + ); + + constructor( + protected store: Store, + public keyListenerService: KeysListenerService, + @Inject(StatusBarConfig) public statusBarConfig: IStatusBarConfig, + protected translateService: TranslateService + ) { + } + @AutoSubscription onKeyDown$ = () => this.keyListenerService.keydown.pipe( withLatestFrom(this.store.select(selectPacmanMode)), @@ -91,37 +120,6 @@ export class OverlayNavigationBarComponent implements OnInit, OnDestroy { }) ); - @AutoSubscription - hasOverlayDisplay$ = this.store.select(selectOverlayOfActiveMap).pipe( - tap(overlay => this.hasOverlayDisplay = Boolean(overlay)) - ); - - @AutoSubscription - isLastOrFirstOverlay$ = combineLatest([ - this.store.select(selectOverlayOfActiveMap), - this.store.select(selectDropsAscending), - this.store.select(selectFilteredOverlays) - ]).pipe( - filter(([activeMapOverlay, overlays, filtered]: [IOverlay, IOverlayDrop[], any[]]) => Boolean(activeMapOverlay) && Boolean(overlays.length)), - tap(([activeMapOverlay, overlays, filtered]: [IOverlay, IOverlayDrop[], IOverlay[]]) => { - this.overlaysLength = filtered.length; - this.isFirstOverlay = activeMapOverlay.id === overlays[0].id; - this.isLastOverlay = activeMapOverlay.id === overlays[overlays.length - 1].id; - }) - ); - - private _scannedAreaKeys = '`~;'.split(''); - private _overlayHackKeys = 'Eeק'.split(''); - private _toggleDirectionKeys = 'Ddג'.split(''); - - constructor( - protected store: Store, - public keyListenerService: KeysListenerService, - @Inject(StatusBarConfig) public statusBarConfig: IStatusBarConfig, - protected translateService: TranslateService - ) { - } - clickGoAdjacent(isNext): void { this.store.dispatch(new GoAdjacentOverlay({isNext})); } diff --git a/src/app/@ansyn/ansyn/modules/status-bar/components/tools/tools/tools.component.ts b/src/app/@ansyn/ansyn/modules/status-bar/components/tools/tools/tools.component.ts index 1186de8ba8..bb953611ca 100644 --- a/src/app/@ansyn/ansyn/modules/status-bar/components/tools/tools/tools.component.ts +++ b/src/app/@ansyn/ansyn/modules/status-bar/components/tools/tools/tools.component.ts @@ -30,6 +30,26 @@ import { KeysListenerService } from "../../../../core/services/keys-listener.ser destroy: 'ngOnDestroy' }) export class ToolsComponent implements OnInit, OnDestroy { + + get subMenuEnum() { + return SubMenuEnum; + } + + get isGeoOptionsDisabled() { + return !this.flags?.get(toolsFlags.geoRegisteredOptionsEnabled); + } + + get shadowMouseDisabled() { + return this.flags?.get(toolsFlags.shadowMouseDisabled); + } + + get onShadowMouse() { + return this.flags?.get(toolsFlags.shadowMouse); + } + + get onMeasureTool() { + return this.flags?.get(toolsFlags.isMeasureToolActive); + } // for component readonly isExportShow: boolean; readonly isGoToShow: boolean; @@ -41,20 +61,14 @@ export class ToolsComponent implements OnInit, OnDestroy { public displayModeOn = false; public flags: Map; toolTipDirection = 'bottom' + + private _pacmanKeys = 'Ppפ'.split(''); + @AutoSubscription public flags$: Observable> = this.store$.select(selectToolFlags).pipe( tap((flags: Map) => this.flags = flags) ); - @AutoSubscription - onKeyUp$ = () => this.keyListenerService.keyup.pipe( - tap($event => { - if (this.keyListenerService.keysWereUsed($event, this._pacmanKeys)) { - this.togglePacmanDialog(); - } - }) - ); - isActiveAnnotationLayer$ = this.store$.select(selectActiveAnnotationLayer).pipe( map(Boolean) ); @@ -66,28 +80,6 @@ export class ToolsComponent implements OnInit, OnDestroy { subMenu: SubMenuEnum; - get subMenuEnum() { - return SubMenuEnum; - } - - get isGeoOptionsDisabled() { - return !this.flags?.get(toolsFlags.geoRegisteredOptionsEnabled); - } - - get shadowMouseDisabled() { - return this.flags?.get(toolsFlags.shadowMouseDisabled); - } - - get onShadowMouse() { - return this.flags?.get(toolsFlags.shadowMouse); - } - - get onMeasureTool() { - return this.flags?.get(toolsFlags.isMeasureToolActive); - } - - private _pacmanKeys = 'Ppפ'.split(''); - constructor( protected store$: Store, public dialog: MatDialog, @@ -101,6 +93,16 @@ export class ToolsComponent implements OnInit, OnDestroy { this.isShadowMouseShow = componentVisibilityService.get(ComponentVisibilityItems.SHADOW_MOUSE); } + @AutoSubscription + onKeyUp$ = () => this.keyListenerService.keyup.pipe( + tap($event => { + if (this.keyListenerService.keysWereUsed($event, this._pacmanKeys)) { + this.togglePacmanDialog(); + } + }) + ); + + ngOnInit() { } From 51bf7fc2a1c891f49791ce520a9e3fc5e3d722c7 Mon Sep 17 00:00:00 2001 From: Danaorlov1005 Date: Mon, 12 Apr 2021 16:57:06 +0300 Subject: [PATCH 06/21] added more lint fixes --- .../services/keys-listener.service.spec.ts | 16 +++++----- .../pacman-popup/pacman-popup.component.html | 2 +- .../pacman-popup.component.spec.ts | 32 +++++++++---------- .../pacman-popup/pacman-popup.component.ts | 7 ++-- 4 files changed, 28 insertions(+), 29 deletions(-) diff --git a/src/app/@ansyn/ansyn/modules/core/services/keys-listener.service.spec.ts b/src/app/@ansyn/ansyn/modules/core/services/keys-listener.service.spec.ts index 99f9ac1de2..85d4b8dbc6 100644 --- a/src/app/@ansyn/ansyn/modules/core/services/keys-listener.service.spec.ts +++ b/src/app/@ansyn/ansyn/modules/core/services/keys-listener.service.spec.ts @@ -3,14 +3,14 @@ import { TestBed } from '@angular/core/testing'; import { KeysListenerService } from './keys-listener.service'; describe('KeysListenerService', () => { - let service: KeysListenerService; + let service: KeysListenerService; - beforeEach(() => { - TestBed.configureTestingModule({}); - service = TestBed.inject(KeysListenerService); - }); + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(KeysListenerService); + }); - it('should be created', () => { - expect(service).toBeTruthy(); - }); + it('should be created', () => { + expect(service).toBeTruthy(); + }); }); diff --git a/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.html b/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.html index 2f7f47af75..993367a97c 100644 --- a/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.html +++ b/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.html @@ -1,2 +1,2 @@
-

Score:0

\ No newline at end of file +

Score:0

diff --git a/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.spec.ts b/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.spec.ts index 7d5aaeeaa5..167108fdd1 100644 --- a/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.spec.ts +++ b/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.spec.ts @@ -3,23 +3,23 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { PacmanPopupComponent } from './pacman-popup.component'; describe('PacmanPopupComponent', () => { - let component: PacmanPopupComponent; - let fixture: ComponentFixture; + let component: PacmanPopupComponent; + let fixture: ComponentFixture; - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [ PacmanPopupComponent ] - }) - .compileComponents(); - })); + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ PacmanPopupComponent ] + }) + .compileComponents(); + })); - beforeEach(() => { - fixture = TestBed.createComponent(PacmanPopupComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(PacmanPopupComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should create', () => { - expect(component).toBeTruthy(); - }); + it('should create', () => { + expect(component).toBeTruthy(); + }); }); diff --git a/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.ts b/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.ts index bc98187d6f..29bd4419c2 100644 --- a/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.ts +++ b/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.ts @@ -213,7 +213,6 @@ export class PacmanPopupComponent implements OnInit, OnDestroy, AfterViewInit { * @param ghost */ moveGhost(ghost) { - // please implement this. let widthX = this.width; let squaresY = this.squares; let scoreValX = this.scoreValue; @@ -301,11 +300,11 @@ export class PacmanPopupComponent implements OnInit, OnDestroy, AfterViewInit { } /** - * Once pacman consume the power pellet it gain super power + * Once pacman consume the power pellet it gains super power * All the ghost will be afraid of em. * By right the ghost should run away from pacman as much as possible - * Set an timeout for the ghost to turn back to hunting mode rather than - * scare of pacman. + * Set a timeout for the ghost to turn back to hunting mode rather than + * be scared of pacman. */ powerPelletEaten() { if (this.squares[this.pacmanCurrentIndex].classList.contains('power-pellet')) { From 081c7161c0f22a680096d6df212ba96e8e69499e Mon Sep 17 00:00:00 2001 From: Danaorlov1005 Date: Sun, 18 Apr 2021 15:53:19 +0300 Subject: [PATCH 07/21] enum --- .../core/services/keys-listener.service.ts | 1 - .../pacman-popup/pacman-popup.component.less | 6 +++--- .../pacman-popup.component.spec.ts | 19 ++++++++++++++++--- .../pacman-popup/pacman-popup.component.ts | 16 +++++++++++----- .../overlay-navigation-bar.component.spec.ts | 19 +++++++------------ 5 files changed, 37 insertions(+), 24 deletions(-) diff --git a/src/app/@ansyn/ansyn/modules/core/services/keys-listener.service.ts b/src/app/@ansyn/ansyn/modules/core/services/keys-listener.service.ts index 2cee9fbdf7..a6b9ffc5dc 100644 --- a/src/app/@ansyn/ansyn/modules/core/services/keys-listener.service.ts +++ b/src/app/@ansyn/ansyn/modules/core/services/keys-listener.service.ts @@ -10,7 +10,6 @@ export class KeysListenerService { events: string[] = ['keypress', 'keyup', 'keydown']; constructor() { - console.log("medabeg im hadpasot"); this.events.forEach(eventName => fromEvent(document, eventName).subscribe(($event: KeyboardEvent ) => { if (this.isElementNotValid($event)) { diff --git a/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.less b/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.less index 5e677eaabf..d7bc311cf2 100644 --- a/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.less +++ b/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.less @@ -55,10 +55,10 @@ } @inkyImages: 'elor.jpg', 'yuval.jpg'; -@randominkyimage: extract(@inkyImages,@random); +@randomInkyimage: extract(@inkyImages,@random); .inky { - background: url('../../../assets/important/@{randominkyimage}'); + background: url('../../../assets/important/@{randomInkyimage}'); } @clydeImages: 'adani.jpg', 'rom.jpg'; @@ -72,7 +72,7 @@ background-color: yellow; border-radius: 50%; } - + .scared-ghost { background: url('../../../assets/important/dana.JPG'); } diff --git a/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.spec.ts b/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.spec.ts index 167108fdd1..5a5098fd9c 100644 --- a/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.spec.ts +++ b/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.spec.ts @@ -1,23 +1,36 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { async, ComponentFixture, inject, TestBed } from '@angular/core/testing'; import { PacmanPopupComponent } from './pacman-popup.component'; +import { Store, StoreModule } from "@ngrx/store"; +import { IStatusBarState, statusBarFeatureKey, StatusBarReducer } from "../../status-bar/reducers/status-bar.reducer"; +import { selectActiveMapId, selectMapsList, selectOverlayOfActiveMap } from "@ansyn/map-facade"; +import { of } from "rxjs"; describe('PacmanPopupComponent', () => { let component: PacmanPopupComponent; let fixture: ComponentFixture; + let store: Store; + let statusBarState: IStatusBarState; beforeEach(async(() => { TestBed.configureTestingModule({ + imports:[ + StoreModule.forRoot({ + [statusBarFeatureKey]: StatusBarReducer + }) + ], declarations: [ PacmanPopupComponent ] }) .compileComponents(); })); - beforeEach(() => { + beforeEach(inject([Store], (_store: Store) => { + store = _store; + fixture = TestBed.createComponent(PacmanPopupComponent); component = fixture.componentInstance; fixture.detectChanges(); - }); + })); it('should create', () => { expect(component).toBeTruthy(); diff --git a/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.ts b/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.ts index 29bd4419c2..462d2bcf0d 100644 --- a/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.ts +++ b/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.ts @@ -12,6 +12,13 @@ export enum KEY_CODE { UP_ARROW = 38 } +export enum BOARD_CELLS { + PAC_DOT, + WALL, + GHOST_LAIR, + POWER_PALLET, +} + class Ghost { className: string; startIndex: number; @@ -175,13 +182,13 @@ export class PacmanPopupComponent implements OnInit, OnDestroy, AfterViewInit { this.renderer.appendChild(this.grid.nativeElement, square); this.squares.push(square) - if (this.layout[i] === 0) { + if (this.layout[i] === BOARD_CELLS.PAC_DOT) { this.renderer.addClass(this.squares[i], 'pac-dot'); - } else if (this.layout[i] === 1) { + } else if (this.layout[i] === BOARD_CELLS.WALL) { this.renderer.addClass(this.squares[i], 'wall'); - } else if (this.layout[i] === 2) { + } else if (this.layout[i] === BOARD_CELLS.GHOST_LAIR) { this.renderer.addClass(this.squares[i], 'ghost-lair'); - } else if (this.layout[i] === 3) { + } else if (this.layout[i] === BOARD_CELLS.POWER_PALLET) { this.renderer.addClass(this.squares[i], 'power-pellet'); } } @@ -312,7 +319,6 @@ export class PacmanPopupComponent implements OnInit, OnDestroy, AfterViewInit { this.score.nativeElement.innerHTML = this.scoreValue; this.ghosts.forEach(ghost => { ghost.isScared = true; - console.log("turn to scared of pacman"); // turn the ghost colour to aquamarine. this.squares[ghost.currentIndex].classList.add(ghost.className, 'ghost', 'scared-ghost'); }); diff --git a/src/app/@ansyn/ansyn/modules/overlays/components/overlay-navigation-bar/overlay-navigation-bar.component.spec.ts b/src/app/@ansyn/ansyn/modules/overlays/components/overlay-navigation-bar/overlay-navigation-bar.component.spec.ts index cf2c64f8cd..ee588dd2a8 100644 --- a/src/app/@ansyn/ansyn/modules/overlays/components/overlay-navigation-bar/overlay-navigation-bar.component.spec.ts +++ b/src/app/@ansyn/ansyn/modules/overlays/components/overlay-navigation-bar/overlay-navigation-bar.component.spec.ts @@ -21,11 +21,13 @@ import { OverlayStatusReducer, } from '../../overlay-status/reducers/overlay-status.reducer'; import { of } from 'rxjs'; +import { KeysListenerService } from "../../../core/services/keys-listener.service"; describe('OverlyaNavigationBarComponent', () => { let component: OverlayNavigationBarComponent; let fixture: ComponentFixture; let store: Store; + let keyListenerService: KeysListenerService; beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ @@ -37,6 +39,7 @@ describe('OverlyaNavigationBarComponent', () => { }), TranslateModule.forRoot()], providers: [ { + KeysListenerService, provide: StatusBarConfig, useValue: { toolTips: {} } } @@ -92,20 +95,12 @@ describe('OverlyaNavigationBarComponent', () => { it(`onkeyup should call ${ key.n } when key = "${ key.k }"`, () => { spyOn(component, <'clickGoAdjacent'>key.f); expect(component[key.n]).toEqual(false); - const $event = { - key: key.k, - currentTarget: { - document: { - activeElement: { - className: [] - } - } - } - }; - component.onkeydown($event); + + spyOn(keyListenerService, 'keydown'); + component.onKeyDown$(); expect(component[key.n]).toEqual(true); - component.onkeyup($event); + component.onKeyUp$(); expect(component[key.n]).toEqual(false); expect(component[key.f]).toHaveBeenCalled(); }); From 312c467f1b6723912e55a4782181c22aebbf1e7e Mon Sep 17 00:00:00 2001 From: Danaorlov1005 Date: Mon, 26 Apr 2021 13:23:14 +0300 Subject: [PATCH 08/21] refactor from pr --- .../core/click-outside/click-outside.service.ts | 2 +- .../overlay-navigation-bar.component.spec.ts | 4 +++- .../overlay-navigation-bar.component.ts | 4 +--- .../components/tools/tools/tools.component.ts | 13 +++++-------- 4 files changed, 10 insertions(+), 13 deletions(-) diff --git a/src/app/@ansyn/ansyn/modules/core/click-outside/click-outside.service.ts b/src/app/@ansyn/ansyn/modules/core/click-outside/click-outside.service.ts index 200e16ab59..0ab48dede3 100644 --- a/src/app/@ansyn/ansyn/modules/core/click-outside/click-outside.service.ts +++ b/src/app/@ansyn/ansyn/modules/core/click-outside/click-outside.service.ts @@ -23,7 +23,7 @@ export class ClickOutsideService { ) } - // for chrome44 - AD MATAY + // for chrome44 private getPath(event) { const currentElement = event.target; const eventTarget = [currentElement]; diff --git a/src/app/@ansyn/ansyn/modules/overlays/components/overlay-navigation-bar/overlay-navigation-bar.component.spec.ts b/src/app/@ansyn/ansyn/modules/overlays/components/overlay-navigation-bar/overlay-navigation-bar.component.spec.ts index ee588dd2a8..ead2c21329 100644 --- a/src/app/@ansyn/ansyn/modules/overlays/components/overlay-navigation-bar/overlay-navigation-bar.component.spec.ts +++ b/src/app/@ansyn/ansyn/modules/overlays/components/overlay-navigation-bar/overlay-navigation-bar.component.spec.ts @@ -51,6 +51,7 @@ describe('OverlyaNavigationBarComponent', () => { beforeEach(() => { fixture = TestBed.createComponent(OverlayNavigationBarComponent); component = fixture.componentInstance; + keyListenerService = new KeysListenerService(); fixture.detectChanges(); }); @@ -96,7 +97,8 @@ describe('OverlyaNavigationBarComponent', () => { spyOn(component, <'clickGoAdjacent'>key.f); expect(component[key.n]).toEqual(false); - spyOn(keyListenerService, 'keydown'); + // spyOn(keyListenerService, 'keydown'); + keyListenerService.keydown.emit(new KeyboardEvent('keydown')); component.onKeyDown$(); expect(component[key.n]).toEqual(true); diff --git a/src/app/@ansyn/ansyn/modules/overlays/components/overlay-navigation-bar/overlay-navigation-bar.component.ts b/src/app/@ansyn/ansyn/modules/overlays/components/overlay-navigation-bar/overlay-navigation-bar.component.ts index 5e1432cf31..0e71df8d3e 100644 --- a/src/app/@ansyn/ansyn/modules/overlays/components/overlay-navigation-bar/overlay-navigation-bar.component.ts +++ b/src/app/@ansyn/ansyn/modules/overlays/components/overlay-navigation-bar/overlay-navigation-bar.component.ts @@ -64,9 +64,7 @@ export class OverlayNavigationBarComponent implements OnInit, OnDestroy { @AutoSubscription onKeyDown$ = () => this.keyListenerService.keydown.pipe( - withLatestFrom(this.store.select(selectPacmanMode)), - filter(([$event, isPacmanMode]: [KeyboardEvent, boolean]) => !isPacmanMode), - tap(([$event, isPacmanMode]: [KeyboardEvent, boolean]) => { + tap(($event: KeyboardEvent) => { if (this.keyListenerService.keyWasUsed($event, 'ArrowRight', 39)) { this.goNextActive = true; } else if (this.keyListenerService.keyWasUsed($event, 'ArrowLeft', 37)) { diff --git a/src/app/@ansyn/ansyn/modules/status-bar/components/tools/tools/tools.component.ts b/src/app/@ansyn/ansyn/modules/status-bar/components/tools/tools/tools.component.ts index bb953611ca..85f7f52daf 100644 --- a/src/app/@ansyn/ansyn/modules/status-bar/components/tools/tools/tools.component.ts +++ b/src/app/@ansyn/ansyn/modules/status-bar/components/tools/tools/tools.component.ts @@ -9,7 +9,7 @@ import { import { Store } from '@ngrx/store'; import { Observable } from 'rxjs'; import { selectSubMenu, selectToolFlags } from '../reducers/tools.reducer'; -import { map, take, tap } from 'rxjs/operators'; +import { filter, map, take, tap } from 'rxjs/operators'; import { AutoSubscription, AutoSubscriptions } from 'auto-subscriptions'; import { MatDialog } from '@angular/material/dialog'; import { ExportMapsPopupComponent } from '../export-maps-popup/export-maps-popup.component'; @@ -95,10 +95,9 @@ export class ToolsComponent implements OnInit, OnDestroy { @AutoSubscription onKeyUp$ = () => this.keyListenerService.keyup.pipe( + filter(($event: KeyboardEvent) => this.keyListenerService.keysWereUsed($event, this._pacmanKeys) && !this.isDialogShowing), tap($event => { - if (this.keyListenerService.keysWereUsed($event, this._pacmanKeys)) { this.togglePacmanDialog(); - } }) ); @@ -153,11 +152,9 @@ export class ToolsComponent implements OnInit, OnDestroy { } togglePacmanDialog() { - if (!this.isDialogShowing) { - const dialogRef = this.dialog.open(PacmanPopupComponent, {panelClass: 'custom-dialog'}); - dialogRef.afterClosed().pipe(take(1), tap(() => this.isDialogShowing = false)).subscribe(); - this.isDialogShowing = !this.isDialogShowing; - } + const dialogRef = this.dialog.open(PacmanPopupComponent, {panelClass: 'custom-dialog'}); + dialogRef.afterClosed().pipe(take(1), tap(() => this.isDialogShowing = false)).subscribe(); + this.isDialogShowing = !this.isDialogShowing; } } From e33fb6a5e1813371aac14007243a8ef94a362a1b Mon Sep 17 00:00:00 2001 From: Danaorlov1005 Date: Mon, 26 Apr 2021 14:30:46 +0300 Subject: [PATCH 09/21] added filter for overlay bering open --- .../components/tools/tools/tools.component.ts | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/app/@ansyn/ansyn/modules/status-bar/components/tools/tools/tools.component.ts b/src/app/@ansyn/ansyn/modules/status-bar/components/tools/tools/tools.component.ts index 85f7f52daf..5d76c6dc0a 100644 --- a/src/app/@ansyn/ansyn/modules/status-bar/components/tools/tools/tools.component.ts +++ b/src/app/@ansyn/ansyn/modules/status-bar/components/tools/tools/tools.component.ts @@ -6,10 +6,10 @@ import { StopMouseShadow, UpdateMeasureDataOptionsAction, UpdateToolsFlags } from '../actions/tools.actions'; -import { Store } from '@ngrx/store'; +import { select, Store } from '@ngrx/store'; import { Observable } from 'rxjs'; import { selectSubMenu, selectToolFlags } from '../reducers/tools.reducer'; -import { filter, map, take, tap } from 'rxjs/operators'; +import { filter, map, take, tap, withLatestFrom } from 'rxjs/operators'; import { AutoSubscription, AutoSubscriptions } from 'auto-subscriptions'; import { MatDialog } from '@angular/material/dialog'; import { ExportMapsPopupComponent } from '../export-maps-popup/export-maps-popup.component'; @@ -18,7 +18,8 @@ import { selectActiveAnnotationLayer } from '../../../../menu-items/layers-manag import { ComponentVisibilityService } from '../../../../../app-providers/component-visibility.service'; import { ComponentVisibilityItems } from '../../../../../app-providers/component-mode'; import { PacmanPopupComponent } from '../../../../easter-eggs/pacman-popup/pacman-popup.component'; -import { KeysListenerService } from "../../../../core/services/keys-listener.service"; +import { KeysListenerService } from '../../../../core/services/keys-listener.service'; +import { selectOverlaysWithMapIds } from '@ansyn/map-facade'; @Component({ selector: 'ansyn-tools', @@ -95,9 +96,14 @@ export class ToolsComponent implements OnInit, OnDestroy { @AutoSubscription onKeyUp$ = () => this.keyListenerService.keyup.pipe( - filter(($event: KeyboardEvent) => this.keyListenerService.keysWereUsed($event, this._pacmanKeys) && !this.isDialogShowing), - tap($event => { - this.togglePacmanDialog(); + withLatestFrom(this.store$.select(selectOverlaysWithMapIds)), + filter(([$event, overlayWithMapIds]: [KeyboardEvent, { overlay: any, mapId: string, isActive: boolean }[]]) => + this.keyListenerService.keysWereUsed($event, this._pacmanKeys) && + // open pacman only when there are no overlays displayed and no dialog + !this.isDialogShowing && + !overlayWithMapIds.some(overlayAndMapId => Boolean(overlayAndMapId.overlay))), + tap($event => { + this.togglePacmanDialog (); }) ); From 426fcc9ccbe4667e5cb80a7d6d6e4ab2861e7636 Mon Sep 17 00:00:00 2001 From: Danaorlov1005 Date: Mon, 26 Apr 2021 14:39:36 +0300 Subject: [PATCH 10/21] fixed pacman check --- .../easter-eggs/pacman-popup/pacman-popup.component.ts | 9 +++++---- .../overlay-navigation-bar.component.ts | 5 +---- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.ts b/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.ts index 462d2bcf0d..66151a4b36 100644 --- a/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.ts +++ b/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.ts @@ -181,15 +181,16 @@ export class PacmanPopupComponent implements OnInit, OnDestroy, AfterViewInit { const square = this.renderer.createElement('div'); this.renderer.appendChild(this.grid.nativeElement, square); this.squares.push(square) + let currentSquare = this.squares[i]; if (this.layout[i] === BOARD_CELLS.PAC_DOT) { - this.renderer.addClass(this.squares[i], 'pac-dot'); + this.renderer.addClass(currentSquare, 'pac-dot'); } else if (this.layout[i] === BOARD_CELLS.WALL) { - this.renderer.addClass(this.squares[i], 'wall'); + this.renderer.addClass(currentSquare, 'wall'); } else if (this.layout[i] === BOARD_CELLS.GHOST_LAIR) { - this.renderer.addClass(this.squares[i], 'ghost-lair'); + this.renderer.addClass(currentSquare, 'ghost-lair'); } else if (this.layout[i] === BOARD_CELLS.POWER_PALLET) { - this.renderer.addClass(this.squares[i], 'power-pellet'); + this.renderer.addClass(currentSquare, 'power-pellet'); } } } diff --git a/src/app/@ansyn/ansyn/modules/overlays/components/overlay-navigation-bar/overlay-navigation-bar.component.ts b/src/app/@ansyn/ansyn/modules/overlays/components/overlay-navigation-bar/overlay-navigation-bar.component.ts index 0e71df8d3e..e8d3715bf5 100644 --- a/src/app/@ansyn/ansyn/modules/overlays/components/overlay-navigation-bar/overlay-navigation-bar.component.ts +++ b/src/app/@ansyn/ansyn/modules/overlays/components/overlay-navigation-bar/overlay-navigation-bar.component.ts @@ -2,7 +2,6 @@ import { Component, Inject, OnDestroy, OnInit } from '@angular/core'; import { Store } from '@ngrx/store'; import { IStatusBarState, - selectPacmanMode } from '../../../status-bar/reducers/status-bar.reducer'; import { ExpandAction, GoAdjacentOverlay } from '../../../status-bar/actions/status-bar.actions'; import { IStatusBarConfig } from '../../../status-bar/models/statusBar-config.model'; @@ -92,9 +91,7 @@ export class OverlayNavigationBarComponent implements OnInit, OnDestroy { @AutoSubscription onKeyUp$ = () => this.keyListenerService.keyup.pipe( - withLatestFrom(this.store.select(selectPacmanMode)), - filter(([$event, isPacmanMode]: [KeyboardEvent, boolean]) => !isPacmanMode), - tap(([$event, isPacmanMode]: [KeyboardEvent, boolean]) => { + tap(($event: KeyboardEvent) => { if (this.keyListenerService.isElementNotValid($event)) { return; } From 599eda788cf811b8a154ae62bfd6df1136256f9e Mon Sep 17 00:00:00 2001 From: Danaorlov1005 Date: Wed, 28 Apr 2021 16:01:06 +0300 Subject: [PATCH 11/21] test try --- .../overlay-navigation-bar.component.spec.ts | 37 ++++++++++++++----- .../overlay-navigation-bar.component.ts | 2 +- 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/src/app/@ansyn/ansyn/modules/overlays/components/overlay-navigation-bar/overlay-navigation-bar.component.spec.ts b/src/app/@ansyn/ansyn/modules/overlays/components/overlay-navigation-bar/overlay-navigation-bar.component.spec.ts index ead2c21329..e6cf1f12d2 100644 --- a/src/app/@ansyn/ansyn/modules/overlays/components/overlay-navigation-bar/overlay-navigation-bar.component.spec.ts +++ b/src/app/@ansyn/ansyn/modules/overlays/components/overlay-navigation-bar/overlay-navigation-bar.component.spec.ts @@ -22,8 +22,9 @@ import { } from '../../overlay-status/reducers/overlay-status.reducer'; import { of } from 'rxjs'; import { KeysListenerService } from "../../../core/services/keys-listener.service"; +import { EventEmitter } from "@angular/core"; -describe('OverlyaNavigationBarComponent', () => { +describe('OverlayNavigationBarComponent', () => { let component: OverlayNavigationBarComponent; let fixture: ComponentFixture; let store: Store; @@ -96,15 +97,33 @@ describe('OverlyaNavigationBarComponent', () => { it(`onkeyup should call ${ key.n } when key = "${ key.k }"`, () => { spyOn(component, <'clickGoAdjacent'>key.f); expect(component[key.n]).toEqual(false); + const $event = { + key: key.k, + currentTarget: { + document: { + activeElement: { + className: [] + } + } + } + }; - // spyOn(keyListenerService, 'keydown'); - keyListenerService.keydown.emit(new KeyboardEvent('keydown')); - component.onKeyDown$(); - expect(component[key.n]).toEqual(true); + // spyOn(keyListenerService, 'keydown').and.returnValue(of($event)); + // spyOn(keyListenerService, 'keyup').and.returnValue(of($event)); - component.onKeyUp$(); - expect(component[key.n]).toEqual(false); - expect(component[key.f]).toHaveBeenCalled(); - }); + component.onKeyDown$().subscribe(() => { + expect(component[key.n]).toEqual(false); + }); + component.onKeyUp$().subscribe(() => { + expect(component[key.n]).toEqual(false); + expect(component[key.f]).toHaveBeenCalled(); + }); + spyOn(keyListenerService.keydown, 'emit'); + spyOn(keyListenerService.keyup, 'emit'); + + // keyListenerService.keydown.emit(); + // + // keyListenerService.keyup.next(new KeyboardEvent('keyup')); + }); }); }); diff --git a/src/app/@ansyn/ansyn/modules/overlays/components/overlay-navigation-bar/overlay-navigation-bar.component.ts b/src/app/@ansyn/ansyn/modules/overlays/components/overlay-navigation-bar/overlay-navigation-bar.component.ts index e8d3715bf5..883bbdf2a3 100644 --- a/src/app/@ansyn/ansyn/modules/overlays/components/overlay-navigation-bar/overlay-navigation-bar.component.ts +++ b/src/app/@ansyn/ansyn/modules/overlays/components/overlay-navigation-bar/overlay-navigation-bar.component.ts @@ -9,7 +9,7 @@ import { StatusBarConfig } from '../../../status-bar/models/statusBar.config'; import { EnableCopyOriginalOverlayDataAction, selectOverlayOfActiveMap } from '@ansyn/map-facade'; import { ActivateScannedAreaAction } from '../../overlay-status/actions/overlay-status.actions'; import { AutoSubscription, AutoSubscriptions } from 'auto-subscriptions'; -import { tap, filter, withLatestFrom } from 'rxjs/operators'; +import { tap, filter } from 'rxjs/operators'; import { selectDropsAscending, selectFilteredOverlays } from '../../reducers/overlays.reducer'; import { combineLatest } from 'rxjs'; import { IOverlay, IOverlayDrop } from '../../models/overlay.model'; From 715d79562cd84662f13ff7efd87f88a850112198 Mon Sep 17 00:00:00 2001 From: Danaorlov1005 Date: Thu, 29 Apr 2021 00:23:37 +0300 Subject: [PATCH 12/21] fixed test to be like before --- .../pacman-popup.component.spec.ts | 2 +- .../pacman-popup/pacman-popup.component.ts | 4 +- .../overlay-navigation-bar.component.spec.ts | 30 +++++--- .../overlay-navigation-bar.component.ts | 75 +++++++++---------- 4 files changed, 59 insertions(+), 52 deletions(-) diff --git a/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.spec.ts b/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.spec.ts index 5a5098fd9c..0a47019f43 100644 --- a/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.spec.ts +++ b/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.spec.ts @@ -14,7 +14,7 @@ describe('PacmanPopupComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - imports:[ + imports: [ StoreModule.forRoot({ [statusBarFeatureKey]: StatusBarReducer }) diff --git a/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.ts b/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.ts index 66151a4b36..afe3651787 100644 --- a/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.ts +++ b/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.ts @@ -168,7 +168,7 @@ export class PacmanPopupComponent implements OnInit, OnDestroy, AfterViewInit { this.pacDotEaten(); this.powerPelletEaten(); this.checkForGameOver(this.squares, this.pacmanCurrentIndex); - this.checkforWin(); + this.checkForWin(); })); @@ -274,7 +274,7 @@ export class PacmanPopupComponent implements OnInit, OnDestroy, AfterViewInit { * Check whether has pacman consume all the pellet from the grid * if yes then display the winning message */ - checkforWin() { + checkForWin() { if (this.scoreValue === 274) { this.ghosts.forEach(ghost => clearInterval(ghost.timerId)); this.isPacmanAlive = false; diff --git a/src/app/@ansyn/ansyn/modules/overlays/components/overlay-navigation-bar/overlay-navigation-bar.component.spec.ts b/src/app/@ansyn/ansyn/modules/overlays/components/overlay-navigation-bar/overlay-navigation-bar.component.spec.ts index e6cf1f12d2..39687ca6e4 100644 --- a/src/app/@ansyn/ansyn/modules/overlays/components/overlay-navigation-bar/overlay-navigation-bar.component.spec.ts +++ b/src/app/@ansyn/ansyn/modules/overlays/components/overlay-navigation-bar/overlay-navigation-bar.component.spec.ts @@ -108,22 +108,30 @@ describe('OverlayNavigationBarComponent', () => { } }; + component.onKeyDownEventCheck(new KeyboardEvent('keydown', {'key': key.k})); + expect(component[key.n]).toEqual(true); + + component.onKeyUpEventCheck(new KeyboardEvent('keyup', {'key': key.k})) + expect(component[key.n]).toEqual(false); + expect(component[key.f]).toHaveBeenCalled(); + }); + // spyOn(keyListenerService, 'keydown').and.returnValue(of($event)); // spyOn(keyListenerService, 'keyup').and.returnValue(of($event)); - component.onKeyDown$().subscribe(() => { - expect(component[key.n]).toEqual(false); - }); - component.onKeyUp$().subscribe(() => { - expect(component[key.n]).toEqual(false); - expect(component[key.f]).toHaveBeenCalled(); - }); - spyOn(keyListenerService.keydown, 'emit'); - spyOn(keyListenerService.keyup, 'emit'); - + // component.onKeyDown$().subscribe(() => { + // expect(component[key.n]).toEqual(false); + // }); + // component.onKeyUp$().subscribe(() => { + // expect(component[key.n]).toEqual(false); + // expect(component[key.f]).toHaveBeenCalled(); + // }); + // spyOn(keyListenerService.keydown, 'emit'); + // spyOn(keyListenerService.keyup, 'emit'); + // fixture.nativeElement.dispatchEvent(new KeyboardEvent('keydown', {'key': key.k})) // keyListenerService.keydown.emit(); // // keyListenerService.keyup.next(new KeyboardEvent('keyup')); }); }); -}); +// }); diff --git a/src/app/@ansyn/ansyn/modules/overlays/components/overlay-navigation-bar/overlay-navigation-bar.component.ts b/src/app/@ansyn/ansyn/modules/overlays/components/overlay-navigation-bar/overlay-navigation-bar.component.ts index 883bbdf2a3..00a77b926d 100644 --- a/src/app/@ansyn/ansyn/modules/overlays/components/overlay-navigation-bar/overlay-navigation-bar.component.ts +++ b/src/app/@ansyn/ansyn/modules/overlays/components/overlay-navigation-bar/overlay-navigation-bar.component.ts @@ -64,57 +64,56 @@ export class OverlayNavigationBarComponent implements OnInit, OnDestroy { @AutoSubscription onKeyDown$ = () => this.keyListenerService.keydown.pipe( tap(($event: KeyboardEvent) => { - if (this.keyListenerService.keyWasUsed($event, 'ArrowRight', 39)) { - this.goNextActive = true; - } else if (this.keyListenerService.keyWasUsed($event, 'ArrowLeft', 37)) { - this.goPrevActive = true; - } + this.onKeyDownEventCheck($event); + }) + ); - if (this.keyListenerService.keysWereUsed($event, this._overlayHackKeys)) { - this.store.dispatch(new EnableCopyOriginalOverlayDataAction(true)); - } + onKeyDownEventCheck($event: KeyboardEvent) { + if (this.keyListenerService.keyWasUsed($event, 'ArrowRight', 39)) { + this.goNextActive = true; + } else if (this.keyListenerService.keyWasUsed($event, 'ArrowLeft', 37)) { + this.goPrevActive = true; + } + + if (this.keyListenerService.keysWereUsed($event, this._overlayHackKeys)) { + this.store.dispatch(new EnableCopyOriginalOverlayDataAction(true)); + } + } + + @AutoSubscription + onKeyUp$ = () => this.keyListenerService.keyup.pipe( + tap(($event: KeyboardEvent) => { + this.onKeyUpEventCheck($event); }) ); + onKeyUpEventCheck($event: KeyboardEvent) { + if (this.keyListenerService.keyWasUsed($event, 'ArrowRight', 39)) { + this.clickGoAdjacent(true); + this.goNextActive = false; + } else if (this.keyListenerService.keyWasUsed($event, 'ArrowLeft', 37)) { + this.clickGoAdjacent(false); + this.goPrevActive = false; + } + + if (this.keyListenerService.keysWereUsed($event, this._overlayHackKeys)) { + this.store.dispatch(new EnableCopyOriginalOverlayDataAction(false)); + } + + if (this.keyListenerService.keysWereUsed($event, this._toggleDirectionKeys)) { + const direction = this.translateService.instant('direction'); + this.translateService.set('direction', direction === 'rtl' ? 'ltr' : 'rtl', 'default'); + } + } @AutoSubscription onkeypress$ = () => this.keyListenerService.keyup.pipe( tap($event => { - if (this.keyListenerService.isElementNotValid($event)) { - return; - } - if (this.keyListenerService.keysWereUsed($event, this._scannedAreaKeys)) { this.clickScannedArea(); } } )); - @AutoSubscription - onKeyUp$ = () => this.keyListenerService.keyup.pipe( - tap(($event: KeyboardEvent) => { - if (this.keyListenerService.isElementNotValid($event)) { - return; - } - - if (this.keyListenerService.keyWasUsed($event, 'ArrowRight', 39)) { - this.clickGoAdjacent(true); - this.goNextActive = false; - } else if (this.keyListenerService.keyWasUsed($event, 'ArrowLeft', 37)) { - this.clickGoAdjacent(false); - this.goPrevActive = false; - } - - if (this.keyListenerService.keysWereUsed($event, this._overlayHackKeys)) { - this.store.dispatch(new EnableCopyOriginalOverlayDataAction(false)); - } - - if (this.keyListenerService.keysWereUsed($event, this._toggleDirectionKeys)) { - const direction = this.translateService.instant('direction'); - this.translateService.set('direction', direction === 'rtl' ? 'ltr' : 'rtl', 'default'); - } - }) - ); - clickGoAdjacent(isNext): void { this.store.dispatch(new GoAdjacentOverlay({isNext})); } From bbdf9cae58086262d62e877b14b919cfc60b8e23 Mon Sep 17 00:00:00 2001 From: Danaorlov1005 Date: Thu, 29 Apr 2021 00:43:07 +0300 Subject: [PATCH 13/21] picture path --- .../pacman-popup/pacman-popup.component.less | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.less b/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.less index d7bc311cf2..7c5cff3e01 100644 --- a/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.less +++ b/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.less @@ -39,33 +39,34 @@ @length: 2; @random: `Math.ceil(Math.random() * (@{length}))`; +@contentRoot: 'src/app/@ansyn/ansyn/assets/important'; @blinkyImages: 'yehonatan.jpg', 'tzahi.jpg'; @randomBlinkyimage: extract(@blinkyImages,@random); .blinky { - background: url('../../../assets/important/@{randomBlinkyimage}'); + background: url('@{contentRoot}/@{randomBlinkyimage}'); } @pinkyImages: 'aviv.jpg', 'pini.jpg'; @randomPinkyimage: extract(@pinkyImages,@random); .pinky { - background: url('../../../assets/important/@{randomPinkyimage}'); + background: url('@{contentRoot}/@{randomPinkyimage}'); } @inkyImages: 'elor.jpg', 'yuval.jpg'; @randomInkyimage: extract(@inkyImages,@random); .inky { - background: url('../../../assets/important/@{randomInkyimage}'); + background: url('@{contentRoot}/@{randomInkyimage}'); } @clydeImages: 'adani.jpg', 'rom.jpg'; @randomClydeimage: extract(@clydeImages,@random); .clyde { - background: url('../../../assets/important/@{randomClydeimage}'); + background: url('@{contentRoot}/@{randomClydeimage}'); } .pac-man { @@ -74,5 +75,5 @@ } .scared-ghost { - background: url('../../../assets/important/dana.JPG'); + background: url('@{contentRoot}/dana.JPG'); } From 8764d37be91489809b499cc99b6f4d467757ecce Mon Sep 17 00:00:00 2001 From: Danaorlov1005 Date: Thu, 29 Apr 2021 01:06:50 +0300 Subject: [PATCH 14/21] picture path --- .../easter-eggs/pacman-popup/pacman-popup.component.less | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.less b/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.less index 7c5cff3e01..82e1a4cf48 100644 --- a/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.less +++ b/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.less @@ -39,20 +39,20 @@ @length: 2; @random: `Math.ceil(Math.random() * (@{length}))`; -@contentRoot: 'src/app/@ansyn/ansyn/assets/important'; +@contentRoot: 'src/app/@ansyn/ansyn/assets/important/'; @blinkyImages: 'yehonatan.jpg', 'tzahi.jpg'; @randomBlinkyimage: extract(@blinkyImages,@random); .blinky { - background: url('@{contentRoot}/@{randomBlinkyimage}'); + background: url('src/app/@ansyn/ansyn/assets/important/@{randomBlinkyimage}'); } @pinkyImages: 'aviv.jpg', 'pini.jpg'; @randomPinkyimage: extract(@pinkyImages,@random); .pinky { - background: url('@{contentRoot}/@{randomPinkyimage}'); + background: url(@contentRoot}'/'@{randomPinkyimage}); } @inkyImages: 'elor.jpg', 'yuval.jpg'; From 4212da68d338c93cfe6dc169983770e2525e362a Mon Sep 17 00:00:00 2001 From: Danaorlov1005 Date: Thu, 29 Apr 2021 01:14:16 +0300 Subject: [PATCH 15/21] picture path --- .../easter-eggs/pacman-popup/pacman-popup.component.less | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.less b/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.less index 82e1a4cf48..02a9876df3 100644 --- a/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.less +++ b/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.less @@ -45,14 +45,14 @@ @randomBlinkyimage: extract(@blinkyImages,@random); .blinky { - background: url('src/app/@ansyn/ansyn/assets/important/@{randomBlinkyimage}'); + background: url('@{contentRoot}/@{randomBlinkyimage}'); } @pinkyImages: 'aviv.jpg', 'pini.jpg'; @randomPinkyimage: extract(@pinkyImages,@random); .pinky { - background: url(@contentRoot}'/'@{randomPinkyimage}); + background: url('@{contentRoot}/@{randomPinkyimage}'); } @inkyImages: 'elor.jpg', 'yuval.jpg'; From ece8d272e171f64109928baaa914e4e956ccb640 Mon Sep 17 00:00:00 2001 From: Danaorlov1005 Date: Thu, 29 Apr 2021 01:29:46 +0300 Subject: [PATCH 16/21] path --- .../easter-eggs/pacman-popup/pacman-popup.component.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.less b/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.less index 02a9876df3..7c5cff3e01 100644 --- a/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.less +++ b/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.less @@ -39,7 +39,7 @@ @length: 2; @random: `Math.ceil(Math.random() * (@{length}))`; -@contentRoot: 'src/app/@ansyn/ansyn/assets/important/'; +@contentRoot: 'src/app/@ansyn/ansyn/assets/important'; @blinkyImages: 'yehonatan.jpg', 'tzahi.jpg'; @randomBlinkyimage: extract(@blinkyImages,@random); From 216bd9d0deff7e640cb6d80249f7cd8b219e741b Mon Sep 17 00:00:00 2001 From: Danaorlov1005 Date: Thu, 29 Apr 2021 01:52:56 +0300 Subject: [PATCH 17/21] relative path --- .../easter-eggs/pacman-popup/pacman-popup.component.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.less b/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.less index 7c5cff3e01..7453536048 100644 --- a/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.less +++ b/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.less @@ -39,7 +39,7 @@ @length: 2; @random: `Math.ceil(Math.random() * (@{length}))`; -@contentRoot: 'src/app/@ansyn/ansyn/assets/important'; +@contentRoot: '/assets/important'; @blinkyImages: 'yehonatan.jpg', 'tzahi.jpg'; @randomBlinkyimage: extract(@blinkyImages,@random); From afb61ead9c09d8630042038653e143ae8f062ed7 Mon Sep 17 00:00:00 2001 From: Danaorlov1005 Date: Thu, 29 Apr 2021 12:53:45 +0300 Subject: [PATCH 18/21] comment --- .../overlay-navigation-bar.component.spec.ts | 21 ++----------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/src/app/@ansyn/ansyn/modules/overlays/components/overlay-navigation-bar/overlay-navigation-bar.component.spec.ts b/src/app/@ansyn/ansyn/modules/overlays/components/overlay-navigation-bar/overlay-navigation-bar.component.spec.ts index 39687ca6e4..c14f30eff3 100644 --- a/src/app/@ansyn/ansyn/modules/overlays/components/overlay-navigation-bar/overlay-navigation-bar.component.spec.ts +++ b/src/app/@ansyn/ansyn/modules/overlays/components/overlay-navigation-bar/overlay-navigation-bar.component.spec.ts @@ -115,23 +115,6 @@ describe('OverlayNavigationBarComponent', () => { expect(component[key.n]).toEqual(false); expect(component[key.f]).toHaveBeenCalled(); }); - - // spyOn(keyListenerService, 'keydown').and.returnValue(of($event)); - // spyOn(keyListenerService, 'keyup').and.returnValue(of($event)); - - // component.onKeyDown$().subscribe(() => { - // expect(component[key.n]).toEqual(false); - // }); - // component.onKeyUp$().subscribe(() => { - // expect(component[key.n]).toEqual(false); - // expect(component[key.f]).toHaveBeenCalled(); - // }); - // spyOn(keyListenerService.keydown, 'emit'); - // spyOn(keyListenerService.keyup, 'emit'); - // fixture.nativeElement.dispatchEvent(new KeyboardEvent('keydown', {'key': key.k})) - // keyListenerService.keydown.emit(); - // - // keyListenerService.keyup.next(new KeyboardEvent('keyup')); - }); }); -// }); +}); + From 13c402f2a4e11b12e275bae717e9f5f0d7b06298 Mon Sep 17 00:00:00 2001 From: Danaorlov1005 Date: Thu, 29 Apr 2021 12:58:59 +0300 Subject: [PATCH 19/21] cleaned code --- .../easter-eggs/pacman-popup/pacman-popup.component.ts | 3 --- .../modules/status-bar/actions/status-bar.actions.ts | 9 --------- .../modules/status-bar/reducers/status-bar.reducer.ts | 7 ------- 3 files changed, 19 deletions(-) diff --git a/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.ts b/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.ts index afe3651787..62298fcd06 100644 --- a/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.ts +++ b/src/app/@ansyn/ansyn/modules/easter-eggs/pacman-popup/pacman-popup.component.ts @@ -2,7 +2,6 @@ import { Component, OnInit, ViewChild, ElementRef, Renderer2, OnDestroy, AfterVi import { KeysListenerService } from "../../core/services/keys-listener.service"; import { AutoSubscription, AutoSubscriptions } from "auto-subscriptions"; import { filter, tap } from "rxjs/operators"; -import { PacnManModeAction } from "../../status-bar/actions/status-bar.actions"; import { Store } from "@ngrx/store"; export enum KEY_CODE { @@ -196,11 +195,9 @@ export class PacmanPopupComponent implements OnInit, OnDestroy, AfterViewInit { } ngOnInit(): void { - this.store$.dispatch(new PacnManModeAction(true)); } ngOnDestroy(): void { - this.store$.dispatch(new PacnManModeAction(false)); } // init all the ghosts from the array diff --git a/src/app/@ansyn/ansyn/modules/status-bar/actions/status-bar.actions.ts b/src/app/@ansyn/ansyn/modules/status-bar/actions/status-bar.actions.ts index e3d1a3effe..e10b347515 100644 --- a/src/app/@ansyn/ansyn/modules/status-bar/actions/status-bar.actions.ts +++ b/src/app/@ansyn/ansyn/modules/status-bar/actions/status-bar.actions.ts @@ -16,7 +16,6 @@ export const StatusBarActionsTypes = { OPENED_FROM_OUTSIDE: 'OPENED_FROM_OUTSIDE', SEARCH_ACTION: 'SEARCH_ACTION', MARK_SECOND_SEARCH: 'MARK_SECOND_SEARCH', - PACMAN_MODE: 'PACMAN_MODE' }; export class CopySnapshotShareLinkAction implements Action, ILogMessage { @@ -66,14 +65,6 @@ export class MarkSecondSearchSensorsAction implements Action { } } - -export class PacnManModeAction implements Action { - type: string = StatusBarActionsTypes.PACMAN_MODE; - - constructor(public payload: boolean) { - } -} - export class ExpandAction implements Action { type: string = StatusBarActionsTypes.EXPAND; diff --git a/src/app/@ansyn/ansyn/modules/status-bar/reducers/status-bar.reducer.ts b/src/app/@ansyn/ansyn/modules/status-bar/reducers/status-bar.reducer.ts index 5f8221222a..28ae4c86ae 100644 --- a/src/app/@ansyn/ansyn/modules/status-bar/reducers/status-bar.reducer.ts +++ b/src/app/@ansyn/ansyn/modules/status-bar/reducers/status-bar.reducer.ts @@ -14,7 +14,6 @@ export interface IStatusBarState { IsSimpleSearchOpen?: boolean; IsOpenedFromOutside?: boolean; markSecondSearchSensors?: boolean; - isPacmanMode?: boolean; } export const StatusBarInitialState: IStatusBarState = { @@ -27,7 +26,6 @@ export const StatusBarInitialState: IStatusBarState = { IsSimpleSearchOpen: false, IsOpenedFromOutside: false, markSecondSearchSensors: false, - isPacmanMode: false }; export const statusBarFeatureKey = 'statusBar'; @@ -64,10 +62,6 @@ export function StatusBarReducer(state = StatusBarInitialState, action: StatusBa const { payload } = action; return { ...state, markSecondSearchSensors: payload} } - case StatusBarActionsTypes.PACMAN_MODE: { - const { payload } = action; - return { ...state, isPacmanMode: payload} - } default: return state; @@ -80,7 +74,6 @@ export const selectCalenderStatus = createSelector(statusBarStateSelector, (stat export const selectAdvancedSearchStatus = createSelector(statusBarStateSelector, (statusBar: IStatusBarState) => statusBar ? statusBar.isAdvancedSearchOpen : StatusBarInitialState.isAdvancedSearchOpen); export const selectSimpledSearchStatus = createSelector(statusBarStateSelector, (statusBar: IStatusBarState) => statusBar ? statusBar.IsSimpleSearchOpen : StatusBarInitialState.IsSimpleSearchOpen); export const selectIsOpenedFromOutside = createSelector(statusBarStateSelector, (statusBar: IStatusBarState) => statusBar ? statusBar.IsOpenedFromOutside : StatusBarInitialState.IsOpenedFromOutside); -export const selectPacmanMode = createSelector(statusBarStateSelector, (statusBar: IStatusBarState) => statusBar ? statusBar.isPacmanMode : StatusBarInitialState.isPacmanMode); export const selectMarkedSecondSearchSensors = createSelector(statusBarStateSelector, (statusBar: IStatusBarState) => statusBar?.markSecondSearchSensors); export const selectGeoFilterActive = createSelector(selectGeoFilterStatus, (geoFilterStatus: IGeoFilterStatus) => geoFilterStatus.active); export const selectGeoFilterType = createSelector(selectGeoFilterStatus, (geoFilterStatus: IGeoFilterStatus) => geoFilterStatus.type); From 2ecdff4694389e510343f0b2d3d9f7e8dff92ce6 Mon Sep 17 00:00:00 2001 From: Danaorlov1005 Date: Tue, 4 May 2021 14:38:17 +0300 Subject: [PATCH 20/21] requests --- package-lock.json | 7 +++++- package.json | 1 + .../core/services/keys-listener.service.ts | 6 ++--- .../overlay-navigation-bar.component.ts | 23 ++++++++++--------- .../components/tools/tools/tools.component.ts | 5 ++-- .../status-bar/reducers/status-bar.reducer.ts | 2 +- 6 files changed, 26 insertions(+), 18 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7a691c4dab..e2f6c16475 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "ansyn-src", - "version": "5.0.0", + "version": "5.1.3", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -20664,6 +20664,11 @@ "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", "dev": true }, + "ts-keycode-enum": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/ts-keycode-enum/-/ts-keycode-enum-1.0.6.tgz", + "integrity": "sha512-DF8+Cf/FJJnPRxwz8agCoDelQXKZWQOS/gnnwx01nZ106tPJdB3BgJ9QTtLwXgR82D8O+nTjuZzWgf0Rg4vuRA==" + }, "ts-node": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz", diff --git a/package.json b/package.json index ca2bd7c437..e4da98a59e 100644 --- a/package.json +++ b/package.json @@ -80,6 +80,7 @@ "proj4": "^2.5.0", "rxjs": "~6.5.4", "shpjs": "^3.6.3", + "ts-keycode-enum": "^1.0.6", "tslib": "^2.0.0", "wellknown": "^0.5.0", "zone.js": "~0.10.2" diff --git a/src/app/@ansyn/ansyn/modules/core/services/keys-listener.service.ts b/src/app/@ansyn/ansyn/modules/core/services/keys-listener.service.ts index a6b9ffc5dc..0a64ed9aa2 100644 --- a/src/app/@ansyn/ansyn/modules/core/services/keys-listener.service.ts +++ b/src/app/@ansyn/ansyn/modules/core/services/keys-listener.service.ts @@ -33,11 +33,11 @@ export class KeysListenerService { return className.includes('owl') || className.includes('title'); } - keyWasUsed(event: KeyboardEvent, key: string, keycode: number = key.charCodeAt(0)): boolean { - return event.key === key;// tslint:disable-line + keyWasUsed(event: KeyboardEvent, key: number): boolean { + return event.which === key; } - keysWereUsed(event: KeyboardEvent, keys: string[]): boolean { + keysWereUsed(event: KeyboardEvent, keys: number[]): boolean { return keys.some(key => this.keyWasUsed(event, key)); } } diff --git a/src/app/@ansyn/ansyn/modules/overlays/components/overlay-navigation-bar/overlay-navigation-bar.component.ts b/src/app/@ansyn/ansyn/modules/overlays/components/overlay-navigation-bar/overlay-navigation-bar.component.ts index 00a77b926d..03ccfc9f9e 100644 --- a/src/app/@ansyn/ansyn/modules/overlays/components/overlay-navigation-bar/overlay-navigation-bar.component.ts +++ b/src/app/@ansyn/ansyn/modules/overlays/components/overlay-navigation-bar/overlay-navigation-bar.component.ts @@ -15,6 +15,7 @@ import { combineLatest } from 'rxjs'; import { IOverlay, IOverlayDrop } from '../../models/overlay.model'; import { TranslateService } from '@ngx-translate/core'; import { KeysListenerService } from "../../../core/services/keys-listener.service"; +import { Key } from "ts-keycode-enum"; @Component({ selector: 'ansyn-overlay-navigation-bar', @@ -30,9 +31,9 @@ export class OverlayNavigationBarComponent implements OnInit, OnDestroy { isLastOverlay: boolean; overlaysLength: number; - private _scannedAreaKeys = '`~;'.split(''); - private _overlayHackKeys = 'Eeק'.split(''); - private _toggleDirectionKeys = 'Ddג'.split(''); + private _scannedAreaKeys = Key.Tilde; + private _overlayHackKeys = Key.E; + private _toggleDirectionKeys = Key.D; @AutoSubscription hasOverlayDisplay$ = this.store.select(selectOverlayOfActiveMap).pipe( @@ -69,13 +70,13 @@ export class OverlayNavigationBarComponent implements OnInit, OnDestroy { ); onKeyDownEventCheck($event: KeyboardEvent) { - if (this.keyListenerService.keyWasUsed($event, 'ArrowRight', 39)) { + if (this.keyListenerService.keyWasUsed($event, Key.RightArrow)) { this.goNextActive = true; - } else if (this.keyListenerService.keyWasUsed($event, 'ArrowLeft', 37)) { + } else if (this.keyListenerService.keyWasUsed($event, Key.LeftArrow)) { this.goPrevActive = true; } - if (this.keyListenerService.keysWereUsed($event, this._overlayHackKeys)) { + if (this.keyListenerService.keyWasUsed($event, this._overlayHackKeys)) { this.store.dispatch(new EnableCopyOriginalOverlayDataAction(true)); } } @@ -88,19 +89,19 @@ export class OverlayNavigationBarComponent implements OnInit, OnDestroy { ); onKeyUpEventCheck($event: KeyboardEvent) { - if (this.keyListenerService.keyWasUsed($event, 'ArrowRight', 39)) { + if (this.keyListenerService.keyWasUsed($event, Key.RightArrow)) { this.clickGoAdjacent(true); this.goNextActive = false; - } else if (this.keyListenerService.keyWasUsed($event, 'ArrowLeft', 37)) { + } else if (this.keyListenerService.keyWasUsed($event, Key.LeftArrow)) { this.clickGoAdjacent(false); this.goPrevActive = false; } - if (this.keyListenerService.keysWereUsed($event, this._overlayHackKeys)) { + if (this.keyListenerService.keyWasUsed($event, this._overlayHackKeys)) { this.store.dispatch(new EnableCopyOriginalOverlayDataAction(false)); } - if (this.keyListenerService.keysWereUsed($event, this._toggleDirectionKeys)) { + if (this.keyListenerService.keyWasUsed($event, this._toggleDirectionKeys)) { const direction = this.translateService.instant('direction'); this.translateService.set('direction', direction === 'rtl' ? 'ltr' : 'rtl', 'default'); } @@ -108,7 +109,7 @@ export class OverlayNavigationBarComponent implements OnInit, OnDestroy { @AutoSubscription onkeypress$ = () => this.keyListenerService.keyup.pipe( tap($event => { - if (this.keyListenerService.keysWereUsed($event, this._scannedAreaKeys)) { + if (this.keyListenerService.keyWasUsed($event, this._scannedAreaKeys)) { this.clickScannedArea(); } } diff --git a/src/app/@ansyn/ansyn/modules/status-bar/components/tools/tools/tools.component.ts b/src/app/@ansyn/ansyn/modules/status-bar/components/tools/tools/tools.component.ts index 5d76c6dc0a..e1b68ad99d 100644 --- a/src/app/@ansyn/ansyn/modules/status-bar/components/tools/tools/tools.component.ts +++ b/src/app/@ansyn/ansyn/modules/status-bar/components/tools/tools/tools.component.ts @@ -20,6 +20,7 @@ import { ComponentVisibilityItems } from '../../../../../app-providers/component import { PacmanPopupComponent } from '../../../../easter-eggs/pacman-popup/pacman-popup.component'; import { KeysListenerService } from '../../../../core/services/keys-listener.service'; import { selectOverlaysWithMapIds } from '@ansyn/map-facade'; +import { Key } from 'ts-keycode-enum'; @Component({ selector: 'ansyn-tools', @@ -63,7 +64,7 @@ export class ToolsComponent implements OnInit, OnDestroy { public flags: Map; toolTipDirection = 'bottom' - private _pacmanKeys = 'Ppפ'.split(''); + private _pacmanKey = Key.P; @AutoSubscription public flags$: Observable> = this.store$.select(selectToolFlags).pipe( @@ -98,7 +99,7 @@ export class ToolsComponent implements OnInit, OnDestroy { onKeyUp$ = () => this.keyListenerService.keyup.pipe( withLatestFrom(this.store$.select(selectOverlaysWithMapIds)), filter(([$event, overlayWithMapIds]: [KeyboardEvent, { overlay: any, mapId: string, isActive: boolean }[]]) => - this.keyListenerService.keysWereUsed($event, this._pacmanKeys) && + this.keyListenerService.keyWasUsed($event, this._pacmanKey) && // open pacman only when there are no overlays displayed and no dialog !this.isDialogShowing && !overlayWithMapIds.some(overlayAndMapId => Boolean(overlayAndMapId.overlay))), diff --git a/src/app/@ansyn/ansyn/modules/status-bar/reducers/status-bar.reducer.ts b/src/app/@ansyn/ansyn/modules/status-bar/reducers/status-bar.reducer.ts index 28ae4c86ae..8fdf849cf1 100644 --- a/src/app/@ansyn/ansyn/modules/status-bar/reducers/status-bar.reducer.ts +++ b/src/app/@ansyn/ansyn/modules/status-bar/reducers/status-bar.reducer.ts @@ -25,7 +25,7 @@ export const StatusBarInitialState: IStatusBarState = { isAdvancedSearchOpen: false, IsSimpleSearchOpen: false, IsOpenedFromOutside: false, - markSecondSearchSensors: false, + markSecondSearchSensors: false }; export const statusBarFeatureKey = 'statusBar'; From a2145e042022db93448fb1b670d04658c42bd4e8 Mon Sep 17 00:00:00 2001 From: Danaorlov1005 Date: Tue, 4 May 2021 14:58:00 +0300 Subject: [PATCH 21/21] added test fix --- .../overlay-navigation-bar.component.spec.ts | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/src/app/@ansyn/ansyn/modules/overlays/components/overlay-navigation-bar/overlay-navigation-bar.component.spec.ts b/src/app/@ansyn/ansyn/modules/overlays/components/overlay-navigation-bar/overlay-navigation-bar.component.spec.ts index c14f30eff3..390b283515 100644 --- a/src/app/@ansyn/ansyn/modules/overlays/components/overlay-navigation-bar/overlay-navigation-bar.component.spec.ts +++ b/src/app/@ansyn/ansyn/modules/overlays/components/overlay-navigation-bar/overlay-navigation-bar.component.spec.ts @@ -23,6 +23,7 @@ import { import { of } from 'rxjs'; import { KeysListenerService } from "../../../core/services/keys-listener.service"; import { EventEmitter } from "@angular/core"; +import { Key } from "ts-keycode-enum"; describe('OverlayNavigationBarComponent', () => { let component: OverlayNavigationBarComponent; @@ -89,29 +90,19 @@ describe('OverlayNavigationBarComponent', () => { }); }); - [{ k: 'ArrowRight', n: 'goNextActive', f: 'clickGoAdjacent' }, { - k: 'ArrowLeft', + [{ k: Key.RightArrow, n: 'goNextActive', f: 'clickGoAdjacent' }, { + k: Key.LeftArrow, n: 'goPrevActive', f: 'clickGoAdjacent' }].forEach(key => { it(`onkeyup should call ${ key.n } when key = "${ key.k }"`, () => { spyOn(component, <'clickGoAdjacent'>key.f); expect(component[key.n]).toEqual(false); - const $event = { - key: key.k, - currentTarget: { - document: { - activeElement: { - className: [] - } - } - } - }; - component.onKeyDownEventCheck(new KeyboardEvent('keydown', {'key': key.k})); + component.onKeyDownEventCheck(new KeyboardEvent('keydown', {'keyCode': key.k})); expect(component[key.n]).toEqual(true); - component.onKeyUpEventCheck(new KeyboardEvent('keyup', {'key': key.k})) + component.onKeyUpEventCheck(new KeyboardEvent('keyup', {'keyCode': key.k})) expect(component[key.n]).toEqual(false); expect(component[key.f]).toHaveBeenCalled(); });