add attendance
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { BehaviorSubject, Observable } from 'rxjs';
|
||||
import {
|
||||
HubConnection, HubConnectionBuilder, HubConnectionState, LogLevel,
|
||||
} from '@microsoft/signalr';
|
||||
import { environment } from '../../../../environments/environment';
|
||||
import { AttendanceCounts, AttendanceCategory } from '../models/attendance.model';
|
||||
|
||||
/**
|
||||
* Thin wrapper around the AttendanceHub SignalR connection. Exposes the latest
|
||||
* authoritative counts as an observable and a fire-and-forget increment() that
|
||||
* sends a batched delta to the server. The server broadcasts the new totals
|
||||
* back to every connected client.
|
||||
*/
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class AttendanceSignalrService {
|
||||
// Hub lives at the host root; environment.apiUrl is e.g. http://localhost:42019/api
|
||||
private readonly hubUrl = environment.apiUrl.replace(/\/api\/?$/, '') + '/hubs/attendance';
|
||||
|
||||
private connection?: HubConnection;
|
||||
private readonly counts$$ = new BehaviorSubject<AttendanceCounts | null>(null);
|
||||
|
||||
/** Latest authoritative counts pushed by the server (null until first message). */
|
||||
get counts$(): Observable<AttendanceCounts | null> {
|
||||
return this.counts$$.asObservable();
|
||||
}
|
||||
|
||||
async start(): Promise<void> {
|
||||
if (this.connection) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.connection = new HubConnectionBuilder()
|
||||
.withUrl(this.hubUrl)
|
||||
.withAutomaticReconnect()
|
||||
.configureLogging(LogLevel.Warning)
|
||||
.build();
|
||||
|
||||
this.connection.on('ReceiveCounts', (counts: AttendanceCounts) => {
|
||||
this.counts$$.next(counts);
|
||||
});
|
||||
|
||||
await this.connection.start();
|
||||
}
|
||||
|
||||
async stop(): Promise<void> {
|
||||
if (this.connection) {
|
||||
await this.connection.stop();
|
||||
this.connection = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
/** Send a batched delta (may be negative) for one age group. */
|
||||
async increment(category: AttendanceCategory, delta: number): Promise<void> {
|
||||
if (delta === 0 || this.connection?.state !== HubConnectionState.Connected) {
|
||||
return;
|
||||
}
|
||||
await this.connection.invoke('Increment', category, delta);
|
||||
}
|
||||
|
||||
/** Overwrite one age group with an absolute value (clamped at zero server-side). */
|
||||
async setCount(category: AttendanceCategory, value: number): Promise<void> {
|
||||
if (this.connection?.state !== HubConnectionState.Connected) {
|
||||
throw new Error('Not connected to the attendance hub.');
|
||||
}
|
||||
await this.connection.invoke('SetCount', category, value);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user