import { Injectable } from '@angular/core'; import { catchError, from, map, merge, mergeMap, Observable, throwError } from 'rxjs'; import { webSocket } from 'rxjs/webSocket'; import { Channel } from '../models/channel'; import { Message } from '../models/message'; import { HttpClient } from '@angular/common/http'; import { environment } from '../../environment/environment'; import { GetMessagesResponse, ListAvailableChannelsResponse, SendMessageResponse } from './responses/chat'; @Injectable({ providedIn: 'root' }) export class ChatService { private readonly CHANNEL: string = "channel_id"; private readonly CONTENT: string = "content"; constructor(private http: HttpClient) { } public ListAvailableChannels(): Observable { let url = `${environment.apiBase}/chat/channels` return this.http.get(url, { withCredentials: true }) .pipe( map(response => { if (response.error) { throw new Error(response.error); } if (response.channels) { return response.channels; } throw new Error("bad API response, missing channels with no error"); }), catchError(error => throwError(() => new Error(error.error.message))) ); } public GetMessages(channelID: number): Observable { let url = `${environment.apiBase}/chat/messages/${channelID}`; let messages: Observable = this.http.get(url, { withCredentials: true }) .pipe( map(response => { if (response.error) { throw new Error(response.error); } if (response.messages) { return response.messages; } throw new Error("bad API response, missing messages with no error"); }), catchError(error => throwError(() => new Error(error.error.message))) ); url = `${environment.apiBase}/chat/subscribe/${channelID}`; let socket = webSocket(url); return merge( messages.pipe(mergeMap(msgArray => from(msgArray))), socket.asObservable()); } public SendMessage(channel: number, content: string): Observable { let url = `${environment.apiBase}/chat/send`; let data = new FormData(); data.append(this.CHANNEL, channel.toString()); data.append(this.CONTENT, content); return this.http.post(url, data, { withCredentials: true }) .pipe( map(response => { if (response.error) { throw new Error(response.error); } return response; }), catchError(error => throwError(() => new Error(error.error.message))) ); } }