Compare commits
8 commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6907404c67 | |||
| b3930f77c8 | |||
| 352260c86f | |||
| a7553e0614 | |||
| 0aad9d3ecb | |||
| ad965cfd6a | |||
| 5dd911fb01 | |||
| 70cd2a8587 |
27 changed files with 162 additions and 109 deletions
32
Dockerfile
Normal file
32
Dockerfile
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
# Stage 1: Build the Angular application
|
||||||
|
FROM node:20 as build
|
||||||
|
|
||||||
|
# Set the working directory
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Copy package.json and package-lock.json to install dependencies
|
||||||
|
COPY package*.json ./
|
||||||
|
|
||||||
|
# Install Node.js dependencies
|
||||||
|
RUN npm install
|
||||||
|
|
||||||
|
# Copy the rest of the application code
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
# Build the Angular application in production mode
|
||||||
|
RUN npm run build --configuration=prod
|
||||||
|
|
||||||
|
# Stage 2: Serve the app with Nginx
|
||||||
|
FROM nginx:1.21-alpine
|
||||||
|
|
||||||
|
# Copy the built app from the previous stage
|
||||||
|
COPY --from=build /app/dist/thanksgiving /usr/share/nginx/html
|
||||||
|
|
||||||
|
# Copy the custom Nginx configuration
|
||||||
|
COPY nginx.conf /etc/nginx/conf.d/default.conf
|
||||||
|
|
||||||
|
# Expose port 80
|
||||||
|
EXPOSE 80
|
||||||
|
|
||||||
|
# Start Nginx server
|
||||||
|
CMD ["nginx", "-g", "daemon off;"]
|
||||||
11
nginx.conf
Normal file
11
nginx.conf
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name localhost;
|
||||||
|
|
||||||
|
root /usr/share/nginx/html;
|
||||||
|
index index.html;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
try_files $uri $uri/ /index.html;
|
||||||
|
}
|
||||||
|
}
|
||||||
5
package-lock.json
generated
5
package-lock.json
generated
|
|
@ -34,7 +34,7 @@
|
||||||
"@angular/cli": "^16.2.9",
|
"@angular/cli": "^16.2.9",
|
||||||
"@angular/compiler-cli": "~16.2.12",
|
"@angular/compiler-cli": "~16.2.12",
|
||||||
"@types/jasmine": "~3.8.0",
|
"@types/jasmine": "~3.8.0",
|
||||||
"@types/node": "^12.11.1",
|
"@types/node": "^12.20.55",
|
||||||
"jasmine-core": "~3.8.0",
|
"jasmine-core": "~3.8.0",
|
||||||
"karma": "~6.3.0",
|
"karma": "~6.3.0",
|
||||||
"karma-chrome-launcher": "~3.1.0",
|
"karma-chrome-launcher": "~3.1.0",
|
||||||
|
|
@ -3646,7 +3646,8 @@
|
||||||
"version": "12.20.55",
|
"version": "12.20.55",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz",
|
||||||
"integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==",
|
"integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==",
|
||||||
"dev": true
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@types/node-forge": {
|
"node_modules/@types/node-forge": {
|
||||||
"version": "1.3.9",
|
"version": "1.3.9",
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@
|
||||||
"@angular/cli": "^16.2.9",
|
"@angular/cli": "^16.2.9",
|
||||||
"@angular/compiler-cli": "~16.2.12",
|
"@angular/compiler-cli": "~16.2.12",
|
||||||
"@types/jasmine": "~3.8.0",
|
"@types/jasmine": "~3.8.0",
|
||||||
"@types/node": "^12.11.1",
|
"@types/node": "^12.20.55",
|
||||||
"jasmine-core": "~3.8.0",
|
"jasmine-core": "~3.8.0",
|
||||||
"karma": "~6.3.0",
|
"karma": "~6.3.0",
|
||||||
"karma-chrome-launcher": "~3.1.0",
|
"karma-chrome-launcher": "~3.1.0",
|
||||||
|
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
export const API_URL = 'http://127.0.0.1:3000';
|
|
||||||
export const WEBSOCK_URL = 'http://127.0.0.1:3000';
|
|
||||||
// export const API_URL = 'https://thanksgiving2023.ngweb.io/api';
|
|
||||||
//export const WEBSOCK_URL = "https://thanksgiving2023.ngweb.io/"
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
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 { EventService } from "./services/event.service";
|
import { EventService } from "./services/event.service";
|
||||||
import {EventStateChanged, ServerEvent, VersusBeginEvent} from "../types/server-event";
|
import {EventStateChanged, ServerEvent, VersusBeginEvent} from "../types/server-event";
|
||||||
import { ApiService } from "./services/api.service";
|
import { ApiService } from "./services/api.service";
|
||||||
|
|
@ -8,9 +7,10 @@ import { ActivatedRoute, Router } from "@angular/router";
|
||||||
import { filter, map, takeUntil } from "rxjs/operators";
|
import { filter, map, takeUntil } from "rxjs/operators";
|
||||||
import { ToastService } from "./toast.service";
|
import { ToastService } from "./toast.service";
|
||||||
import { VoiceService } from "./services/voice.service";
|
import { VoiceService } from "./services/voice.service";
|
||||||
import { Subject } from "rxjs";
|
import {delay, delayWhen, Subject} from "rxjs";
|
||||||
import { getAudioPath } from "./helper/tts.helper";
|
import { getAudioPath } from "./helper/tts.helper";
|
||||||
import {animate, keyframes, style, transition, trigger} from "@angular/animations";
|
import {animate, keyframes, style, transition, trigger} from "@angular/animations";
|
||||||
|
import {environment} from "../environments/environment";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-root',
|
selector: 'app-root',
|
||||||
|
|
@ -32,7 +32,7 @@ import {animate, keyframes, style, transition, trigger} from "@angular/animation
|
||||||
})
|
})
|
||||||
export class AppComponent implements OnInit, OnDestroy {
|
export class AppComponent implements OnInit, OnDestroy {
|
||||||
title = 'thanksgiving';
|
title = 'thanksgiving';
|
||||||
connection = io(WEBSOCK_URL, { transports: ['websocket']});
|
connection = io(environment.WEBSOCK_URL, { transports: ['websocket']});
|
||||||
destroyed = new Subject<void>();
|
destroyed = new Subject<void>();
|
||||||
versusData: VersusBeginEvent|null = null;
|
versusData: VersusBeginEvent|null = null;
|
||||||
audioSrc: string;
|
audioSrc: string;
|
||||||
|
|
@ -53,8 +53,8 @@ export class AppComponent implements OnInit, OnDestroy {
|
||||||
console.log(data);
|
console.log(data);
|
||||||
this.eventService.emit(data);
|
this.eventService.emit(data);
|
||||||
});
|
});
|
||||||
this.apiService.getAppState('main').subscribe((result) => {
|
this.apiService.getAppState('main').pipe(takeUntil(this.destroyed),delay(300)).subscribe((result) => {
|
||||||
if(this.router.url.indexOf('admin') === -1) {
|
if(this.router.url.indexOf('admin') === -1 || window.location.href.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}`);
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
<div class="d-block justify-content-centers">
|
<div class="d-block justify-content-centers">
|
||||||
<h1 *ngIf="answerIsValid">🎉 Ура, правильный ответ!</h1>
|
<h1 *ngIf="answerIsValid">🎉 Ура, правильный ответ!</h1>
|
||||||
<h1 *ngIf="!answerIsValid">❌ А вот и нет! ❌</h1>
|
<h1 *ngIf="!answerIsValid">❌ А вот и нет! ❌</h1>
|
||||||
<div class="d-flex align-items-center justify-content-center flex-wrap">
|
<div class="d-flex align-items-center justify-content-center flex-wrap" *ngIf="this.participants.length > 0">
|
||||||
<ng-container *ngFor="let participant of participants" >
|
<ng-container *ngFor="let participant of participants" >
|
||||||
<app-participant-item [participant]="participant"></app-participant-item>
|
<app-participant-item [participant]="participant"></app-participant-item>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||||
import { ApiService } from "../../services/api.service";
|
import { ApiService } from "../../services/api.service";
|
||||||
import { interval, Observable, Subject } from "rxjs";
|
import {concatMap, interval, Observable, Subject} from "rxjs";
|
||||||
import { EventService } from "../../services/event.service";
|
import { EventService } from "../../services/event.service";
|
||||||
import { filter, map, take, takeUntil, tap } from "rxjs/operators";
|
import { filter, map, take, takeUntil, tap } from "rxjs/operators";
|
||||||
import { Participant } from "../../../types/participant";
|
import { Participant } from "../../../types/participant";
|
||||||
|
|
@ -57,7 +57,6 @@ export class AnswerNotificationComponent implements OnInit, OnDestroy {
|
||||||
participants: Participant[] = [];
|
participants: Participant[] = [];
|
||||||
audioSrc: string;
|
audioSrc: string;
|
||||||
private destroyed$ = new Subject<void>();
|
private destroyed$ = new Subject<void>();
|
||||||
|
|
||||||
constructor(private apiService: ApiService, private eventService: EventService, private voiceService: VoiceService) {
|
constructor(private apiService: ApiService, private eventService: EventService, private voiceService: VoiceService) {
|
||||||
this.eventService.answerReceivedEvent.pipe(
|
this.eventService.answerReceivedEvent.pipe(
|
||||||
takeUntil(this.destroyed$),
|
takeUntil(this.destroyed$),
|
||||||
|
|
@ -75,6 +74,8 @@ export class AnswerNotificationComponent implements OnInit, OnDestroy {
|
||||||
// this.participant.score = e.newScore
|
// this.participant.score = e.newScore
|
||||||
// }
|
// }
|
||||||
// });
|
// });
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
showNotification(telegramId: number, validAnswer: boolean, validAnswerValue: string, note: string|null) {
|
showNotification(telegramId: number, validAnswer: boolean, validAnswerValue: string, note: string|null) {
|
||||||
|
|
@ -89,7 +90,10 @@ export class AnswerNotificationComponent implements OnInit, OnDestroy {
|
||||||
templateData['user'] = p.name;
|
templateData['user'] = p.name;
|
||||||
templateData['answer'] = validAnswerValue;
|
templateData['answer'] = validAnswerValue;
|
||||||
templateData['user-genitive'] = p.properties.genitive;
|
templateData['user-genitive'] = p.properties.genitive;
|
||||||
this.voiceService.playAudio(getAudioPathWithTemplate(template, '', templateData));
|
if(this.participants.length === 1) {
|
||||||
|
this.voiceService.playAudio(getAudioPathWithTemplate(template, '', templateData));
|
||||||
|
}
|
||||||
|
//this.voiceService.playAudio(getAudioPathWithTemplate(template, '', templateData));
|
||||||
this.voiceService.audioEndedSubject.pipe(takeUntil(this.destroyed$), take(1)).subscribe(r => {
|
this.voiceService.audioEndedSubject.pipe(takeUntil(this.destroyed$), take(1)).subscribe(r => {
|
||||||
if (note && validAnswer) {
|
if (note && validAnswer) {
|
||||||
this.voiceService.playAudio(getAudioPath(note))
|
this.voiceService.playAudio(getAudioPath(note))
|
||||||
|
|
@ -101,13 +105,14 @@ export class AnswerNotificationComponent implements OnInit, OnDestroy {
|
||||||
}
|
}
|
||||||
|
|
||||||
countdownCompleted() {
|
countdownCompleted() {
|
||||||
|
this.participants = [];
|
||||||
console.log(`countdown-completed`);
|
console.log(`countdown-completed`);
|
||||||
this.showCountdown = false;
|
this.showCountdown = false;
|
||||||
this.isShown = false;
|
this.isShown = false;
|
||||||
this.announceAudio = false;
|
this.announceAudio = false;
|
||||||
this.countdown = 10;
|
this.countdown = 10;
|
||||||
this.apiService.continueGame().subscribe(r => console.log(r));
|
// this.apiService.continueGame().subscribe(r => console.log(r));
|
||||||
this.participants = [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,11 @@
|
||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
import { EventService } from "../../services/event.service";
|
import { EventService } from "../../services/event.service";
|
||||||
import { filter, map } from "rxjs/operators";
|
import { filter, map } from "rxjs/operators";
|
||||||
import { EventCardPlayed } from "../../../types/server-event";
|
|
||||||
import { ApiService } from "../../services/api.service";
|
import { ApiService } from "../../services/api.service";
|
||||||
import { animate, style, transition, trigger } from "@angular/animations";
|
import { animate, style, transition, trigger } from "@angular/animations";
|
||||||
import { API_URL } from "../../../app.constants";
|
|
||||||
import { getAudioPath } from "../../helper/tts.helper";
|
import { getAudioPath } from "../../helper/tts.helper";
|
||||||
import { VoiceService } from "../../services/voice.service";
|
import { VoiceService } from "../../services/voice.service";
|
||||||
|
import {environment} from "../../../environments/environment";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-card-played',
|
selector: 'app-card-played',
|
||||||
|
|
@ -59,7 +58,7 @@ export class CardPlayedComponent implements OnInit {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
getImageUrl() {
|
getImageUrl() {
|
||||||
return `${API_URL}/guests/photo/${this.participantId}?$t=${this.imgTimestamp}`;
|
return `${environment.API_URL}/guests/photo/${this.participantId}?$t=${this.imgTimestamp}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
getAudioSrc(text: string) {
|
getAudioSrc(text: string) {
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ import { getAudioPath } from "../../helper/tts.helper";
|
||||||
})
|
})
|
||||||
export class GamePauseComponent implements OnInit, OnDestroy {
|
export class GamePauseComponent implements OnInit, OnDestroy {
|
||||||
tstamp = new Date().getTime();
|
tstamp = new Date().getTime();
|
||||||
private interval: number;
|
private interval: NodeJS.Timeout;
|
||||||
|
|
||||||
constructor(private voiceService: VoiceService) { }
|
constructor(private voiceService: VoiceService) { }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -59,3 +59,6 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="versus-container" *ngIf="action && action.type === gameQueueTypes.versus">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
@ -50,4 +50,11 @@ h1,h3 {
|
||||||
animation: results 3s 1;
|
animation: results 3s 1;
|
||||||
background-color: $thg_yellow;
|
background-color: $thg_yellow;
|
||||||
color: black;
|
color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
.versus-container {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 100vh;
|
||||||
|
background-color: $thg_red;
|
||||||
}
|
}
|
||||||
|
|
@ -3,7 +3,7 @@ import { EventGameQueue, QueueTypes } from "../../../types/server-event";
|
||||||
import { Participant } from "../../../types/participant";
|
import { Participant } from "../../../types/participant";
|
||||||
import { ApiService } from "../../services/api.service";
|
import { ApiService } from "../../services/api.service";
|
||||||
import { Subject } from "rxjs";
|
import { Subject } from "rxjs";
|
||||||
import {map, takeUntil} from "rxjs/operators";
|
import {map, take, takeUntil} from "rxjs/operators";
|
||||||
import { Question } from "../../../types/question";
|
import { Question } from "../../../types/question";
|
||||||
import { getAudioPath } from "../../helper/tts.helper";
|
import { getAudioPath } from "../../helper/tts.helper";
|
||||||
import { PrizeDto } from "../../../types/prize.dto";
|
import { PrizeDto } from "../../../types/prize.dto";
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<div class="card rounded m-3 animate__animated" [ngClass]="{ 'small': small, 'shadow': shadow, 'transparent': transparent, 'banned': banned, 'animate__flipInY': small }">
|
<div *ngIf="participant" class="card rounded m-3 animate__animated" [ngClass]="{ 'small': small, 'shadow': shadow, 'transparent': transparent, 'banned': banned, 'animate__flipInY': small }">
|
||||||
<figure class="p-1" *ngIf="participant">
|
<figure class="p-1">
|
||||||
<img [src]="getImageUrl()" class="participant-photo img-fluid">
|
<img [src]="getImageUrl()" class="participant-photo img-fluid">
|
||||||
</figure>
|
</figure>
|
||||||
<div class="card-title">
|
<div class="card-title">
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@
|
||||||
|
|
||||||
.transparent {
|
.transparent {
|
||||||
background: inherit;
|
background: inherit;
|
||||||
|
max-width: 200px;
|
||||||
}
|
}
|
||||||
|
|
||||||
figure {
|
figure {
|
||||||
|
|
@ -66,7 +67,7 @@ figure {
|
||||||
}
|
}
|
||||||
|
|
||||||
.big {
|
.big {
|
||||||
font-size: 7em;
|
font-size: 3em;
|
||||||
color: $thg_green;
|
color: $thg_green;
|
||||||
|
|
||||||
transition-delay: 2s;
|
transition-delay: 2s;
|
||||||
|
|
|
||||||
|
|
@ -4,9 +4,9 @@ import { EventService } from "../../services/event.service";
|
||||||
import { Observable, Subject, Subscription } from "rxjs";
|
import { Observable, Subject, Subscription } from "rxjs";
|
||||||
import { filter, map, takeUntil } from "rxjs/operators";
|
import { filter, map, takeUntil } from "rxjs/operators";
|
||||||
import { EventCardPlayed, EventCardsChanged, EventPhotosUpdated, ServerEvent } from "../../../types/server-event";
|
import { EventCardPlayed, EventCardsChanged, EventPhotosUpdated, ServerEvent } from "../../../types/server-event";
|
||||||
import { API_URL } from "../../../app.constants";
|
|
||||||
import { ApiService } from "../../services/api.service";
|
import { ApiService } from "../../services/api.service";
|
||||||
import { CardItem } from "../../../types/card-item";
|
import { CardItem } from "../../../types/card-item";
|
||||||
|
import {environment} from "../../../environments/environment";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-participant-item',
|
selector: 'app-participant-item',
|
||||||
|
|
@ -74,7 +74,7 @@ export class ParticipantItemComponent implements OnInit, OnDestroy, OnChanges {
|
||||||
|
|
||||||
getImageUrl() {
|
getImageUrl() {
|
||||||
if(this.participant) {
|
if(this.participant) {
|
||||||
return `${API_URL}/guests/photo/${this.participant.telegramId}?$t=${this.imgTimestamp}`;
|
return `${environment.API_URL}/guests/photo/${this.participant.telegramId}?$t=${this.imgTimestamp}`;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,10 @@
|
||||||
import { API_URL } from "../../app.constants";
|
import {environment} from "../../environments/environment";
|
||||||
|
|
||||||
|
|
||||||
export function getAudioPath(text: string, voice: number = 1) {
|
export function getAudioPath(text: string, voice: number = 1) {
|
||||||
return `${API_URL}/voice/tts?text=${text}&voice=${voice}`;
|
return `${environment.API_URL}/voice/tts?text=${text}&voice=${voice}`;
|
||||||
}
|
}
|
||||||
export function getAudioPathWithTemplate(path: string, text: string, vars: { [index: string]: string }) {
|
export function getAudioPathWithTemplate(path: string, text: string, vars: { [index: string]: string }) {
|
||||||
const t = new Date().getTime();
|
const t = new Date().getTime();
|
||||||
return `${API_URL}/voice/${path}?text=${text}&vars=${JSON.stringify(vars)}&t=${t}`;
|
return `${environment.API_URL}/voice/${path}?text=${text}&vars=${JSON.stringify(vars)}&t=${t}`;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { HttpClient } from "@angular/common/http";
|
import { HttpClient } from "@angular/common/http";
|
||||||
import { Observable } from "rxjs";
|
import { Observable } from "rxjs";
|
||||||
import { API_URL } from "../../app.constants";
|
|
||||||
import { AppState } from "../../types/app-state";
|
import { AppState } from "../../types/app-state";
|
||||||
import { Participant } from "../../types/participant";
|
import { Participant } from "../../types/participant";
|
||||||
import { Question } from "../../types/question";
|
import { Question } from "../../types/question";
|
||||||
|
|
@ -12,6 +11,7 @@ import { PrizeDto } from "../../types/prize.dto";
|
||||||
import {QuestionresultsDto} from "../../types/questionresults.dto";
|
import {QuestionresultsDto} from "../../types/questionresults.dto";
|
||||||
import {map} from "rxjs/operators";
|
import {map} from "rxjs/operators";
|
||||||
import {VersusItem} from "../../types/versus-item";
|
import {VersusItem} from "../../types/versus-item";
|
||||||
|
import {environment} from "../../environments/environment";
|
||||||
|
|
||||||
export class FeatureFlagStateDto {
|
export class FeatureFlagStateDto {
|
||||||
name: string;
|
name: string;
|
||||||
|
|
@ -57,83 +57,90 @@ export interface EndgameResultsDto {
|
||||||
})
|
})
|
||||||
export class ApiService {
|
export class ApiService {
|
||||||
|
|
||||||
constructor(private httpClient: HttpClient) { }
|
constructor(private httpClient: HttpClient) {
|
||||||
|
console.log(environment.API_URL);
|
||||||
|
}
|
||||||
|
|
||||||
public getAppState(state: string): Observable<AppState> {
|
public getAppState(state: string): Observable<AppState> {
|
||||||
return this.httpClient.get<AppState>(`${API_URL}/state/${state}`);
|
return this.httpClient.get<AppState>(`${environment.API_URL}/state/${state}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
public getParticipants(): Observable<Participant[]> {
|
public getParticipants(): Observable<Participant[]> {
|
||||||
return this.httpClient.get<Participant[]>(`${API_URL}/guests`);
|
return this.httpClient.get<Participant[]>(`${environment.API_URL}/guests`);
|
||||||
}
|
}
|
||||||
|
|
||||||
public getParticipant(id: number): Observable<Participant> {
|
public getParticipant(id: number): Observable<Participant> {
|
||||||
return this.httpClient.get<Participant>(`${API_URL}/guests/${id}`);
|
return this.httpClient.get<Participant>(`${environment.API_URL}/guests/${id}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
public getQuestion(): Observable<Question> {
|
public getQuestion(): Observable<Question> {
|
||||||
return this.httpClient.get<Question>(`${API_URL}/quiz`);
|
return this.httpClient.get<Question>(`${environment.API_URL}/quiz`);
|
||||||
}
|
}
|
||||||
|
|
||||||
public setAppState(state: string, value: string) {
|
public setAppState(state: string, value: string) {
|
||||||
return this.httpClient.post<AppState>(`${API_URL}/state`, {
|
return this.httpClient.post<AppState>(`${environment.API_URL}/state`, {
|
||||||
state,
|
state,
|
||||||
value
|
value
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getCards(telegramId: number): Observable<CardItem[]> {
|
getCards(telegramId: number): Observable<CardItem[]> {
|
||||||
return this.httpClient.get<CardItem[]>(`${API_URL}/cards/${telegramId}`);
|
return this.httpClient.get<CardItem[]>(`${environment.API_URL}/cards/${telegramId}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
continueGame() {
|
continueGame() {
|
||||||
console.log(`continue game`);
|
console.log(`continue game`);
|
||||||
return this.httpClient.post(`${API_URL}/quiz/proceed`, {});
|
return this.httpClient.post(`${environment.API_URL}/quiz/proceed`, {});
|
||||||
|
}
|
||||||
|
|
||||||
|
questionTimeout() {
|
||||||
|
console.log(`continue game`);
|
||||||
|
return this.httpClient.post(`${environment.API_URL}/quiz/timeout`, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
markQueueAsCompleted(_id: string) {
|
markQueueAsCompleted(_id: string) {
|
||||||
return this.httpClient.post(`${API_URL}/game/${_id}/complete`, {});
|
return this.httpClient.post(`${environment.API_URL}/game/${_id}/complete`, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
pauseGame() {
|
pauseGame() {
|
||||||
return this.httpClient.post(`${API_URL}/game/pause`, {});
|
return this.httpClient.post(`${environment.API_URL}/game/pause`, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
resumeGame() {
|
resumeGame() {
|
||||||
return this.httpClient.post(`${API_URL}/game/resume`, {});
|
return this.httpClient.post(`${environment.API_URL}/game/resume`, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
getGameState() {
|
getGameState() {
|
||||||
return this.httpClient.get<GameState>(`${API_URL}/game/state`);
|
return this.httpClient.get<GameState>(`${environment.API_URL}/game/state`);
|
||||||
}
|
}
|
||||||
|
|
||||||
getPenalty() {
|
getPenalty() {
|
||||||
console.log(`get penalty`);
|
console.log(`get penalty`);
|
||||||
return this.httpClient.get<PenaltyDto>(`${API_URL}/penalty`);
|
return this.httpClient.get<PenaltyDto>(`${environment.API_URL}/penalty`);
|
||||||
}
|
}
|
||||||
|
|
||||||
playExtraCards() {
|
playExtraCards() {
|
||||||
console.log(`play extra cards`);
|
console.log(`play extra cards`);
|
||||||
return this.httpClient.get(`${API_URL}/game/playextracards`);
|
return this.httpClient.get(`${environment.API_URL}/game/playextracards`);
|
||||||
}
|
}
|
||||||
|
|
||||||
getAdditionalQuestion(target: number) {
|
getAdditionalQuestion(target: number) {
|
||||||
return this.httpClient.post<Question>(`${API_URL}/quiz/extraquestion`, {
|
return this.httpClient.post<Question>(`${environment.API_URL}/quiz/extraquestion`, {
|
||||||
telegramId: target,
|
telegramId: target,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getImageUrl(id: number) {
|
getImageUrl(id: number) {
|
||||||
const timestamp = new Date().getTime();
|
const timestamp = new Date().getTime();
|
||||||
return `${API_URL}/guests/photo/${id}?$t=${timestamp}}`;
|
return `${environment.API_URL}/guests/photo/${id}?$t=${timestamp}}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
getPrize(): Observable<PrizeDto> {
|
getPrize(): Observable<PrizeDto> {
|
||||||
return this.httpClient.get<PrizeDto>(`${API_URL}/gifts`);
|
return this.httpClient.get<PrizeDto>(`${environment.API_URL}/gifts`);
|
||||||
}
|
}
|
||||||
|
|
||||||
getQuestionResults() {
|
getQuestionResults() {
|
||||||
return this.httpClient.get<QuestionresultsDto[]>(`${API_URL}/quiz/question-results`).pipe(map((data) =>
|
return this.httpClient.get<QuestionresultsDto[]>(`${environment.API_URL}/quiz/question-results`).pipe(map((data) =>
|
||||||
data.map((item) => {
|
data.map((item) => {
|
||||||
return {
|
return {
|
||||||
...item,
|
...item,
|
||||||
|
|
@ -144,29 +151,29 @@ export class ApiService {
|
||||||
}
|
}
|
||||||
|
|
||||||
getFeatureFlagState(feature: string) {
|
getFeatureFlagState(feature: string) {
|
||||||
return this.httpClient.get<FeatureFlagStateDto>(`${API_URL}/featureflag/${feature}`);
|
return this.httpClient.get<FeatureFlagStateDto>(`${environment.API_URL}/featureflag/${feature}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
setFeatureFlagState(feature: string, state: boolean) {
|
setFeatureFlagState(feature: string, state: boolean) {
|
||||||
return this.httpClient.post<FeatureFlagStateDto>(`${API_URL}/featureflag`, { name: feature, state: state });
|
return this.httpClient.post<FeatureFlagStateDto>(`${environment.API_URL}/featureflag`, { name: feature, state: state });
|
||||||
}
|
}
|
||||||
|
|
||||||
getStateDetails() {
|
getStateDetails() {
|
||||||
return this.httpClient.get<ConfigRecordDto>(`${API_URL}/game/state-details`);
|
return this.httpClient.get<ConfigRecordDto>(`${environment.API_URL}/game/state-details`);
|
||||||
}
|
}
|
||||||
|
|
||||||
getVersus() {
|
getVersus() {
|
||||||
return this.httpClient.get<VersusItem>(`${API_URL}/versus`);
|
return this.httpClient.get<VersusItem>(`${environment.API_URL}/versus`);
|
||||||
}
|
}
|
||||||
|
|
||||||
completeVersus(winner: number, loser: number) {
|
completeVersus(winner: number, loser: number) {
|
||||||
return this.httpClient.post(`${API_URL}/versus/complete`, {
|
return this.httpClient.post(`${environment.API_URL}/versus/complete`, {
|
||||||
winner: winner,
|
winner: winner,
|
||||||
loser: loser
|
loser: loser
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getEndgameResults() {
|
getEndgameResults() {
|
||||||
return this.httpClient.get<EndgameResultsDto>(`${API_URL}/quiz/endgame-results`)
|
return this.httpClient.get<EndgameResultsDto>(`${environment.API_URL}/quiz/endgame-results`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import {HttpClient} from "@angular/common/http";
|
import {HttpClient} from "@angular/common/http";
|
||||||
import {API_URL} from "../../app.constants";
|
import {environment} from "../../environments/environment";
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
|
|
@ -10,26 +10,26 @@ export class TestingApiService {
|
||||||
constructor(private httpClient: HttpClient) { }
|
constructor(private httpClient: HttpClient) { }
|
||||||
|
|
||||||
public simulateVersus() {
|
public simulateVersus() {
|
||||||
return this.httpClient.post(`${API_URL}/versus/simulate-versus`, {});
|
return this.httpClient.post(`${environment.API_URL}/versus/simulate-versus`, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
resetAllVersusTasksAsIncompleted() {
|
resetAllVersusTasksAsIncompleted() {
|
||||||
return this.httpClient.post(`${API_URL}/versus/reset-all`, {});
|
return this.httpClient.post(`${environment.API_URL}/versus/reset-all`, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
resetAllPlayersScore() {
|
resetAllPlayersScore() {
|
||||||
return this.httpClient.post(`${API_URL}/guests/reset-score`, {});
|
return this.httpClient.post(`${environment.API_URL}/guests/reset-score`, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
clearGameQueue() {
|
clearGameQueue() {
|
||||||
return this.httpClient.post(`${API_URL}/game/clear-queue`, {});
|
return this.httpClient.post(`${environment.API_URL}/game/clear-queue`, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
simulateEndGamePoints() {
|
simulateEndGamePoints() {
|
||||||
return this.httpClient.post(`${API_URL}/quiz/calculate-endgame-extrapoints`, {})
|
return this.httpClient.post(`${environment.API_URL}/quiz/calculate-endgame-extrapoints`, {})
|
||||||
}
|
}
|
||||||
|
|
||||||
simulateValidAnswer() {
|
simulateValidAnswer() {
|
||||||
return this.httpClient.post(`${API_URL}/game/simulate-valid-answer`, {});
|
return this.httpClient.post(`${environment.API_URL}/game/simulate-valid-answer`, {});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { HttpClient, HttpHeaders, HttpParams } from "@angular/common/http";
|
import { HttpClient, HttpHeaders, HttpParams } from "@angular/common/http";
|
||||||
import { API_URL } from "../../app.constants";
|
|
||||||
import {delay, delayWhen, interval, Observable, of, Subject} from "rxjs";
|
import {delay, delayWhen, interval, Observable, of, Subject} from "rxjs";
|
||||||
import {ApiService} from "./api.service";
|
import {ApiService} from "./api.service";
|
||||||
import {takeUntil, tap} from "rxjs/operators";
|
import {takeUntil, tap} from "rxjs/operators";
|
||||||
import {SharedMethods} from "../shared/sharedmethods";
|
import {SharedMethods} from "../shared/sharedmethods";
|
||||||
|
import {environment} from "../../environments/environment";
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
|
|
@ -45,11 +45,11 @@ export class VoiceService {
|
||||||
}
|
}
|
||||||
|
|
||||||
getAudioUrl(text: string,voice: number = 1) {
|
getAudioUrl(text: string,voice: number = 1) {
|
||||||
return `${API_URL}/voice/tts?voice=${voice}&text=${text}`
|
return `${environment.API_URL}/voice/tts?voice=${voice}&text=${text}`
|
||||||
}
|
}
|
||||||
|
|
||||||
getAudioUrlSSML(text: string) {
|
getAudioUrlSSML(text: string) {
|
||||||
return `${API_URL}/voice/ssml?text=${encodeURI(text)}`
|
return `${environment.API_URL}/voice/ssml?text=${encodeURI(text)}`
|
||||||
}
|
}
|
||||||
|
|
||||||
audioEnded() {
|
audioEnded() {
|
||||||
|
|
|
||||||
|
|
@ -22,11 +22,11 @@
|
||||||
<p class="card-text">Если тебе требуется пояснять эту карточку - то игра не для тебя, налей себе алкоголь и побольше.</p>
|
<p class="card-text">Если тебе требуется пояснять эту карточку - то игра не для тебя, налей себе алкоголь и побольше.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card text-white bg-secondary mb-3" style="max-width: 18rem;" #shitCard>
|
<div class="card text-white bg-secondary mb-3" style="max-width: 18rem;" #versusCard>
|
||||||
<img src="../../../assets/cards/ShitCard.png" class="card-img-top" alt="...">
|
<img src="../../../assets/cards/VersusCard.png" class="card-img-top" alt="...">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h5 class="card-title">Говнокарта</h5>
|
<h5 class="card-title">Поединок</h5>
|
||||||
<p class="card-text">Можно подкинуть еще один вопрос игроку, который правильно ответил.</p>
|
<p class="card-text">Можно вызвать другого игрока на схватку 1 на 1 в мини-игре</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card text-white bg-success mb-3" style="max-width: 18rem;" #luckyCard>
|
<div class="card text-white bg-success mb-3" style="max-width: 18rem;" #luckyCard>
|
||||||
|
|
@ -54,7 +54,7 @@
|
||||||
<img src="../../../assets/cards/BanPlayer.png" class="card-img-top" alt="...">
|
<img src="../../../assets/cards/BanPlayer.png" class="card-img-top" alt="...">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h5 class="card-title">Заблокировать игрока</h5>
|
<h5 class="card-title">Заблокировать игрока</h5>
|
||||||
<p class="card-text">Запрещает игроку давать ответы в следующих двух раундах</p>
|
<p class="card-text">Запрещает игроку давать ответы в случайном количестве раундов</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ interface RuleItem {
|
||||||
export class OnboardingComponent implements OnInit, OnDestroy {
|
export class OnboardingComponent implements OnInit, OnDestroy {
|
||||||
@ViewChild('avoidPenaltyCard') private avoidPenaltyCardEl: ElementRef;
|
@ViewChild('avoidPenaltyCard') private avoidPenaltyCardEl: ElementRef;
|
||||||
@ViewChild('stolePrizeCard') private stolePrizeCardEl: ElementRef;
|
@ViewChild('stolePrizeCard') private stolePrizeCardEl: ElementRef;
|
||||||
@ViewChild('shitCard') private shitCardEl: ElementRef;
|
@ViewChild('versusCard') private versusCardEl: ElementRef;
|
||||||
@ViewChild('luckyCard') private luckyCardEl: ElementRef;
|
@ViewChild('luckyCard') private luckyCardEl: ElementRef;
|
||||||
@ViewChild('banPlayerCard') private banPlayerEl: ElementRef;
|
@ViewChild('banPlayerCard') private banPlayerEl: ElementRef;
|
||||||
@ViewChild('doubleTreasureCard') private doubleTreasureCardEl: ElementRef;
|
@ViewChild('doubleTreasureCard') private doubleTreasureCardEl: ElementRef;
|
||||||
|
|
@ -42,30 +42,26 @@ export class OnboardingComponent implements OnInit, OnDestroy {
|
||||||
{ text: 'Вопросы и ответы будут отображаться на экране и в Боте Благодарения.' },
|
{ text: 'Вопросы и ответы будут отображаться на экране и в Боте Благодарения.' },
|
||||||
{ text: 'Каждый игрок в начале игры имеет на руках 4 карты, набор карт определяется случайно. Описание карт ты найдешь ниже. После использования карты ты получаешь новую случайную карту.' },
|
{ text: 'Каждый игрок в начале игры имеет на руках 4 карты, набор карт определяется случайно. Описание карт ты найдешь ниже. После использования карты ты получаешь новую случайную карту.' },
|
||||||
{ text: 'На разыгрывание карты время ограничено, примерно 10 секунд.' },
|
{ text: 'На разыгрывание карты время ограничено, примерно 10 секунд.' },
|
||||||
{ text: 'Задача игрока - ответить правильно и быстрее других.' },
|
{ text: 'Вы долго просили оптимизировать геймплей для медленных и глупых, и мы это сделали!'},
|
||||||
{ text: 'Первый игрок, ответивший правильно, получает одно очко и шанс выиграть приз.' },
|
{ text: 'Задача игрока - ответить правильно и быстрее других, ну или хотя бы просто правильно в течение 20 секунд' },
|
||||||
{ text: 'Приз??? Какой приз?', screpa: true, voice: 2 },
|
{ text: 'Первый игрок, ответивший правильно, получает два очка' },
|
||||||
{ text: 'Я не думаю, что их мозгов хватит для получения призов', screpa: true, voice: 2 },
|
{ text: 'Все остальные, ответившие правильно, получают одно очко'},
|
||||||
{ text: 'А ты вообще кто такая?', hideWithoutVoice: true },
|
{ text: 'Иногда за неправильные ответы игроки будут получать наказания' },
|
||||||
{ text: 'Ах, да.. простите, забыла представиться, я - Скрепа по фамилии Духовная', screpa: true, voice: 2},
|
{ text: 'Некоторые карты можно разыграть в любой момент, для этого нужно выбрать соответсвующую команду в боте'},
|
||||||
{ text: 'И на кой ты нам нужна?', hideWithoutVoice: true },
|
|
||||||
{ text: 'Я тут, чтобы нарушать ход игры, и вообще тебя не спрашивали. ', screpa: true, voice: 2},
|
|
||||||
{ text: '[Ладно, ]В общем - чем больше правильных ответов - тем больше призов '},
|
|
||||||
{ text: 'Первый игрок, ответивший неправильно, получает наказание, и мы переходим к следующему вопросу' },
|
|
||||||
{ text: 'Избежать наказания можно только с помощью соотвествуещей карты, данную карту ты можешь сыграть перед озвучиванием наказания', action: () => {
|
{ text: 'Избежать наказания можно только с помощью соотвествуещей карты, данную карту ты можешь сыграть перед озвучиванием наказания', action: () => {
|
||||||
this.shakeCard(this.avoidPenaltyCardEl);
|
this.shakeCard(this.avoidPenaltyCardEl);
|
||||||
}},
|
}},
|
||||||
{ text: 'Карту "украсть приз" ты можешь сыграть в момент, когда кто-то собирается получить награду, но до момента того, как ты узнаешь, что это именно за приз', action: () => {
|
{ text: 'Карту "украсть приз" ты можешь сыграть в момент, когда кто-то собирается получить награду, но до момента того, как ты узнаешь, что это именно за приз', action: () => {
|
||||||
this.shakeCard(this.stolePrizeCardEl);
|
this.shakeCard(this.stolePrizeCardEl);
|
||||||
}},
|
}},
|
||||||
{ text: '"Говно-карту" ты можешь разыграть в момент, когда кто-то ответил правильно, тем самым ты заставишь именно этого игрока ответить на один дополнительный вопрос. На одного игрока можно сыграть неограниченное количество этих карт', action: () => {
|
{ text: 'Карту "Поединок" ты можешь разыграть в любой момент, чтобы вызвать игрока на дуэль', action: () => {
|
||||||
this.shakeCard(this.shitCardEl);
|
this.shakeCard(this.versusCardEl);
|
||||||
}},
|
}},
|
||||||
{ text: '"Лаки карту" ты сможешь сыграть после своего правильного ответа, она увеличит твои шансы на получение приза', action: () => {
|
{ text: '"Лаки карту" ты сможешь сыграть после своего правильного ответа, она увеличит твои шансы на получение приза', action: () => {
|
||||||
this.shakeCard(this.luckyCardEl);
|
this.shakeCard(this.luckyCardEl);
|
||||||
}},
|
}},
|
||||||
{
|
{
|
||||||
text: 'Карту бана можно сыграть на любого игрока (даже себя), чтобы отправить его на пару ходов во Владикавказ. Игрок не сможет участвовать в игре в течение двух раундов',
|
text: 'Карту бана можно сыграть на любого игрока (даже себя), чтобы отправить его на пару ходов во Владикавказ. Игрок не сможет участвовать в случайном количестве раундов',
|
||||||
action: () => {
|
action: () => {
|
||||||
this.shakeCard(this.banPlayerEl);
|
this.shakeCard(this.banPlayerEl);
|
||||||
}
|
}
|
||||||
|
|
@ -78,22 +74,10 @@ export class OnboardingComponent implements OnInit, OnDestroy {
|
||||||
},
|
},
|
||||||
{ text: 'Не торопись с ответами, игра идет до той поры, пока мы не разыграем все призы' },
|
{ text: 'Не торопись с ответами, игра идет до той поры, пока мы не разыграем все призы' },
|
||||||
{
|
{
|
||||||
text: 'Ах да, так как создатель игры, работает на Microsoft, мы добавили привычные вам баги, сейчас расскажу',
|
text: 'Ах да, так как создатель игры, работает на Microsoft, мы добавили привычные вам баги, но все их оставим в секрете',
|
||||||
screpa: true,
|
|
||||||
voice: 2
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: 'Если у вас нет вариантов ответа - перезайдите в бот или перезапустите телеграмм',
|
text: 'Кажется, правила закончились'
|
||||||
screpa: true,
|
|
||||||
voice: 2,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'Остальные баги будут сюрпризом! Но не забывайте громко кричать, когда что-то работает не так',
|
|
||||||
screpa: true,
|
|
||||||
voice: 2,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'Кажется правила закончились'
|
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
@ -172,7 +156,7 @@ export class OnboardingComponent implements OnInit, OnDestroy {
|
||||||
this.allRulesAnnounced = true;
|
this.allRulesAnnounced = true;
|
||||||
this.voiceService.playAudio(getAudioPath(`Это все правила, надеюсь, все понятно. А если нет - сейчас Кирилл и Оксана вам все пояснят,
|
this.voiceService.playAudio(getAudioPath(`Это все правила, надеюсь, все понятно. А если нет - сейчас Кирилл и Оксана вам все пояснят,
|
||||||
ну и совсем для тупых - пустила по кругу правила на экране,
|
ну и совсем для тупых - пустила по кругу правила на экране,
|
||||||
а если ты их не поймешь - то за Путина голосовать пойдешь (или за Грузинскую мечту) . Каждый правильный ответ отнимает у Путина год жизни, постарайтесь!`));
|
а если ты их не поймешь - то очень жаль тебя глупенького`));
|
||||||
this.voiceService.audioEndedSubject.pipe(takeUntil(this.destroyed$),take(1)).subscribe(() => {
|
this.voiceService.audioEndedSubject.pipe(takeUntil(this.destroyed$),take(1)).subscribe(() => {
|
||||||
setInterval(() => { this.playNextRule() }, 6000);
|
setInterval(() => { this.playNextRule() }, 6000);
|
||||||
this.currentRulePosition = 0
|
this.currentRulePosition = 0
|
||||||
|
|
|
||||||
|
|
@ -17,15 +17,16 @@ export class RegisterComponent implements OnInit {
|
||||||
playWelcome() {
|
playWelcome() {
|
||||||
const url = this.voiceService.getAudioUrlSSML(`<speak>
|
const url = this.voiceService.getAudioUrlSSML(`<speak>
|
||||||
Гамарджоба, дорогие друзья! Спасибо, что вы в этот вечер с нами!<break time="1s"/>
|
Гамарджоба, дорогие друзья! Спасибо, что вы в этот вечер с нами!<break time="1s"/>
|
||||||
Кто-то меня уже помнит, а для новеньких представлюсь: меня зовут Нино Алкошвили, и сегодня я буду вести эту игру.
|
Кто-то меня уже помнит, а для новеньких представлюсь: меня зовут Нино Алкошвили, и вот уже в седьмой раз я буду вести эту игру.
|
||||||
<break time="1s"/>вай-мээ!
|
|
||||||
Хочу предупредить, что я уже бахнула вина, поэтому за юмор простите.
|
|
||||||
Настало время зарегистрироваться! <break time="1s" />
|
Настало время зарегистрироваться! <break time="1s" />
|
||||||
Доставай свой телефон <break time="1s" /> и, я надеюсь, у тебя есть телеграм?<break time="1s" /><break time="2s" />
|
Для новоприбывших расскажу как тут все работает, мы играем в игру, используем для этого глаза направленные в телевизор и пальцы гладящие сенсорные поверности
|
||||||
Достал?<break time="1s" />
|
ваших смарт устройств с установленным приложением Телеграм
|
||||||
Тогда сканируй кью ар код с индюшкой и проходи простую регистрацию, надеюсь, твоих мозгов на это хватит? ха-ха<break time="1s"/>
|
Чтобы начать тебе надо отсканировать кью ар код с индюшкой и понажимать там несколько кнопочек.
|
||||||
<break time="2s" />
|
<break time="2s" />
|
||||||
Кстати, кто проиграет - будет мыть посуду, а кто умненький - заберет много призов!
|
Кстати, кто проиграет - будет мыть посуду, а кто умненький - заберет много призов!
|
||||||
|
<break time="2s" />
|
||||||
|
Мы тут считаем, что хороший юмор это залог успешной жизни, но иногда можем выходить за рамки - поэтому просто простите,
|
||||||
|
если вы обиделись, рекомендуем вам пересмотреть взгляды на свою жизнь если вас такие пустяки задевают.
|
||||||
</speak>`);
|
</speak>`);
|
||||||
|
|
||||||
this.voiceService.playAudio(url)
|
this.voiceService.playAudio(url)
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
export const environment = {
|
export const environment = {
|
||||||
production: true
|
production: true,
|
||||||
|
API_URL: "https://thanksgiving2024.ngweb.io/api",
|
||||||
|
WEBSOCK_URL: "https://thanksgiving2024.ngweb.io"
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,9 @@
|
||||||
// The list of file replacements can be found in `angular.json`.
|
// The list of file replacements can be found in `angular.json`.
|
||||||
|
|
||||||
export const environment = {
|
export const environment = {
|
||||||
production: false
|
production: false,
|
||||||
|
API_URL: "http://localhost:3000",
|
||||||
|
WEBSOCK_URL: "http://localhost:3000"
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ export enum QueueTypes {
|
||||||
playExtraCard = 'play_extra_card',
|
playExtraCard = 'play_extra_card',
|
||||||
screpa = 'screpa',
|
screpa = 'screpa',
|
||||||
showresults = 'show_results',
|
showresults = 'show_results',
|
||||||
|
versus = 'versus',
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface EventPhotosUpdated {
|
export interface EventPhotosUpdated {
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
"extends": "./tsconfig.json",
|
"extends": "./tsconfig.json",
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"outDir": "./out-tsc/app",
|
"outDir": "./out-tsc/app",
|
||||||
"types": []
|
"types": ["node"]
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"src/main.ts",
|
"src/main.ts",
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue