diff --git a/pokeR/ClientApp/angular.json b/pokeR/ClientApp/angular.json
index f28b19b..c10f48c 100644
--- a/pokeR/ClientApp/angular.json
+++ b/pokeR/ClientApp/angular.json
@@ -29,7 +29,9 @@
"styles": [
"src/styles.scss"
],
- "scripts": []
+ "scripts": [
+ "node_modules/canvas-confetti/dist/confetti.browser.js"
+ ]
},
"configurations": {
"production": {
diff --git a/pokeR/ClientApp/package-lock.json b/pokeR/ClientApp/package-lock.json
index ad67169..472cda6 100644
--- a/pokeR/ClientApp/package-lock.json
+++ b/pokeR/ClientApp/package-lock.json
@@ -456,7 +456,8 @@
"ansi-regex": {
"version": "2.1.1",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"aproba": {
"version": "1.2.0",
@@ -869,7 +870,8 @@
"safe-buffer": {
"version": "5.1.2",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"safer-buffer": {
"version": "2.1.2",
@@ -925,6 +927,7 @@
"version": "3.0.1",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"ansi-regex": "^2.0.0"
}
@@ -968,12 +971,14 @@
"wrappy": {
"version": "1.0.2",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"yallist": {
"version": "3.0.3",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
}
}
},
@@ -2733,6 +2738,11 @@
"integrity": "sha512-feylzsbDxi1gPZ1IjystzIQZagYYLvfKrSuygUCgf7z6x790VEzze5QEkdSV1U58RA7Hi0+v6fv4K54atOzATg==",
"dev": true
},
+ "canvas-confetti": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/canvas-confetti/-/canvas-confetti-0.2.0.tgz",
+ "integrity": "sha512-Rt7LnO9SdVnfGLWdU2yG5LdqAMW26qg6vujYO5+49+uZboEI7BfTJCMQt04QrYX/CTxEWRveoKuzykA2oirgFA=="
+ },
"caseless": {
"version": "0.12.0",
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
diff --git a/pokeR/ClientApp/package.json b/pokeR/ClientApp/package.json
index 81de464..0fbad50 100644
--- a/pokeR/ClientApp/package.json
+++ b/pokeR/ClientApp/package.json
@@ -22,6 +22,7 @@
"@angular/router": "~7.2.11",
"@aspnet/signalr": "^1.1.0",
"@ng-bootstrap/ng-bootstrap": "^4.0.1",
+ "canvas-confetti": "^0.2.0",
"core-js": "^2.5.4",
"rxjs": "~6.4.0",
"tslib": "^1.9.0",
diff --git a/pokeR/ClientApp/src/app/pages/ingame/ingame.component.html b/pokeR/ClientApp/src/app/pages/ingame/ingame.component.html
index 3acccde..9c80653 100644
--- a/pokeR/ClientApp/src/app/pages/ingame/ingame.component.html
+++ b/pokeR/ClientApp/src/app/pages/ingame/ingame.component.html
@@ -1,9 +1,9 @@
@@ -16,4 +16,5 @@
Room not found 😢
-
\ No newline at end of file
+
+
\ No newline at end of file
diff --git a/pokeR/ClientApp/src/app/shared-components/confetti/confetti.component.html b/pokeR/ClientApp/src/app/shared-components/confetti/confetti.component.html
new file mode 100644
index 0000000..fcfc6f4
--- /dev/null
+++ b/pokeR/ClientApp/src/app/shared-components/confetti/confetti.component.html
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/pokeR/ClientApp/src/app/shared-components/confetti/confetti.component.scss b/pokeR/ClientApp/src/app/shared-components/confetti/confetti.component.scss
new file mode 100644
index 0000000..c85fe0d
--- /dev/null
+++ b/pokeR/ClientApp/src/app/shared-components/confetti/confetti.component.scss
@@ -0,0 +1,7 @@
+.confettiHolder {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100vw;
+ height: 100vh;
+}
diff --git a/pokeR/ClientApp/src/app/shared-components/confetti/confetti.component.spec.ts b/pokeR/ClientApp/src/app/shared-components/confetti/confetti.component.spec.ts
new file mode 100644
index 0000000..3987005
--- /dev/null
+++ b/pokeR/ClientApp/src/app/shared-components/confetti/confetti.component.spec.ts
@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { ConfettiComponent } from './confetti.component';
+
+describe('ConfettiComponent', () => {
+ let component: ConfettiComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ ConfettiComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(ConfettiComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/pokeR/ClientApp/src/app/shared-components/confetti/confetti.component.ts b/pokeR/ClientApp/src/app/shared-components/confetti/confetti.component.ts
new file mode 100644
index 0000000..dd2072a
--- /dev/null
+++ b/pokeR/ClientApp/src/app/shared-components/confetti/confetti.component.ts
@@ -0,0 +1,54 @@
+import { Component, ViewChild, ElementRef, AfterViewInit } from '@angular/core';
+import { ConfettiService } from './confetti.service';
+import { Observable } from 'rxjs';
+import { map } from 'rxjs/operators';
+declare const confetti;
+
+@Component({
+ selector: 'app-confetti',
+ templateUrl: './confetti.component.html',
+ styleUrls: ['./confetti.component.scss']
+})
+export class ConfettiComponent implements AfterViewInit {
+ @ViewChild('canvas') canvas: ElementRef;
+ private confettiLauncher: any;
+
+ constructor(private service: ConfettiService) { }
+
+ ngAfterViewInit(): void {
+ this.setupConfetti();
+ this.watchRequests().subscribe();
+ }
+
+ setupConfetti = (): void => {
+ this.confettiLauncher = confetti.create(this.canvas.nativeElement, { resize: true });
+ this.confettiLauncher({
+ particleCount: 100,
+ spread: 160
+ });
+ }
+
+ watchRequests = (): Observable => this.service.confettiPlz.pipe(map(this.launch))
+
+ launch = (duration: number): void => {
+ var end = Date.now() + (duration);
+
+ var interval = setInterval(() => {
+ if (Date.now() > end) {
+ return clearInterval(interval);
+ }
+
+ confetti({
+ startVelocity: 30,
+ spread: 360,
+ ticks: 60,
+ origin: {
+ x: Math.random(),
+ // since they fall down, start a bit higher than random
+ y: Math.random() - 0.2
+ }
+ });
+ }, 200);
+ }
+
+}
diff --git a/pokeR/ClientApp/src/app/shared-components/confetti/confetti.service.spec.ts b/pokeR/ClientApp/src/app/shared-components/confetti/confetti.service.spec.ts
new file mode 100644
index 0000000..db75cc7
--- /dev/null
+++ b/pokeR/ClientApp/src/app/shared-components/confetti/confetti.service.spec.ts
@@ -0,0 +1,12 @@
+import { TestBed } from '@angular/core/testing';
+
+import { ConfettiService } from './confetti.service';
+
+describe('ConfettiService', () => {
+ beforeEach(() => TestBed.configureTestingModule({}));
+
+ it('should be created', () => {
+ const service: ConfettiService = TestBed.get(ConfettiService);
+ expect(service).toBeTruthy();
+ });
+});
diff --git a/pokeR/ClientApp/src/app/shared-components/confetti/confetti.service.ts b/pokeR/ClientApp/src/app/shared-components/confetti/confetti.service.ts
new file mode 100644
index 0000000..ffbf8fc
--- /dev/null
+++ b/pokeR/ClientApp/src/app/shared-components/confetti/confetti.service.ts
@@ -0,0 +1,13 @@
+import { Injectable, EventEmitter } from '@angular/core';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class ConfettiService {
+
+ constructor() { }
+
+ public confettiPlz: EventEmitter = new EventEmitter();
+
+ public pop = (): void => this.confettiPlz.emit(5000);
+}
diff --git a/pokeR/ClientApp/src/app/shared-components/playfield/playfield.component.ts b/pokeR/ClientApp/src/app/shared-components/playfield/playfield.component.ts
index eb44eb1..36a7322 100644
--- a/pokeR/ClientApp/src/app/shared-components/playfield/playfield.component.ts
+++ b/pokeR/ClientApp/src/app/shared-components/playfield/playfield.component.ts
@@ -4,6 +4,7 @@ import { User } from 'src/app/models/entities/user';
import { Observable, forkJoin } from 'rxjs';
import { map } from 'rxjs/operators';
import { Card } from 'src/app/models/entities/card';
+import { ConfettiService } from '../confetti/confetti.service';
@Component({
selector: 'app-playfield',
@@ -14,7 +15,7 @@ export class PlayfieldComponent implements OnInit {
lastState: Array = new Array();
isRevealed = false;
- constructor(private service: PokerService) { }
+ constructor(private service: PokerService, private confetti: ConfettiService) { }
ngOnInit() {
this.watchState().subscribe();
@@ -57,7 +58,13 @@ export class PlayfieldComponent implements OnInit {
revealCards = (): void => {
this.isRevealed = true;
console.log('YOU ACTIVATED MY TRAP CARD!');
+ if (this.lastState.map(s => s.currentCardId).every(i => this.lastState.find(() => true).currentCardId === i)) {
+ console.log('party time!');
+ this.showConfetti();
+ }
}
getEmblemUrl = (id: number): string => this.service.getEmblemUrl(id);
+
+ private showConfetti = (): void => this.confetti.pop();
}
diff --git a/pokeR/ClientApp/src/app/shared-components/shared-components.module.ts b/pokeR/ClientApp/src/app/shared-components/shared-components.module.ts
index 2396e79..eb1bdea 100644
--- a/pokeR/ClientApp/src/app/shared-components/shared-components.module.ts
+++ b/pokeR/ClientApp/src/app/shared-components/shared-components.module.ts
@@ -11,6 +11,7 @@ import { PlayfieldComponent } from './playfield/playfield.component';
import { RoundStatusComponent } from './round-status/round-status.component';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { AppRoutingModule } from '../app-routing.module';
+import { ConfettiComponent } from './confetti/confetti.component';
@NgModule({
declarations: [
@@ -21,7 +22,8 @@ import { AppRoutingModule } from '../app-routing.module';
JoinRoomComponent,
CardListComponent,
PlayfieldComponent,
- RoundStatusComponent
+ RoundStatusComponent,
+ ConfettiComponent
], imports: [
CommonModule,
FormsModule,
@@ -35,7 +37,8 @@ import { AppRoutingModule } from '../app-routing.module';
JoinRoomComponent,
CardListComponent,
PlayfieldComponent,
- RoundStatusComponent
+ RoundStatusComponent,
+ ConfettiComponent
]
})
export class SharedComponentsModule { }