versus implementation
This commit is contained in:
parent
3bb63d1d5a
commit
afabd52e02
23 changed files with 332 additions and 11 deletions
|
|
@ -4,6 +4,7 @@ import { HomeComponent } from "./home/home.component";
|
||||||
import { Observable, of } from "rxjs";
|
import { Observable, of } from "rxjs";
|
||||||
import {ConfigurationComponent} from "./configuration/configuration.component";
|
import {ConfigurationComponent} from "./configuration/configuration.component";
|
||||||
import {AdminMainComponent} from "./admin-main/admin-main.component";
|
import {AdminMainComponent} from "./admin-main/admin-main.component";
|
||||||
|
import {AdminTestingComponent} from "./admin-testing/admin-testing.component";
|
||||||
|
|
||||||
export class AdminGuard {
|
export class AdminGuard {
|
||||||
|
|
||||||
|
|
@ -20,7 +21,6 @@ export class AdminGuard {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
{
|
{
|
||||||
path: '',
|
path: '',
|
||||||
|
|
@ -36,7 +36,13 @@ const routes: Routes = [
|
||||||
path: 'configuration',
|
path: 'configuration',
|
||||||
component: ConfigurationComponent,
|
component: ConfigurationComponent,
|
||||||
canDeactivate: [AdminGuard],
|
canDeactivate: [AdminGuard],
|
||||||
}]
|
},
|
||||||
|
{
|
||||||
|
path:'testing',
|
||||||
|
component: AdminTestingComponent,
|
||||||
|
canDeactivate: [AdminGuard],
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|
|
||||||
12
src/app/admin/admin-testing/admin-testing.component.html
Normal file
12
src/app/admin/admin-testing/admin-testing.component.html
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
<div class="game-testing m-2" *ngIf="!prodMode">
|
||||||
|
<h3>Game testing menu</h3>
|
||||||
|
<button class="btn btn-danger" (click)="simulateVersus()">Begin versus</button>
|
||||||
|
<button class="btn btn-danger" disabled>Stop versus</button>
|
||||||
|
<button class="btn btn-danger" disabled>Simulate endgame points</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="game-testing m-2" *ngIf="prodMode">
|
||||||
|
<div class="alert alert-danger">
|
||||||
|
You are in prod mode, testing disabled
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
6
src/app/admin/admin-testing/admin-testing.component.scss
Normal file
6
src/app/admin/admin-testing/admin-testing.component.scss
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
div {
|
||||||
|
|
||||||
|
button {
|
||||||
|
margin: 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
21
src/app/admin/admin-testing/admin-testing.component.spec.ts
Normal file
21
src/app/admin/admin-testing/admin-testing.component.spec.ts
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { AdminTestingComponent } from './admin-testing.component';
|
||||||
|
|
||||||
|
describe('AdminTestingComponent', () => {
|
||||||
|
let component: AdminTestingComponent;
|
||||||
|
let fixture: ComponentFixture<AdminTestingComponent>;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [AdminTestingComponent]
|
||||||
|
});
|
||||||
|
fixture = TestBed.createComponent(AdminTestingComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
40
src/app/admin/admin-testing/admin-testing.component.ts
Normal file
40
src/app/admin/admin-testing/admin-testing.component.ts
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
import {Component, OnDestroy, OnInit} from '@angular/core';
|
||||||
|
import {ApiService} from "../../services/api.service";
|
||||||
|
import {Subject} from "rxjs";
|
||||||
|
import {takeUntil} from "rxjs/operators";
|
||||||
|
import {EventService} from "../../services/event.service";
|
||||||
|
import {TestingApiService} from "../../services/testing-api.service";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-admin-testing',
|
||||||
|
templateUrl: './admin-testing.component.html',
|
||||||
|
styleUrls: ['./admin-testing.component.scss']
|
||||||
|
})
|
||||||
|
export class AdminTestingComponent implements OnInit, OnDestroy {
|
||||||
|
prodMode = false;
|
||||||
|
destroyed$ = new Subject<void>();
|
||||||
|
constructor(
|
||||||
|
private apiService: ApiService,
|
||||||
|
private eventService: EventService,
|
||||||
|
private testingApiService: TestingApiService) {
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
this.getFFState();
|
||||||
|
this.eventService.featureFlagChanged.pipe(takeUntil(this.destroyed$)).subscribe((r) => this.getFFState());
|
||||||
|
}
|
||||||
|
|
||||||
|
private getFFState() {
|
||||||
|
this.apiService.getFeatureFlagState("ProdMode").pipe(takeUntil(this.destroyed$)).subscribe((res) =>
|
||||||
|
{
|
||||||
|
this.prodMode = res.state;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
ngOnDestroy() {
|
||||||
|
this.destroyed$.complete();
|
||||||
|
}
|
||||||
|
|
||||||
|
simulateVersus() {
|
||||||
|
this.testingApiService.simulateVersus().pipe(takeUntil(this.destroyed$)).subscribe((r) => console.log(r));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -9,6 +9,7 @@ import { ConfigurationComponent } from './configuration/configuration.component'
|
||||||
import { AdminNavComponent } from './components/admin-nav/admin-nav.component';
|
import { AdminNavComponent } from './components/admin-nav/admin-nav.component';
|
||||||
import { AdminMainComponent } from './admin-main/admin-main.component';
|
import { AdminMainComponent } from './admin-main/admin-main.component';
|
||||||
import { FeatureflagsComponent } from './components/featureflags/featureflags.component';
|
import { FeatureflagsComponent } from './components/featureflags/featureflags.component';
|
||||||
|
import { AdminTestingComponent } from './admin-testing/admin-testing.component';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -21,6 +22,7 @@ import { FeatureflagsComponent } from './components/featureflags/featureflags.co
|
||||||
AdminNavComponent,
|
AdminNavComponent,
|
||||||
AdminMainComponent,
|
AdminMainComponent,
|
||||||
FeatureflagsComponent,
|
FeatureflagsComponent,
|
||||||
|
AdminTestingComponent,
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
CommonModule, AdminRoutingModule, SharedModule,
|
CommonModule, AdminRoutingModule, SharedModule,
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
|
||||||
<a routerLink="/admin/">Main</a>
|
<a routerLink="/admin/">Main</a>
|
||||||
|
<a routerLink="/admin/testing">Testing</a>
|
||||||
<a routerLink="/admin/configuration">Config</a>
|
<a routerLink="/admin/configuration">Config</a>
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,15 @@ export class FeatureflagsComponent implements OnInit, OnDestroy {
|
||||||
this.apiService.getFeatureFlagState(featureFlag).pipe(takeUntil(this.destroyed$)).subscribe((result) => {
|
this.apiService.getFeatureFlagState(featureFlag).pipe(takeUntil(this.destroyed$)).subscribe((result) => {
|
||||||
if(!this.features.find((x) => x.name === result.name)) {
|
if(!this.features.find((x) => x.name === result.name)) {
|
||||||
this.features.push(result);
|
this.features.push(result);
|
||||||
|
this.features.sort((a, b) => {
|
||||||
|
if (a.name < b.name) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (a.name > b.name) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
const index = this.features.findIndex((x) => x.name === result.name);
|
const index = this.features.findIndex((x) => x.name === result.name);
|
||||||
this.features[index] = result;
|
this.features[index] = result;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
<app-toast>
|
<app-versus *ngIf="versusInProgress" [player1]="versusData.player1" [player2]="versusData.player2">
|
||||||
|
|
||||||
|
</app-versus>
|
||||||
|
<app-toast>
|
||||||
</app-toast>
|
</app-toast>
|
||||||
<audio *ngIf="audioSrc" [src]="audioSrc" autoplay (ended)="onAudioEnded()"></audio>
|
<audio *ngIf="audioSrc" [src]="audioSrc" autoplay (ended)="onAudioEnded()"></audio>
|
||||||
<router-outlet></router-outlet>
|
<router-outlet></router-outlet>
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||||
import { io, Socket } from "socket.io-client";
|
import { io, Socket } from "socket.io-client";
|
||||||
import { API_URL, WEBSOCK_URL } from '../app.constants';
|
import { API_URL, WEBSOCK_URL } from '../app.constants';
|
||||||
import { EventService } from "./services/event.service";
|
import { EventService } from "./services/event.service";
|
||||||
import { EventStateChanged, ServerEvent } from "../types/server-event";
|
import {EventStateChanged, ServerEvent, VersusBeginEvent} from "../types/server-event";
|
||||||
import { ApiService } from "./services/api.service";
|
import { ApiService } from "./services/api.service";
|
||||||
import { ActivatedRoute, Router } from "@angular/router";
|
import { ActivatedRoute, Router } from "@angular/router";
|
||||||
import { filter, map, takeUntil } from "rxjs/operators";
|
import { filter, map, takeUntil } from "rxjs/operators";
|
||||||
|
|
@ -20,6 +20,8 @@ export class AppComponent implements OnInit, OnDestroy {
|
||||||
title = 'thanksgiving';
|
title = 'thanksgiving';
|
||||||
connection = io(WEBSOCK_URL, { transports: ['websocket']});
|
connection = io(WEBSOCK_URL, { transports: ['websocket']});
|
||||||
destroyed = new Subject<void>();
|
destroyed = new Subject<void>();
|
||||||
|
versusInProgress = false;
|
||||||
|
versusData: VersusBeginEvent;
|
||||||
audioSrc: string;
|
audioSrc: string;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
|
@ -39,9 +41,11 @@ export class AppComponent implements OnInit, OnDestroy {
|
||||||
this.eventService.emit(data);
|
this.eventService.emit(data);
|
||||||
});
|
});
|
||||||
this.apiService.getAppState('main').subscribe((result) => {
|
this.apiService.getAppState('main').subscribe((result) => {
|
||||||
|
if(this.router.url.indexOf('admin') === -1) {
|
||||||
this.router.navigate([`/${result.value}`]).then(() => {
|
this.router.navigate([`/${result.value}`]).then(() => {
|
||||||
console.log(`navigated to ${result.value}`);
|
console.log(`navigated to ${result.value}`);
|
||||||
})
|
})
|
||||||
|
}
|
||||||
});
|
});
|
||||||
this.eventService.stateChangedEvent.pipe(
|
this.eventService.stateChangedEvent.pipe(
|
||||||
map(e => e.data),
|
map(e => e.data),
|
||||||
|
|
@ -55,6 +59,7 @@ export class AppComponent implements OnInit, OnDestroy {
|
||||||
console.log(text);
|
console.log(text);
|
||||||
this.audioSrc = text;
|
this.audioSrc = text;
|
||||||
})
|
})
|
||||||
|
this.setupVersusHandler();
|
||||||
}
|
}
|
||||||
ngOnDestroy() {
|
ngOnDestroy() {
|
||||||
this.destroyed.complete();
|
this.destroyed.complete();
|
||||||
|
|
@ -63,4 +68,14 @@ export class AppComponent implements OnInit, OnDestroy {
|
||||||
onAudioEnded() {
|
onAudioEnded() {
|
||||||
this.voiceService.audioEnded();
|
this.voiceService.audioEnded();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private setupVersusHandler() {
|
||||||
|
console.log(this.routeSnapshot.snapshot.url);
|
||||||
|
this.eventService.versusBegin.pipe(takeUntil(this.destroyed)).subscribe(r => {
|
||||||
|
if(this.router.url.indexOf('admin') === -1) {
|
||||||
|
this.versusInProgress = true;
|
||||||
|
this.versusData = r.data;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ import { AvatarComponent } from './components/avatar/avatar.component';
|
||||||
import { FinishComponent } from './views/finish/finish.component';
|
import { FinishComponent } from './views/finish/finish.component';
|
||||||
import { InitialComponent } from './views/initial/initial.component';
|
import { InitialComponent } from './views/initial/initial.component';
|
||||||
import { SkrepaComponent } from './components/skrepa/skrepa.component';
|
import { SkrepaComponent } from './components/skrepa/skrepa.component';
|
||||||
|
import { VersusComponent } from './components/versus/versus.component';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
|
|
@ -50,6 +51,7 @@ import { SkrepaComponent } from './components/skrepa/skrepa.component';
|
||||||
FinishComponent,
|
FinishComponent,
|
||||||
InitialComponent,
|
InitialComponent,
|
||||||
SkrepaComponent,
|
SkrepaComponent,
|
||||||
|
VersusComponent,
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
BrowserModule,
|
BrowserModule,
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
<div class="card shadow rounded m-3 animate__animated" [ngClass]="{ 'small': small, 'banned': banned, 'animate__flipInY': small }">
|
<div class="card rounded m-3 animate__animated" [ngClass]="{ 'small': small, 'shadow': shadow, 'transparent': transparent, 'banned': banned, 'animate__flipInY': small }">
|
||||||
<figure class="p-1">
|
<figure class="p-1">
|
||||||
<img [src]="getImageUrl()" class="participant-photo img-fluid">
|
<img [src]="getImageUrl()" class="participant-photo img-fluid">
|
||||||
</figure>
|
</figure>
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,10 @@
|
||||||
padding: 0px;
|
padding: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.transparent {
|
||||||
|
background: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
figure {
|
figure {
|
||||||
border-radius:100%;
|
border-radius:100%;
|
||||||
display:inline-block;
|
display:inline-block;
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,8 @@ export class ParticipantItemComponent implements OnInit, OnDestroy, OnChanges {
|
||||||
imgTimestamp = (new Date()).getTime();
|
imgTimestamp = (new Date()).getTime();
|
||||||
addAnimatedClass = false;
|
addAnimatedClass = false;
|
||||||
@Input() bannedRemaining: number|undefined = 0;
|
@Input() bannedRemaining: number|undefined = 0;
|
||||||
|
@Input() transparent = false;
|
||||||
|
@Input() shadow = true;
|
||||||
|
|
||||||
constructor(private eventService: EventService, private apiService: ApiService) {
|
constructor(private eventService: EventService, private apiService: ApiService) {
|
||||||
}
|
}
|
||||||
|
|
|
||||||
14
src/app/components/versus/versus.component.html
Normal file
14
src/app/components/versus/versus.component.html
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
<div class="versus">
|
||||||
|
|
||||||
|
<div class="d-flex players">
|
||||||
|
<div class="player-one">
|
||||||
|
<app-participant-item [participant]="player1data" [small]="true" [shadow]="false" [transparent]="true">
|
||||||
|
</app-participant-item>
|
||||||
|
</div>
|
||||||
|
<div class="player-two">
|
||||||
|
<app-participant-item [participant]="player2data" [small]="true" [shadow]="false" [transparent]="true">
|
||||||
|
|
||||||
|
</app-participant-item>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
86
src/app/components/versus/versus.component.scss
Normal file
86
src/app/components/versus/versus.component.scss
Normal file
|
|
@ -0,0 +1,86 @@
|
||||||
|
@import '../../../styles';
|
||||||
|
@keyframes slideDown {
|
||||||
|
0% {
|
||||||
|
top: -100vh;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@keyframes slideRight {
|
||||||
|
0% {
|
||||||
|
left: -100vh;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes slideLeft {
|
||||||
|
0% {
|
||||||
|
right: -100vh;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.versus {
|
||||||
|
background-color: $thg_brown;
|
||||||
|
z-index: 20000;
|
||||||
|
position: fixed;
|
||||||
|
top: -100vh;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100vh;
|
||||||
|
animation: slideDown 1s ease forwards;
|
||||||
|
}
|
||||||
|
.versus:before {
|
||||||
|
content: "VS";
|
||||||
|
position: absolute;
|
||||||
|
font-size: 20vw; /* Large size for the background */
|
||||||
|
color: rgba(255, 255, 255, 0.2); /* Light opacity */
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
font-weight: bold;
|
||||||
|
z-index: 22000; /* Puts it behind other content */
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.players {
|
||||||
|
height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Left player area */
|
||||||
|
.player-one {
|
||||||
|
position: relative;
|
||||||
|
width: 50%;
|
||||||
|
height: 100%;
|
||||||
|
background-color: #4a90e2;
|
||||||
|
clip-path: polygon(0 0, 100% 0, 50% 100%, 0 100%);
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
color: white;
|
||||||
|
font-size: 2rem;
|
||||||
|
font-weight: bold;
|
||||||
|
animation: slideRight 1s ease forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Right player area */
|
||||||
|
.player-two {
|
||||||
|
position: relative;
|
||||||
|
width: 50%;
|
||||||
|
height: 100%;
|
||||||
|
background-color: #d9534f;
|
||||||
|
clip-path: polygon(50% 0, 100% 0, 100% 100%, 0 100%);
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
color: white;
|
||||||
|
font-size: 2rem;
|
||||||
|
font-weight: bold;
|
||||||
|
animation: slideLeft 1s ease forwards;
|
||||||
|
}
|
||||||
21
src/app/components/versus/versus.component.spec.ts
Normal file
21
src/app/components/versus/versus.component.spec.ts
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { VersusComponent } from './versus.component';
|
||||||
|
|
||||||
|
describe('VersusComponent', () => {
|
||||||
|
let component: VersusComponent;
|
||||||
|
let fixture: ComponentFixture<VersusComponent>;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [VersusComponent]
|
||||||
|
});
|
||||||
|
fixture = TestBed.createComponent(VersusComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
32
src/app/components/versus/versus.component.ts
Normal file
32
src/app/components/versus/versus.component.ts
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
import {Component, Input, OnDestroy, OnInit} from '@angular/core';
|
||||||
|
import {ApiService} from "../../services/api.service";
|
||||||
|
import {Subject} from "rxjs";
|
||||||
|
import {takeUntil} from "rxjs/operators";
|
||||||
|
import {Participant} from "../../../types/participant";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-versus',
|
||||||
|
templateUrl: './versus.component.html',
|
||||||
|
styleUrls: ['./versus.component.scss']
|
||||||
|
})
|
||||||
|
export class VersusComponent implements OnInit, OnDestroy{
|
||||||
|
@Input() player1: number;
|
||||||
|
@Input() player2: number;
|
||||||
|
player1data: Participant;
|
||||||
|
player2data: Participant;
|
||||||
|
destroyed$ = new Subject<void>();
|
||||||
|
|
||||||
|
constructor(private apiService: ApiService) {
|
||||||
|
}
|
||||||
|
ngOnInit() {
|
||||||
|
this.loadPlayersData();
|
||||||
|
}
|
||||||
|
ngOnDestroy() {
|
||||||
|
this.destroyed$.complete();
|
||||||
|
}
|
||||||
|
|
||||||
|
loadPlayersData() {
|
||||||
|
this.apiService.getParticipant(this.player1).pipe(takeUntil(this.destroyed$)).subscribe((r) => this.player1data = r);
|
||||||
|
this.apiService.getParticipant(this.player2).pipe(takeUntil(this.destroyed$)).subscribe((r) => this.player2data = r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -9,7 +9,7 @@ import {
|
||||||
EventUserAdded,
|
EventUserAdded,
|
||||||
EventWrongAnswerReceived,
|
EventWrongAnswerReceived,
|
||||||
QuestionChangedEvent,
|
QuestionChangedEvent,
|
||||||
ServerEvent, UserPropertyChanged
|
ServerEvent, UserPropertyChanged, VersusBeginEvent
|
||||||
} from "../../types/server-event";
|
} from "../../types/server-event";
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
|
|
@ -31,7 +31,8 @@ export class EventService {
|
||||||
public gameResumed = new EventEmitter<ServerEvent<void>>();
|
public gameResumed = new EventEmitter<ServerEvent<void>>();
|
||||||
public notificationEvent = new EventEmitter<ServerEvent<EventNotification>>();
|
public notificationEvent = new EventEmitter<ServerEvent<EventNotification>>();
|
||||||
public userPropertyChanged = new EventEmitter<ServerEvent<UserPropertyChanged>>();
|
public userPropertyChanged = new EventEmitter<ServerEvent<UserPropertyChanged>>();
|
||||||
public featureFlagChanged = new EventEmitter<ServerEvent<void>>();
|
public featureFlagChanged = new EventEmitter<ServerEvent<void>>()
|
||||||
|
public versusBegin = new EventEmitter<ServerEvent<VersusBeginEvent>>();
|
||||||
constructor() { }
|
constructor() { }
|
||||||
|
|
||||||
public emit(event: ServerEvent<any>) {
|
public emit(event: ServerEvent<any>) {
|
||||||
|
|
@ -85,6 +86,9 @@ export class EventService {
|
||||||
case "feature_flag_changed":
|
case "feature_flag_changed":
|
||||||
this.featureFlagChanged.emit(event);
|
this.featureFlagChanged.emit(event);
|
||||||
break;
|
break;
|
||||||
|
case "begin_versus":
|
||||||
|
this.versusBegin.emit(event as ServerEvent<VersusBeginEvent>);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
15
src/app/services/testing-api.service.ts
Normal file
15
src/app/services/testing-api.service.ts
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import {HttpClient} from "@angular/common/http";
|
||||||
|
import {API_URL} from "../../app.constants";
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class TestingApiService {
|
||||||
|
|
||||||
|
constructor(private httpClient: HttpClient) { }
|
||||||
|
|
||||||
|
public simulateVersus() {
|
||||||
|
return this.httpClient.post(`${API_URL}/game/simulate-versus`, {});
|
||||||
|
}
|
||||||
|
}
|
||||||
16
src/app/services/testingapi.service.spec.ts
Normal file
16
src/app/services/testingapi.service.spec.ts
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
import { TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { TestingApiService } from './testing-api.service';
|
||||||
|
|
||||||
|
describe('TestingapiService', () => {
|
||||||
|
let service: TestingApiService;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
TestBed.configureTestingModule({});
|
||||||
|
service = TestBed.inject(TestingApiService);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be created', () => {
|
||||||
|
expect(service).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -1,3 +1,8 @@
|
||||||
export class FeatureFlagList {
|
export class FeatureFlagList {
|
||||||
static readonly FeatureFlags: string[] = ["EnableEndgamePoints"];
|
static readonly FeatureFlags: string[] = [
|
||||||
|
"EnableEndgamePoints",
|
||||||
|
"DontMarkQuestionsAsCompleted",
|
||||||
|
"DisableVoice",
|
||||||
|
"ProdMode",
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
@ -51,6 +51,11 @@ export interface EventScoreChanged {
|
||||||
newScore: number;
|
newScore: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface VersusBeginEvent {
|
||||||
|
player1: number;
|
||||||
|
player2: number;
|
||||||
|
}
|
||||||
|
|
||||||
export interface EventGameQueue {
|
export interface EventGameQueue {
|
||||||
text?: string;
|
text?: string;
|
||||||
target: number;
|
target: number;
|
||||||
|
|
@ -88,5 +93,6 @@ export interface ServerEvent<T> {
|
||||||
| 'notification'
|
| 'notification'
|
||||||
| 'user_property_changed'
|
| 'user_property_changed'
|
||||||
| 'feature_flag_changed'
|
| 'feature_flag_changed'
|
||||||
|
| 'begin_versus'
|
||||||
data: T
|
data: T
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue