|
1 | 1 | import { Injectable } from '@nestjs/common';
|
| 2 | +import { events, questions } from './constants'; |
| 3 | + |
| 4 | +interface Client { |
| 5 | + subscribedEvent: string; |
| 6 | + callback: (data: any) => void; |
| 7 | +} |
2 | 8 |
|
3 | 9 | @Injectable()
|
4 | 10 | export class EventsService {
|
5 |
| - private clients: Array<(data: any) => void> = []; |
6 |
| - private data: any = { action: null }; |
| 11 | + private clients: Client[] = []; |
| 12 | + private currentActions: Record<string, any> = events.reduce( |
| 13 | + (acc, event) => ({ ...acc, [event.name]: { action: null } }), |
| 14 | + {}, |
| 15 | + ); |
7 | 16 |
|
8 | 17 | constructor() {
|
9 |
| - this.scheduleNewAction(); |
| 18 | + events.forEach((event) => this.scheduleNewAction(event.name)); |
10 | 19 | }
|
11 | 20 |
|
12 |
| - addClient(client: (data: any) => void) { |
| 21 | + addClient(client: Client) { |
13 | 22 | this.clients.push(client);
|
14 | 23 | }
|
15 | 24 |
|
16 |
| - removeClient(client: (data: any) => void) { |
17 |
| - this.clients = this.clients.filter((c) => c !== client); |
18 |
| - } |
| 25 | + notifyClients(event: string) { |
| 26 | + // Notify all clients subscribed to the event |
| 27 | + this.clients |
| 28 | + .filter((client) => client.subscribedEvent === event) |
| 29 | + .forEach((client) => client.callback(this.currentActions[event])); |
19 | 30 |
|
20 |
| - notifyClients() { |
21 |
| - this.clients.forEach((c) => c(this.data)); |
22 |
| - this.clients = []; |
| 31 | + // Remove clients subscribed to the event |
| 32 | + this.clients = this.clients.filter( |
| 33 | + (client) => client.subscribedEvent !== event, |
| 34 | + ); |
23 | 35 | }
|
24 | 36 |
|
25 |
| - scheduleNewAction() { |
26 |
| - const actions = ['flashlight', 'vote']; |
27 |
| - const selectedAction = actions[Math.floor(Math.random() * actions.length)]; |
28 |
| - const delay = Math.floor(Math.random() * 15000) + 5000; // 5-20 seconds |
| 37 | + scheduleNewAction(event: string) { |
| 38 | + const availableActions = events.find( |
| 39 | + (e) => e.name === event, |
| 40 | + ).availableActions; |
| 41 | + const selectedAction = |
| 42 | + availableActions[Math.floor(Math.random() * availableActions.length)]; |
| 43 | + const delay = Math.floor(Math.random() * 15000) + 15000; // 15-30 seconds |
29 | 44 |
|
30 | 45 | setTimeout(() => {
|
31 |
| - this.data = { action: selectedAction }; |
32 |
| - this.notifyClients(); |
| 46 | + if (selectedAction === 'flashlight') { |
| 47 | + this.currentActions[event] = { action: { type: 'flashlight' } }; |
| 48 | + } else if (selectedAction === 'vote') { |
| 49 | + const question = |
| 50 | + questions[Math.floor(Math.random() * questions.length)]; |
| 51 | + this.currentActions[event] = { action: { type: 'vote', ...question } }; |
| 52 | + } |
| 53 | + |
| 54 | + this.notifyClients(event); |
33 | 55 |
|
34 | 56 | setTimeout(
|
35 | 57 | () => {
|
36 |
| - this.data = { action: null }; |
37 |
| - this.notifyClients(); |
38 |
| - this.scheduleNewAction(); |
| 58 | + this.currentActions[event] = { action: null }; |
| 59 | + this.notifyClients(event); |
| 60 | + this.scheduleNewAction(event); |
39 | 61 | },
|
40 | 62 | selectedAction === 'flashlight' ? 5000 : 15000,
|
41 | 63 | );
|
42 | 64 | }, delay);
|
43 | 65 | }
|
44 | 66 |
|
45 |
| - getCurrentAction() { |
46 |
| - if (Object.keys(this.data).length > 0) return this.data; |
47 |
| - return { action: null }; |
| 67 | + getCurrentAction(event: string) { |
| 68 | + return this.currentActions[event]; |
48 | 69 | }
|
49 | 70 | }
|
0 commit comments