44 lines
1.3 KiB
TypeScript
44 lines
1.3 KiB
TypeScript
|
|
import { Injectable } from '@angular/core';
|
||
|
|
|
||
|
|
import { MissionSnapshot } from '@fog-explorer/api-interfaces';
|
||
|
|
|
||
|
|
import { MissionStateStore } from './mission-state.store';
|
||
|
|
import { TwitchAuthService } from './twitch-auth.service';
|
||
|
|
|
||
|
|
interface MissionDeltaMessage {
|
||
|
|
sequence: number;
|
||
|
|
missionId: string;
|
||
|
|
state: string;
|
||
|
|
recentLog: MissionSnapshot['recentLog'];
|
||
|
|
}
|
||
|
|
|
||
|
|
@Injectable({ providedIn: 'root' })
|
||
|
|
export class PubSubService {
|
||
|
|
private lastSequence = 0;
|
||
|
|
|
||
|
|
constructor(
|
||
|
|
private readonly auth: TwitchAuthService,
|
||
|
|
private readonly store: MissionStateStore
|
||
|
|
) {}
|
||
|
|
|
||
|
|
subscribeToMissionUpdates(topic: string, fullRefetch: () => Promise<void>): void {
|
||
|
|
this.auth.onPubSub(topic, async (_target, _contentType, message) => {
|
||
|
|
const parsed = JSON.parse(message) as MissionDeltaMessage;
|
||
|
|
if (parsed.sequence !== this.lastSequence + 1 && this.lastSequence !== 0) {
|
||
|
|
await fullRefetch();
|
||
|
|
} else {
|
||
|
|
const current = this.store.mission();
|
||
|
|
if (current && current.id === parsed.missionId) {
|
||
|
|
this.store.setMission({
|
||
|
|
...current,
|
||
|
|
state: parsed.state as MissionSnapshot['state'],
|
||
|
|
recentLog: parsed.recentLog.slice(-15),
|
||
|
|
tickIndex: parsed.sequence
|
||
|
|
});
|
||
|
|
}
|
||
|
|
}
|
||
|
|
this.lastSequence = parsed.sequence;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
}
|