import { Injectable } from '@angular/core'; import { MessageRemoteDataSourceService } from '../data-source/message/message-remote-data-source.service'; import { MessageLiveDataSourceService } from '../data-source/message/message-live-data-source.service'; import { MessageLocalDataSourceService, TableMessage } from '../data-source/message/message-local-data-source.service'; import { SessionStore } from 'src/app/store/session.service'; import { SignalRService } from '../../infra/socket/signal-r.service'; import { v4 as uuidv4 } from 'uuid' import { err, ok } from 'neverthrow'; import { MessageDeleteInputDTO } from '../../domain/use-case/message-delete-live-use-case.service'; import { MessageUpdateInput } from '../../domain/use-case/message-update-use-case.service'; import { messageListDetermineChanges } from '../async/list/rooms/messageListChangedetector'; import { MessageEntity } from '../../domain/entity/message'; import { InstanceId } from '../../domain/chat-service.service'; import { MessageMapper } from '../../domain/mapper/messageMapper'; import { MessageOutPutDataDTO } from '../dto/message/messageOutputDTO'; @Injectable({ providedIn: 'root' }) export class MessageRepositoryService { constructor( private messageRemoteDataSourceService: MessageRemoteDataSourceService, private messageLiveDataSourceService: MessageLiveDataSourceService, private messageLiveSignalRDataSourceService: SignalRService, private messageLocalDataSourceService: MessageLocalDataSourceService ) {} async createMessageLocally(entity: MessageEntity) { const requestId = InstanceId +'@'+ uuidv4(); const roomId = entity.roomId return await this.messageLocalDataSourceService.sendMessage(entity) } async sendMessage(entity: MessageEntity) { const requestId = InstanceId +'@'+ uuidv4(); const roomId = entity.roomId const localActionResult = await this.messageLocalDataSourceService.sendMessage(entity) if(localActionResult.isOk()) { const DTO = MessageMapper.fromDomain(entity, requestId) const sendMessageResult = await this.messageLiveSignalRDataSourceService.sendMessage(DTO) if(sendMessageResult.isOk()) { if(sendMessageResult.value.sender == undefined || sendMessageResult.value.sender == null) { delete sendMessageResult.value.sender } let clone: TableMessage = { ...sendMessageResult.value, id: sendMessageResult.value.id, $id : localActionResult.value } return this.messageLocalDataSourceService.update({...clone, sending: false, roomId: entity.roomId}) } else { await this.messageLocalDataSourceService.update({sending: false, $id: localActionResult.value}) return err('no connection') } } else { // return this.messageLocalDataSourceService.update({sending: false}) } } sendMessageDelete(data: MessageDeleteInputDTO) { data['requestId'] = InstanceId +'@'+ uuidv4(); return this.messageLiveSignalRDataSourceService.sendMessageDelete(data) } async sendReadAt({roomId}) { const result = await this.messageLocalDataSourceService.getLastMessageByRoomId(roomId) if(result.isOk()) { if(result.value) { return await this.messageLiveSignalRDataSourceService.sendReadAt({roomId, memberId: SessionStore.user.UserId, chatMessageId: result.value.id}) } return ok(true) } return err(false) } reactToMessage(data) { this.messageLiveSignalRDataSourceService.sendData({ method: 'ReactMessage', data }) } updateMessage(input: MessageUpdateInput) { this.messageLiveSignalRDataSourceService.sendData({ method: 'EditMessage', data: input, }) } async listAllMessagesByRoomId(id: string) { const result = await this.messageRemoteDataSourceService.getMessagesFromRoom(id) const localResult = await this.messageLocalDataSourceService.getItems(id) if(result.isOk()) { const { addedItems, changedItems } = messageListDetermineChanges(result.value.data, localResult) for(const message of changedItems) { let clone: TableMessage = message clone.roomId = id await this.messageLocalDataSourceService.findOrUpdate(clone) } for(const message of addedItems) { let clone: TableMessage = message clone.roomId = id await this.messageLocalDataSourceService.createMessage(clone) } } return result } getItemsLive (roomId: string) { return this.messageLocalDataSourceService.getItemsLive(roomId) } subscribeToNewMessages(roomId: any) { return this.messageLocalDataSourceService.subscribeToNewMessage(roomId) } sendTyping(roomId) { return this.messageLiveSignalRDataSourceService.sendTyping({ roomId, UserName:SessionStore.user.FullName, userId: SessionStore.user.UserId }) } }