mirror of
https://code.equilibrium.co.ao/ITO/doneit-web.git
synced 2026-04-18 20:47:54 +00:00
improve chat
This commit is contained in:
@@ -16,6 +16,7 @@ import { ListenMessageDeleteByRoomIdService } from './use-case/listene-message-d
|
||||
import { ListenMessageUpdateByRoomIdUseCase } from './use-case/listen-message-update-by-roomId.service';
|
||||
import { SyncAllRoomMessagesService } from './use-case/sync-all-room-messages.service';
|
||||
import { ListenSendMessageUseCase } from './use-case/listen-send-message.service'
|
||||
import { GetMessageAttachmentLocallyUseCaseService } from 'src/app/module/chat/domain/use-case/get-message-attachment-localy-use-case.service';
|
||||
import { filter } from 'rxjs/operators';
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import { MessageEntity } from './entity/message';
|
||||
@@ -46,7 +47,8 @@ export class ChatServiceService {
|
||||
private ListenSendMessageUseCase: ListenSendMessageUseCase,
|
||||
private MessageAttachmentByMessageIdService: MessageAttachmentByMessageIdUseCase,
|
||||
private SyncAllRoomMessagesService: SyncAllRoomMessagesService,
|
||||
private DownloadMessageAttachmentUserCaseService: DownloadMessageAttachmentUserCaseService
|
||||
private DownloadMessageAttachmentUserCaseService: DownloadMessageAttachmentUserCaseService,
|
||||
private GetMessageAttachmentLocallyUseCaseService: GetMessageAttachmentLocallyUseCaseService
|
||||
) {
|
||||
this.messageLiveSignalRDataSourceService.getMessageDelete()
|
||||
.pipe()
|
||||
@@ -127,7 +129,7 @@ export class ChatServiceService {
|
||||
return this.SyncAllRoomMessagesService.execute()
|
||||
}
|
||||
|
||||
getMessageAttachmentByMessageId(input: MessageAttachmentByMessageIdInput) {
|
||||
getMessageAttachmentByMessageId(input: MessageEntity) {
|
||||
return this.MessageAttachmentByMessageIdService.execute(input)
|
||||
}
|
||||
|
||||
@@ -135,6 +137,10 @@ export class ChatServiceService {
|
||||
return this.DownloadMessageAttachmentUserCaseService.execute(input)
|
||||
}
|
||||
|
||||
getMessageAttachmentLocallyByMessageId(input: MessageAttachmentByMessageIdInput) {
|
||||
return this.GetMessageAttachmentLocallyUseCaseService.execute(input)
|
||||
}
|
||||
|
||||
|
||||
listenToIncomingMessage(roomId:string) {
|
||||
return this.ListenMessageByRoomIdNewUseCase.execute({roomId})
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { MessageAttachmentByMessageIdInput } from './message-attachment-by-message-id.service';
|
||||
import { AttachmentRemoteDataSourceService } from 'src/app/module/chat/data/data-source/attachment/attachment-remote-data-source.service'
|
||||
import { AttachmentLocalDataSource } from 'src/app/module/chat/data/data-source/attachment/attachment-local-data-source.service'
|
||||
import { err, Result } from 'neverthrow';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class GetMessageAttachmentLocallyUseCaseService {
|
||||
|
||||
constructor(
|
||||
private AttachmentRemoteDataSourceService: AttachmentRemoteDataSourceService,
|
||||
private AttachmentLocalDataSource: AttachmentLocalDataSource
|
||||
) { }
|
||||
|
||||
|
||||
async execute(input: MessageAttachmentByMessageIdInput): Promise<Result<string, any>> {
|
||||
|
||||
const getLocalAttachment = await this.AttachmentLocalDataSource.findOne({
|
||||
$messageId: input.$messageId
|
||||
})
|
||||
|
||||
if(getLocalAttachment.isOk()) {
|
||||
if(getLocalAttachment.value) {
|
||||
return getLocalAttachment.map(e => e.file)
|
||||
}
|
||||
} else {
|
||||
return err(getLocalAttachment.error)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import { AttachmentLocalDataSource } from 'src/app/module/chat/data/data-source/
|
||||
import { convertBlobToDataURL } from 'src/app/utils/ToBase64';
|
||||
import { Result } from 'neverthrow';
|
||||
import { Logger } from 'src/app/services/logger/main/service';
|
||||
import { MessageEntity } from '../entity/message';
|
||||
|
||||
const MessageAttachmentByMessageIdSchema = z.object({
|
||||
$messageId: z.number(),
|
||||
@@ -23,10 +24,10 @@ export class MessageAttachmentByMessageIdUseCase {
|
||||
private AttachmentLocalDataSource: AttachmentLocalDataSource
|
||||
) { }
|
||||
|
||||
async execute(input: MessageAttachmentByMessageIdInput): Promise<Result<string, any>> {
|
||||
async execute(input: MessageEntity): Promise<Result<string, any>> {
|
||||
|
||||
const getLocalAttachment = await this.AttachmentLocalDataSource.findOne({
|
||||
$messageId: input.$messageId
|
||||
$messageId: input.$id
|
||||
})
|
||||
|
||||
if(getLocalAttachment.isOk() && getLocalAttachment.value) {
|
||||
@@ -34,18 +35,40 @@ export class MessageAttachmentByMessageIdUseCase {
|
||||
return getLocalAttachment.map(e => e.file)
|
||||
}
|
||||
} else {
|
||||
const result = await this.AttachmentRemoteDataSourceService.getAttachment(input.id)
|
||||
const result = await this.AttachmentRemoteDataSourceService.getAttachment(input.attachments[0].id)
|
||||
|
||||
if(result.isErr()) {
|
||||
Logger.error('failed to download message attachment', {
|
||||
error: result.error,
|
||||
data: 'document id '+ input.attachments[0].id,
|
||||
messageId: input.id,
|
||||
$messageId: input.$id
|
||||
})
|
||||
}
|
||||
|
||||
return result.asyncMap(async (e) => {
|
||||
|
||||
const dataUrl = await convertBlobToDataURL(e)
|
||||
Logger.info('downloaded file', {
|
||||
data: dataUrl.slice(0, 100)+'...'
|
||||
})
|
||||
// Logger.info('downloaded file .', {
|
||||
// data: dataUrl.slice(0, 100)+'...'
|
||||
// })
|
||||
|
||||
this.AttachmentLocalDataSource.insert({
|
||||
$messageId: input.$messageId,
|
||||
id: input.id,
|
||||
file: dataUrl
|
||||
$messageId: input.$id,
|
||||
file: dataUrl,
|
||||
fileType: input.attachments[0].fileType,
|
||||
source: input.attachments[0].source,
|
||||
fileName: input.attachments[0].fileName,
|
||||
applicationId: input.attachments[0].applicationId,
|
||||
docId: input.attachments[0].docId,
|
||||
mimeType: input.attachments[0].mimeType,
|
||||
}).then((e) => {
|
||||
if(e.isErr()) {
|
||||
Logger.error('failed to create attachment locally on send message', {
|
||||
error: e.error,
|
||||
data: dataUrl.slice(0, 100)+'...'
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
return dataUrl
|
||||
|
||||
@@ -49,7 +49,13 @@ export class MessageCreateUseCaseService {
|
||||
|
||||
this.AttachmentRepositoryService.create({
|
||||
$messageId: createMessageLocally.value.$id,
|
||||
file: createDataURL(attachment.file, attachment.mimeType)
|
||||
file: createDataURL(attachment.file, attachment.mimeType),
|
||||
fileType: attachment.fileType,
|
||||
source: attachment.source,
|
||||
fileName: attachment.fileName,
|
||||
applicationId: attachment.applicationId,
|
||||
docId: attachment.docId,
|
||||
mimeType: attachment.mimeType,
|
||||
}).then((e) => {
|
||||
if(e.isErr()) {
|
||||
Logger.error('failed to create attachment locally on send message', {
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { MessageLocalDataSourceService } from '../../data/data-source/message/message-local-data-source.service';
|
||||
import { MessageOutPutDataDTO } from '../../data/dto/message/messageOutputDTO';
|
||||
import { MessageTable } from '../../infra/database/dexie/schema/message';
|
||||
import { SignalRService } from '../../infra/socket/signal-r.service';
|
||||
import { InstanceId } from '../chat-service.service';
|
||||
import { MessageMapper } from '../mapper/messageMapper';
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import { AttachmentRepositoryService } from "src/app/module/chat/data/repository/attachment-repository.service";
|
||||
import { AttachmentLocalDataSource } from '../../data/data-source/attachment/attachment-local-data-source.service';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class SendLocalMessagesUseCaseService {
|
||||
|
||||
constructor(
|
||||
private messageLiveSignalRDataSourceService: SignalRService,
|
||||
private messageLocalDataSourceService: MessageLocalDataSourceService,
|
||||
private AttachmentRepositoryService: AttachmentLocalDataSource,
|
||||
) { }
|
||||
|
||||
|
||||
async execute() {
|
||||
const messages = await this.messageLocalDataSourceService.getOfflineMessages()
|
||||
|
||||
if(messages.length >= 1) {
|
||||
|
||||
for(const message of messages) {
|
||||
|
||||
const attachments = await this.AttachmentRepositoryService.find({$messageId: message.$id})
|
||||
|
||||
if(attachments.isOk()) {
|
||||
|
||||
message.attachments = attachments.value.map(e => ({
|
||||
fileType: e.fileType,
|
||||
source: e.source,
|
||||
fileName: e.fileName,
|
||||
applicationId: e.applicationId,
|
||||
docId: e.docId,
|
||||
id: e.id,
|
||||
mimeType: e.mimeType,
|
||||
description: e.description,
|
||||
file: e.file.split(',')[0]
|
||||
}))
|
||||
console.log('to upload', messages)
|
||||
const requestId = InstanceId +'@'+ uuidv4();
|
||||
const DTO = MessageMapper.fromDomain(message, requestId)
|
||||
|
||||
await this.messageLocalDataSourceService.update(message.$id, { sending: true })
|
||||
const sendMessageResult = await this.messageLiveSignalRDataSourceService.sendMessage<MessageOutPutDataDTO>(DTO)
|
||||
|
||||
if(sendMessageResult.isOk()) {
|
||||
|
||||
if(sendMessageResult.value.sender == undefined || sendMessageResult.value.sender == null) {
|
||||
|
||||
delete sendMessageResult.value.sender
|
||||
}
|
||||
|
||||
let clone: MessageTable = {
|
||||
...sendMessageResult.value,
|
||||
id: sendMessageResult.value.id,
|
||||
$id : message.$id
|
||||
}
|
||||
|
||||
console.log('send message local '+ messages.length)
|
||||
|
||||
this.messageLocalDataSourceService.update(message.$id, {...clone, sending: false, roomId: message.roomId})
|
||||
} else {
|
||||
|
||||
console.log('erro send message')
|
||||
this.messageLocalDataSourceService.update(message.$id, {sending: false})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,22 @@
|
||||
import { z } from "zod";
|
||||
import { EntityTable } from 'Dexie';
|
||||
import { zodDataUrlSchema } from "src/app/utils/zod";
|
||||
import { MessageAttachmentFileType, MessageAttachmentSource } from "src/app/module/chat/data/dto/message/messageOutputDTO";
|
||||
|
||||
export const AttachmentTableSchema = z.object({
|
||||
id: z.string().optional(), // attachment id
|
||||
$id: z.number().optional(), // local id
|
||||
$messageId: z.number(),
|
||||
attachmentId: z.string().optional(),
|
||||
file: zodDataUrlSchema,
|
||||
//
|
||||
fileType: z.nativeEnum(MessageAttachmentFileType),
|
||||
source: z.nativeEnum(MessageAttachmentSource),
|
||||
fileName: z.string().optional(),
|
||||
applicationId: z.number().optional(),
|
||||
docId: z.string().optional(),
|
||||
mimeType: z.string().optional(),
|
||||
id: z.string().optional(),
|
||||
description: z.string().optional(),
|
||||
})
|
||||
|
||||
export type AttachmentTable = z.infer<typeof AttachmentTableSchema>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { nativeEnum, z } from "zod";
|
||||
import { EntityTable } from 'Dexie';
|
||||
import { MessageAttachmentFileType, MessageAttachmentSource } from "src/app/module/chat/data/dto/message/messageOutputDTO";
|
||||
import { z } from 'zod';
|
||||
|
||||
export const MessageTableSchema = z.object({
|
||||
$id: z.number().optional(),
|
||||
@@ -33,6 +33,7 @@ export const MessageTableSchema = z.object({
|
||||
applicationId: z.number().optional(),
|
||||
docId: z.string().optional(),
|
||||
id: z.string().optional(),
|
||||
description: z.string().optional(),
|
||||
mimeType: z.string().optional()
|
||||
})).optional()
|
||||
})
|
||||
|
||||
@@ -5,11 +5,16 @@ import { DexieMembersTableSchema, MemberTableColumn } from './schema/members';
|
||||
import { DexieRoomsTable, RoomTableColumn } from './schema/room';
|
||||
import { DexieTypingsTable, TypingTableColumn } from './schema/typing';
|
||||
import { MessageEntity } from '../../../domain/entity/message';
|
||||
import { AttachmentTable, AttachmentTableColumn, DexieAttachmentsTableSchema } from './schema/attachment';
|
||||
// import DexieMemory from 'dexie-in-memory';
|
||||
import { AttachmentTableColumn, DexieAttachmentsTableSchema } from './schema/attachment';
|
||||
// import FDBFactory from 'fake-indexeddb/lib/FDBFactory';
|
||||
// import FDBKeyRange from 'fake-indexeddb/lib/FDBKeyRange';
|
||||
|
||||
|
||||
// Database declaration (move this to its own module also)
|
||||
export const chatDatabase = new Dexie('chat-database-infra') as Dexie & {
|
||||
export const chatDatabase = new Dexie('chat-database-infra',{
|
||||
// indexedDB: new FDBFactory,
|
||||
// IDBKeyRange: FDBKeyRange, // Mocking IDBKeyRange
|
||||
}) as Dexie & {
|
||||
message: DexieMessageTable,
|
||||
members: DexieMembersTableSchema,
|
||||
room: DexieRoomsTable,
|
||||
@@ -26,4 +31,4 @@ chatDatabase.version(1).stores({
|
||||
});
|
||||
|
||||
chatDatabase.message.mapToClass(MessageEntity)
|
||||
// Apply in-memory storage
|
||||
// Apply in-memory storage
|
||||
Reference in New Issue
Block a user