src/users-new/Presence.ts
import {concat, defer, Observable} from 'rxjs';
import {filter, first, map, shareReplay, mergeMap} from 'rxjs/operators';
import {PresenceService} from '../wac-proxy/wac-stack/presence/PresenceService';
import {PresenceActivity} from './PresenceActivity';
import {PresenceMood} from './PresenceMood';
export type PresenceState = Readonly<{
online: boolean;
activity: PresenceActivity;
mood: PresenceMood;
note: string;
avatar: string;
displayName: string;
}>;
export class Presence {
readonly state$: Observable<PresenceState>;
private presenceService: PresenceService;
private ownId: string;
constructor(
presenceService: PresenceService,
ownId: string,
) {
this.presenceService = presenceService;
this.ownId = ownId;
const initial$ = defer(() => this.presenceService.subscribeToPresence$(this.ownId));
const updates$ = defer(() => this.presenceService.event$).pipe(
map(event => event.body),
filter(presence => presence.address === this.ownId),
);
this.state$ = concat(initial$, updates$).pipe(
map(presenceDto => ({
online: presenceDto.online,
activity: presenceDto.activity,
mood: presenceDto.mood,
note: presenceDto.note,
avatar: presenceDto.avatar,
displayName: presenceDto.displayName,
})),
shareReplay(1),
);
}
update(presence: Partial<PresenceState>): Observable<void> {
return this.state$.pipe(
first(),
mergeMap(currentState => this.presenceService.update$(this.ownId, {...currentState, ...presence})),
map(() => undefined),
);
}
}