import {DatabaseAPI} from "../storage/database"; import {AxiosInstance, isAxiosError} from "axios"; import {MessageListener} from "../domain/websocket.schema"; import {getClient} from "../core/http"; import {WebSocketHandler} from "../core/webSocketHandler"; import { DeleteMessagesReq, EditMessageReq, FinishMessageReq, GetMessagePosResp, JoinWsRoomReq, Message, PinMessageReq, PinnedMessage, ReadMessagesReq, UnpinMessageReq } from "../domain/dmService.schema"; import {NetworkInvite} from "../domain/networkService.schema"; import {GenericErrorBody} from "../domain/http.schema"; import {FileData} from "../domain/fileUploadService.schema"; import {FileUploadService} from "./fileUploadService"; export class DMService { userid: string; chatid: string; token: string; database: DatabaseAPI; client: AxiosInstance constructor(userid: string, token: string, chatid: string, database: DatabaseAPI, wsMessageListener: MessageListener) { this.userid = userid; this.chatid = chatid; this.database = database; this.token = token; this.client = getClient(false).create({ headers: { "Authorization": token, "X-WS-ID": WebSocketHandler.getInstance().connId } }) WebSocketHandler.getInstance().registerService({ identifier: chatid, onNewConnId: this.onNewConnId, onNewMessage: wsMessageListener, }) } private onNewConnId(newConnId: string) { console.log("NetworkService: New connection id") this.client.defaults.headers["X-WS-ID"] = newConnId; } /** * Fetches all messages in the chat * @param from */ async get(from: number = 0): Promise { try { const resp = await this.client.get(`chat/dm/messages?chatid=${this.chatid}&userid=${this.userid}&from=${from}`); return resp.data } catch (e) { if (isAxiosError(e)) { throw e; } throw new Error("Unexpected error") } } /** * Fetches the position of the specified message which can be used in get() to fetch an old message with it's surrounding messages * @param messageId */ async getMessagePos(messageId: string): Promise { try { const resp = await this.client.get(`chat/dm/getMessagePosition?chatid=${this.chatid}&userid=${this.userid}&messageId=${messageId}`); return resp.data.messagePos } catch (e) { if (isAxiosError(e)) { throw e; } throw new Error("Unexpected error") } } /** * Gets all messages pinned in the chat */ async getPinnedMessages(): Promise { try { const resp = await this.client.get(`chat/dm/pinnedMessages?chatid=${this.chatid}&userid=${this.userid}`); return resp.data } catch (e) { if (isAxiosError(e)) { throw e; } throw new Error("Unexpected error") } } /** * Edits the specified message * @param messageId * @param newMessage */ async editMessage(messageId: string, newMessage: string): Promise { try { const resp = await this.client.patch("chat/dm/editMessage", { messageId: messageId, chatid: this.chatid, userid: this.userid, message: newMessage }); return resp.data } catch (e) { if (isAxiosError(e)) { throw e; } throw new Error("Unexpected error") } } /** * Sends a new message to the chat * @param message * @param replyTo * @param replyToMessage * @param attachments */ async sendMessage(message: string, replyTo: string | null = null, replyToMessage: string | null = null, attachments: FileData[] | null = null): Promise { let uploadId = "" if (attachments) { const uploader = new FileUploadService(this.token) uploadId = await uploader.uploadFiles(this.chatid, this.userid, attachments) } try { const resp = await this.client.post("chat/dm/finishMessage", { message: message, chatid: this.chatid, replyTo: replyTo, replyToMessage: replyToMessage, userid: this.userid, uploadId: uploadId, }); return resp.data } catch (e) { if (isAxiosError(e)) { throw e; } throw new Error("Unexpected error") } } /** * Reads all messages sent to you in the chat */ async readMessages(): Promise { try { await this.client.patch("chat/dm/readMessages", { chatid: this.chatid, userid: this.userid, }); return } catch (e) { if (isAxiosError(e)) { throw e; } throw new Error("Unexpected error") } } /** * Pins the specified message * @param messageId * @param message */ async pinMessage(messageId: string, message: string): Promise { try { const resp = await this.client.patch("chat/dm/pinMessage", { messageId: messageId, chatid: this.chatid, userid: this.userid, message: message }); return } catch (e) { if (isAxiosError(e)) { throw e; } throw new Error("Unexpected error") } } /** * Unpins the specified message * @param messageId */ async unpinMessage(messageId: string): Promise { try { const resp = await this.client.patch("chat/dm/unpinMessage", { messageId: messageId, chatid: this.chatid, userid: this.userid, }); return } catch (e) { if (isAxiosError(e)) { throw e; } throw new Error("Unexpected error") } } /** * Deletes the message(s) * @param messageIds */ async deleteMessages(messageIds: string[]): Promise { try { const resp = await this.client.patch("chat/dm/deleteMessages", { chatid: this.chatid, userid: this.userid, messageIds: messageIds }); return } catch (e) { if (isAxiosError(e)) { throw e; } throw new Error("Unexpected error") } } /** * Joins the WebSocket room to start receiving realtime messages */ async joinWebSocketRoom(): Promise { try { const resp = await this.client.patch("chat/dm/joinWebSocketRoom", { chatid: this.chatid, userid: this.userid, connId: WebSocketHandler.getInstance().connId, }); return } catch (e) { if (isAxiosError(e)) { throw e; } throw new Error("Unexpected error") } } }