import { Injectable } from '@angular/core'; import { Observable, Subject } from 'rxjs'; import { map, take, takeWhile, share, tap, filter } from 'rxjs/operators'; import { ProtocolService } from '@ucap-webmessenger/protocol'; import { SVC_TYPE_ROOM, SSVC_TYPE_ROOM_OPEN_REQ, SSVC_TYPE_ROOM_OPEN2_REQ, SSVC_TYPE_ROOM_OPEN3_REQ, SSVC_TYPE_ROOM_OPEN4_REQ, SSVC_TYPE_ROOM_INVITE_REQ, SSVC_TYPE_ROOM_INFO_ROOM, SSVC_TYPE_ROOM_INFO_RES, SSVC_TYPE_ROOM_INFO_REQ, SSVC_TYPE_ROOM_INFO_USER, SSVC_TYPE_ROOM_INFO_USER2, SSVC_TYPE_ROOM_EXIT_REQ, SSVC_TYPE_ROOM_EXIT_ALL_REQ, SSVC_TYPE_ROOM_EXIT_FORCING_REQ, SSVC_TYPE_ROOM_USER_STATUS_REQ, SSVC_TYPE_ROOM_UPD_REQ, SSVC_TYPE_ROOM_INFO_UPD_REQ, SSVC_TYPE_ROOM_FONT_UPD_REQ, SSVC_TYPE_ROOM_INVITE_NOTI, SSVC_TYPE_ROOM_EXIT_NOTI, SSVC_TYPE_ROOM_EXIT_FORCING_NOTI, SSVC_TYPE_ROOM_FONT_UPD_NOTI } from '../types/service'; import { OpenRequest, encodeOpen, decodeOpen, OpenResponse, Open2Request, Open2Response, decodeOpen2, encodeOpen2, Open3Request, Open3Response, encodeOpen3, decodeOpen3, Open4Request, Open4Response, encodeOpen4, decodeOpen4 } from '../protocols/open'; import { InviteRequest, InviteResponse, encodeInvite, decodeInvite, decodeInviteNotification, InviteNotification } from '../protocols/invite'; import { InfoRequest, InfoResponse, InfoData, UserShortData, UserData, encodeInfo, decodeInfoData, decodeInfo, decodeUserShortData, decodeUserData, UserStatusOfflineRequest, UserStatusOfflineResponse, encodeUserStatusOffline, decodeUserStatusOffline } from '../protocols/info'; import { ExitRequest, ExitResponse, encodeExit, decodeExit, ExitAllRequest, encodeAllExit, ExitForcingRequest, ExitForcingResponse, encodeExitForcing, decodeExitForcing, decodeAllExit, ExitAllResponse, decodeExitForcingNotification, decodeExitNotification, ExitNotification, ExitForcingNotification } from '../protocols/exit'; import { UpdateRequest, UpdateResponse, encodeUpdate, decodeUpdate, UpdateTimerSetRequest, UpdateTimerSetResponse, encodeUpdateTimerSet, decodeUpdateTimerSet, UpdateFontRequest, UpdateFontResponse, encodeUpdateFont, decodeUpdateFont, decodeUpdateFontNotification, UpdateFontNotification } from '../protocols/update'; type Notifications = | UpdateFontNotification | InviteNotification | ExitNotification | ExitForcingNotification; @Injectable({ providedIn: 'root' }) export class RoomProtocolService { private notificationSubject: Subject; public notification$: Observable; constructor(private protocolService: ProtocolService) { this.notificationSubject = new Subject(); this.notification$ = this.notificationSubject.asObservable().pipe(share()); this.protocolService.serverMessage .pipe( filter(message => message.serviceType === SVC_TYPE_ROOM), tap(message => { switch (message.subServiceType) { case SSVC_TYPE_ROOM_INVITE_NOTI: { this.notificationSubject.next({ ...decodeInviteNotification(message), Type: SSVC_TYPE_ROOM_INVITE_NOTI }); } break; case SSVC_TYPE_ROOM_EXIT_NOTI: { this.notificationSubject.next({ ...decodeExitNotification(message), Type: SSVC_TYPE_ROOM_EXIT_NOTI }); } break; case SSVC_TYPE_ROOM_EXIT_FORCING_NOTI: { this.notificationSubject.next({ ...decodeExitForcingNotification(message), Type: SSVC_TYPE_ROOM_EXIT_FORCING_NOTI }); } break; case SSVC_TYPE_ROOM_FONT_UPD_NOTI: { this.notificationSubject.next({ ...decodeUpdateFontNotification(message), Type: SSVC_TYPE_ROOM_FONT_UPD_NOTI }); } break; default: break; } }) ) .subscribe(); } public open(req: OpenRequest): Observable { return this.protocolService .call(SVC_TYPE_ROOM, SSVC_TYPE_ROOM_OPEN_REQ, ...encodeOpen(req)) .pipe( take(1), map(res => decodeOpen(res)) ); } public open2(req: Open2Request): Observable { return this.protocolService .call(SVC_TYPE_ROOM, SSVC_TYPE_ROOM_OPEN2_REQ, ...encodeOpen2(req)) .pipe( take(1), map(res => decodeOpen2(res)) ); } public open3(req: Open3Request): Observable { return this.protocolService .call(SVC_TYPE_ROOM, SSVC_TYPE_ROOM_OPEN3_REQ, ...encodeOpen3(req)) .pipe( take(1), map(res => decodeOpen3(res)) ); } public open4(req: Open4Request): Observable { return this.protocolService .call(SVC_TYPE_ROOM, SSVC_TYPE_ROOM_OPEN4_REQ, ...encodeOpen4(req)) .pipe( take(1), map(res => decodeOpen4(res)) ); } public invite(req: InviteRequest): Observable { return this.protocolService .call(SVC_TYPE_ROOM, SSVC_TYPE_ROOM_INVITE_REQ, ...encodeInvite(req)) .pipe( take(1), map(res => decodeInvite(res)) ); } public info( req: InfoRequest ): Observable { return this.protocolService .call(SVC_TYPE_ROOM, SSVC_TYPE_ROOM_INFO_REQ, ...encodeInfo(req)) .pipe( takeWhile(res => SSVC_TYPE_ROOM_INFO_RES !== res.subServiceType, true), map(res => { if (SSVC_TYPE_ROOM_INFO_ROOM === res.subServiceType) { return { ...decodeInfoData(res), Type: SSVC_TYPE_ROOM_INFO_ROOM }; } else if (SSVC_TYPE_ROOM_INFO_USER === res.subServiceType) { return { ...decodeUserShortData(res), Type: SSVC_TYPE_ROOM_INFO_USER }; } else if (SSVC_TYPE_ROOM_INFO_USER2 === res.subServiceType) { return { ...decodeUserData(res), Type: SSVC_TYPE_ROOM_INFO_USER2 }; } return { ...decodeInfo(res), Type: SSVC_TYPE_ROOM_INFO_RES }; }) ); } public userStatusOffline( req: UserStatusOfflineRequest ): Observable { return this.protocolService .call( SVC_TYPE_ROOM, SSVC_TYPE_ROOM_USER_STATUS_REQ, ...encodeUserStatusOffline(req) ) .pipe( take(1), map(res => { return decodeUserStatusOffline(res); }) ); } public exit(req: ExitRequest): Observable { return this.protocolService .call(SVC_TYPE_ROOM, SSVC_TYPE_ROOM_EXIT_REQ, ...encodeExit(req)) .pipe( take(1), map(res => { return decodeExit(res); }) ); } public exitAll(req: ExitAllRequest): Observable { return this.protocolService .call(SVC_TYPE_ROOM, SSVC_TYPE_ROOM_EXIT_ALL_REQ, ...encodeAllExit(req)) .pipe( take(1), map(res => { return decodeAllExit(res); }) ); } public exitForcing(req: ExitForcingRequest): Observable { return this.protocolService .call( SVC_TYPE_ROOM, SSVC_TYPE_ROOM_EXIT_FORCING_REQ, ...encodeExitForcing(req) ) .pipe( take(1), map(res => { return decodeExitForcing(res); }) ); } public update(req: UpdateRequest): Observable { return this.protocolService .call(SVC_TYPE_ROOM, SSVC_TYPE_ROOM_UPD_REQ, ...encodeUpdate(req)) .pipe( take(1), map(res => { return decodeUpdate(res); }) ); } public updateTimerSet( req: UpdateTimerSetRequest ): Observable { return this.protocolService .call( SVC_TYPE_ROOM, SSVC_TYPE_ROOM_INFO_UPD_REQ, ...encodeUpdateTimerSet(req) ) .pipe( take(1), map(res => { return decodeUpdateTimerSet(res); }) ); } public updateFont(req: UpdateFontRequest): Observable { return this.protocolService .call( SVC_TYPE_ROOM, SSVC_TYPE_ROOM_FONT_UPD_REQ, ...encodeUpdateFont(req) ) .pipe( take(1), map(res => { return decodeUpdateFont(res); }) ); } }