mirror of
https://code.equilibrium.co.ao/ITO/doneit-web.git
synced 2026-04-19 21:06:06 +00:00
reorganizde file path
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { filter, map } from 'rxjs/operators';
|
||||
import { InstanceId } from '../../chat-service.service';
|
||||
import { MessageSocketRepositoryService } from 'src/app/module/chat/data/repository/message/message-live-signalr-data-source.service'
|
||||
import { MessageEntity } from '../../../../../core/chat/entity/message';
|
||||
import { UseCase } from 'src/app/utils/use-case-interface';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class ListenMessageByRoomIdNewUseCase {
|
||||
|
||||
constructor(
|
||||
private MessageSocketRepositoryService: MessageSocketRepositoryService
|
||||
) { }
|
||||
|
||||
execute({roomId}: {roomId: string}) {
|
||||
|
||||
return this.MessageSocketRepositoryService.listenToMessages().pipe(
|
||||
filter((message) => !message?.requestId?.startsWith(InstanceId) && message?.roomId == roomId),
|
||||
map(message => Object.assign(new MessageEntity(), message))
|
||||
)
|
||||
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { filter } from 'rxjs/operators';
|
||||
import { MessageSocketRepositoryService } from '../../../data/repository/message/message-live-signalr-data-source.service';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class ListenMessageUpdateByRoomIdUseCase {
|
||||
|
||||
constructor(
|
||||
private messageLiveSignalRDataSourceService: MessageSocketRepositoryService,
|
||||
) { }
|
||||
|
||||
execute({roomId}) {
|
||||
return this.messageLiveSignalRDataSourceService.listenToUpdateMessages().pipe(
|
||||
filter((message) => roomId == message?.roomId )
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { MessageSocketRepositoryService } from 'src/app/module/chat/data/repository/message/message-live-signalr-data-source.service'
|
||||
import { InstanceId } from '../../chat-service.service';
|
||||
import { filter, map } from 'rxjs/operators';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class ListenSendMessageUseCase {
|
||||
|
||||
constructor(
|
||||
private MessageSocketRepositoryService: MessageSocketRepositoryService
|
||||
) { }
|
||||
|
||||
execute({roomId}: {roomId: string}) {
|
||||
|
||||
return this.MessageSocketRepositoryService.listenToMessages().pipe(
|
||||
filter((message) => {
|
||||
return message?.requestId?.startsWith(InstanceId) && message?.roomId == roomId
|
||||
}),
|
||||
map(message => message)
|
||||
)
|
||||
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { SignalRService } from '../../../infra/socket/signal-r.service';
|
||||
import { filter } from 'rxjs/operators';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class ListenMessageDeleteByRoomIdService {
|
||||
|
||||
constructor(
|
||||
private messageLiveSignalRDataSourceService: SignalRService,
|
||||
) { }
|
||||
|
||||
execute({roomId}) {
|
||||
return this.messageLiveSignalRDataSourceService.getMessageDelete().pipe(
|
||||
filter((message) => {
|
||||
return roomId == message?.roomId
|
||||
} )
|
||||
)
|
||||
}
|
||||
}
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { z } from 'zod';
|
||||
import { AttachmentRemoteDataSourceService } from 'src/app/module/chat/data/repository/attachment/attachment-remote-repository.service'
|
||||
import { AttachmentLocalDataSource } from 'src/app/module/chat/data/repository/attachment/attachment-local-repository.service'
|
||||
import { convertBlobToDataURL } from 'src/app/utils/ToBase64';
|
||||
import { Result } from 'neverthrow';
|
||||
import { Logger } from 'src/app/services/logger/main/service';
|
||||
import { MessageEntity } from '../../../../../core/chat/entity/message';
|
||||
|
||||
const MessageAttachmentByMessageIdSchema = z.object({
|
||||
$messageId: z.number(),
|
||||
id: z.string()
|
||||
})
|
||||
|
||||
export type MessageAttachmentByMessageIdInput = z.infer<typeof MessageAttachmentByMessageIdSchema>
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class MessageAttachmentByMessageIdUseCase {
|
||||
|
||||
constructor(
|
||||
private AttachmentRemoteDataSourceService: AttachmentRemoteDataSourceService,
|
||||
private AttachmentLocalDataSource: AttachmentLocalDataSource
|
||||
) { }
|
||||
|
||||
async execute(input: MessageEntity): Promise<Result<string, any>> {
|
||||
|
||||
const getLocalAttachment = await this.AttachmentLocalDataSource.findOne({
|
||||
$messageId: input.$id
|
||||
})
|
||||
|
||||
if(getLocalAttachment.isOk() && getLocalAttachment.value) {
|
||||
if(getLocalAttachment.value) {
|
||||
return getLocalAttachment.map(e => e.file)
|
||||
}
|
||||
} else {
|
||||
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)+'...'
|
||||
// })
|
||||
|
||||
this.AttachmentLocalDataSource.insert({
|
||||
$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
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,169 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { MessageEntity, MessageEntitySchema, } from '../../../../../core/chat/entity/message';
|
||||
import { AttachmentLocalDataSource } from "src/app/module/chat/data/repository/attachment/attachment-local-repository.service";
|
||||
import { z } from 'zod';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import { InstanceId } from '../../chat-service.service';
|
||||
import { createDataURL } from 'src/app/utils/ToBase64';
|
||||
import { zodSafeValidation } from 'src/app/utils/zodValidation';
|
||||
import { Logger } from 'src/app/services/logger/main/service';
|
||||
import { MessageAttachmentSource, MessageOutPutDataDTO } from '../../../data/dto/message/messageOutputDTO';
|
||||
import { MessageLocalDataSourceService } from '../../../data/repository/message/message-local-data-source.service';
|
||||
import { MessageSocketRepositoryService } from '../../../data/repository/message/message-live-signalr-data-source.service';
|
||||
import { err, Result } from 'neverthrow';
|
||||
import { MessageTable } from '../../../infra/database/dexie/schema/message';
|
||||
import { MessageMapper } from '../../mapper/messageMapper';
|
||||
import { RoomType } from "src/app/core/chat/entity/group";
|
||||
import { TracingType, XTracerAsync } from 'src/app/services/monitoring/opentelemetry/tracer';
|
||||
import { MemberListLocalRepository } from 'src/app/module/chat/data/repository/member/member-list-local-repository.service'
|
||||
import { SessionStore } from 'src/app/store/session.service';
|
||||
|
||||
const MessageInputUseCaseSchema = z.object({
|
||||
memberId: z.number(),
|
||||
roomId: z.string(),
|
||||
message: z.string()
|
||||
})
|
||||
|
||||
export enum MessageEnum {
|
||||
Direct = 1,
|
||||
group = 2
|
||||
}
|
||||
|
||||
export type MessageInputUseCase = z.infer< typeof MessageInputUseCaseSchema>
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class MessageCreateUseCaseService {
|
||||
|
||||
constructor(
|
||||
private AttachmentLocalRepositoryService: AttachmentLocalDataSource,
|
||||
private messageLocalDataSourceService: MessageLocalDataSourceService,
|
||||
private MessageSocketRepositoryService: MessageSocketRepositoryService,
|
||||
private messageSocketRepositoryService: MessageSocketRepositoryService,
|
||||
private MemberListLocalRepository: MemberListLocalRepository
|
||||
) { }
|
||||
|
||||
|
||||
@XTracerAsync({name:'MessageCreateUseCaseService', module:'chat', bugPrint: true, waitNThrow: 5000})
|
||||
async execute(message: MessageEntity, messageEnum: RoomType, tracing?: TracingType) {
|
||||
|
||||
const validation = zodSafeValidation<MessageEntity>(MessageEntitySchema, message)
|
||||
|
||||
if(validation.isOk()) {
|
||||
message.sendAttemp++;
|
||||
|
||||
message.requestId = InstanceId +'@'+ uuidv4();
|
||||
message.sending = true;
|
||||
|
||||
const createMessageLocally = await this.messageLocalDataSourceService.insert(message)
|
||||
|
||||
if(createMessageLocally.isOk()) {
|
||||
|
||||
message.$id = createMessageLocally.value
|
||||
|
||||
if(message.hasAttachment) {
|
||||
|
||||
for (const attachment of message.attachments) {
|
||||
|
||||
if(attachment.source != MessageAttachmentSource.Webtrix) {
|
||||
|
||||
this.AttachmentLocalRepositoryService.insert({
|
||||
$messageId: createMessageLocally.value,
|
||||
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', {
|
||||
error: e.error,
|
||||
data: createDataURL(attachment.file, attachment.mimeType).slice(0, 100) +'...'
|
||||
})
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
attachment.safeFile = createDataURL(attachment.file, attachment.mimeType)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//====================
|
||||
message.sending = true
|
||||
|
||||
let sendMessageResult: Result<MessageOutPutDataDTO, any>
|
||||
if(messageEnum == RoomType.Group) {
|
||||
const DTO = MessageMapper.fromDomain(message, message.requestId)
|
||||
sendMessageResult = await this.MessageSocketRepositoryService.sendGroupMessage(DTO)
|
||||
} else {
|
||||
|
||||
if(message.receiverId) {
|
||||
const DTO = MessageMapper.fromDomain(message, message.requestId)
|
||||
sendMessageResult = await this.messageSocketRepositoryService.sendDirectMessage(DTO)
|
||||
} else {
|
||||
const getRoomMembers = await this.MemberListLocalRepository.directMember({
|
||||
roomId:message.roomId,
|
||||
currentUserId: SessionStore.user.UserId
|
||||
})
|
||||
if(getRoomMembers.isOk()) {
|
||||
message.receiverId = getRoomMembers.value.wxUserId
|
||||
const DTO = MessageMapper.fromDomain(message, message.requestId)
|
||||
sendMessageResult = await this.messageSocketRepositoryService.sendGroupMessage(DTO)
|
||||
} else {
|
||||
console.log('not found direct users', getRoomMembers.error)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// return this sendMessageResult
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
this.messageLocalDataSourceService.update(message.$id, {...clone, sending: false, roomId: message.roomId})
|
||||
|
||||
return sendMessageResult
|
||||
} else {
|
||||
Logger.error('failed to send message to the server', {
|
||||
error: sendMessageResult.error
|
||||
})
|
||||
await this.messageLocalDataSourceService.update(message.$id, {sending: false, $id: message.$id})
|
||||
return err('no connection')
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
|
||||
if(validation.error.formErrors.fieldErrors.attachments) {
|
||||
Logger.error('failed to send message doe to invalid attachment', {
|
||||
zodErrorList: validation.error.errors,
|
||||
data: message.attachments
|
||||
})
|
||||
} else {
|
||||
Logger.error('failed to send message, validation failed', {
|
||||
zodErrorList: validation.error.errors,
|
||||
data: message
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { z } from 'zod';
|
||||
import { SafeValidateSchema, ValidateSchema } from 'src/app/services/decorators/validate-schema.decorator';
|
||||
import { MessageRemoteDataSourceService } from '../../../data/repository/message/message-remote-data-source.service';
|
||||
import { MessageSocketRepositoryService } from '../../../data/repository/message/message-live-signalr-data-source.service';
|
||||
import { XTracerAsync, TracingType } from 'src/app/services/monitoring/opentelemetry/tracer';
|
||||
export const MessageDeleteInputDTOSchema = z.object({
|
||||
requestId: z.string().optional(),
|
||||
roomId: z.string(),
|
||||
messageId: z.string(),
|
||||
senderId: z.number(),
|
||||
});
|
||||
export type MessageDeleteInputDTO = z.infer<typeof MessageDeleteInputDTOSchema>
|
||||
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class MessageDeleteLiveUseCaseService {
|
||||
constructor(
|
||||
public repository: MessageSocketRepositoryService
|
||||
) { }
|
||||
|
||||
@XTracerAsync({name:'MessageDeleteLiveUseCaseService', module:'chat', bugPrint: true})
|
||||
async execute(data: MessageDeleteInputDTO, tracing?: TracingType) {
|
||||
tracing.log('MessageDeleteLiveUseCaseService payload', {
|
||||
data: data
|
||||
})
|
||||
return this.repository.sendMessageDelete(data)
|
||||
}
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { AttachmentRemoteDataSourceService } from 'src/app/module/chat/data/repository/attachment/attachment-remote-repository.service'
|
||||
import { Logger } from 'src/app/services/logger/main/service';
|
||||
import { convertBlobToDataURL } from 'src/app/utils/ToBase64';
|
||||
import { AttachmentLocalDataSource } from 'src/app/module/chat/data/repository/attachment/attachment-local-repository.service'
|
||||
import { MessageAttachmentByMessageIdInput } from './message-attachment-by-message-id.service';
|
||||
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class DownloadMessageAttachmentUserCaseService {
|
||||
|
||||
constructor(
|
||||
private AttachmentRemoteDataSourceService: AttachmentRemoteDataSourceService,
|
||||
private AttachmentLocalDataSource: AttachmentLocalDataSource
|
||||
) { }
|
||||
|
||||
async execute(input: MessageAttachmentByMessageIdInput) {
|
||||
const result = await this.AttachmentRemoteDataSourceService.getAttachment(input.$messageId)
|
||||
return result.asyncMap(async (e) => {
|
||||
|
||||
const dataUrl = await convertBlobToDataURL(e)
|
||||
Logger.info('downloaded file #1', {
|
||||
data: dataUrl.slice(0, 100)+'...',
|
||||
context: 'DownloadMessageAttachmentUserCaseService'
|
||||
})
|
||||
|
||||
this.AttachmentLocalDataSource.insert({
|
||||
$messageId: input.$messageId,
|
||||
id: input.id,
|
||||
file: dataUrl
|
||||
})
|
||||
|
||||
return dataUrl
|
||||
})
|
||||
}
|
||||
}
|
||||
+33
@@ -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/repository/attachment/attachment-remote-repository.service'
|
||||
import { AttachmentLocalDataSource } from 'src/app/module/chat/data/repository/attachment/attachment-local-repository.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)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { object, z } from 'zod';
|
||||
import { ValidateSchema } from 'src/app/services/decorators/validate-schema.decorator';
|
||||
import { MessageRemoteDataSourceService } from '../../../data/repository/message/message-remote-data-source.service';
|
||||
import { MessageSocketRepositoryService } from '../../../data/repository/message/message-live-signalr-data-source.service';
|
||||
|
||||
|
||||
const MessageReactionInputDTOSchema = z.object({
|
||||
memberId: z.number(),
|
||||
messageId: z.string(),
|
||||
roomId: z.string(),
|
||||
reaction: z.string(),
|
||||
requestId: z.string().optional()
|
||||
})
|
||||
|
||||
export type MessageReactionInput = z.infer< typeof MessageReactionInputDTOSchema>
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class MessageReactionUseCaseService {
|
||||
|
||||
constructor(
|
||||
public repository: MessageSocketRepositoryService
|
||||
) { }
|
||||
|
||||
@ValidateSchema(MessageReactionInputDTOSchema)
|
||||
execute(input: MessageReactionInput) {
|
||||
return this.repository.reactToMessageSocket(input)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { err, ok } from 'neverthrow';
|
||||
import { SessionStore } from 'src/app/store/session.service';
|
||||
import { MessageLocalDataSourceService } from '../../../data/repository/message/message-local-data-source.service';
|
||||
import { MessageSocketRepositoryService } from '../../../data/repository/message/message-live-signalr-data-source.service';
|
||||
import { MessageRemoteDataSourceService } from '../../../data/repository/message/message-remote-data-source.service';
|
||||
import { SignalRService } from '../../../infra/socket/signal-r.service';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class MessageReadAtByIdUseCaseService {
|
||||
|
||||
constructor(
|
||||
private MessageSocketRepositoryService: MessageSocketRepositoryService,
|
||||
private messageLiveSignalRDataSourceService: SignalRService,
|
||||
private messageLocalDataSourceService: MessageLocalDataSourceService,
|
||||
) { }
|
||||
|
||||
async execute({roomId}) {
|
||||
// const result = await this.messageLocalDataSourceService.getLastMessageByRoomId(roomId)
|
||||
// if(result.isOk()) {
|
||||
// if(result.value) {
|
||||
|
||||
// return await this.MessageSocketRepositoryService.sendReadAt({roomId, memberId: SessionStore.user.UserId, messageId: result.value.id, requestId: ''})
|
||||
// }
|
||||
// return ok(true)
|
||||
// }
|
||||
// return err(false)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { MessageEntity } from '../../../../../core/chat/entity/message';
|
||||
import { z } from 'zod';
|
||||
|
||||
const MessageInputUseCaseSchema = z.object({
|
||||
memberId: z.number(),
|
||||
roomId: z.string(),
|
||||
message: z.string()
|
||||
})
|
||||
|
||||
export type MessageInputUseCase = z.infer< typeof MessageInputUseCaseSchema>
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class MessageCreateUseCaseService {
|
||||
|
||||
constructor() { }
|
||||
|
||||
|
||||
async execute(input: MessageEntity) {
|
||||
|
||||
// const result = await this.MessageRepositoryService.(input)
|
||||
|
||||
// if(result.isOk()) {
|
||||
|
||||
// }
|
||||
|
||||
// return result
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class MessageToAsyncUIService {
|
||||
|
||||
constructor() { }
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { z } from 'zod';
|
||||
import { ValidateSchema } from 'src/app/services/decorators/validate-schema.decorator';
|
||||
import { MessageRemoteDataSourceService } from '../../../data/repository/message/message-remote-data-source.service';
|
||||
import { MessageSocketRepositoryService } from '../../../data/repository/message/message-live-signalr-data-source.service';
|
||||
|
||||
|
||||
const MessageUpdateInputDTOSchema = z.object({
|
||||
memberId: z.number(),
|
||||
messageId: z.string(),
|
||||
roomId: z.string(),
|
||||
message: z.string().optional().nullable(),
|
||||
requestId: z.string().optional()
|
||||
})
|
||||
|
||||
export type MessageUpdateInput = z.infer< typeof MessageUpdateInputDTOSchema>
|
||||
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class MessageUpdateUseCaseService {
|
||||
|
||||
constructor(
|
||||
public repository: MessageSocketRepositoryService
|
||||
) { }
|
||||
|
||||
@ValidateSchema(MessageUpdateInputDTOSchema)
|
||||
execute(input: MessageUpdateInput) {
|
||||
return this.repository.updateMessage(input);
|
||||
}
|
||||
|
||||
}
|
||||
+116
@@ -0,0 +1,116 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { MessageLocalDataSourceService } from '../../../data/repository/message/message-local-data-source.service';
|
||||
import { MessageSocketRepositoryService } from '../../../data/repository/message/message-live-signalr-data-source.service';
|
||||
import { MessageTable } from '../../../infra/database/dexie/schema/message';
|
||||
import { InstanceId } from '../../chat-service.service';
|
||||
import { MessageMapper } from '../../mapper/messageMapper';
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import { AttachmentLocalDataSource } from '../../../data/repository/attachment/attachment-local-repository.service';
|
||||
import { RoomLocalRepository } from '../../../data/repository/room/room-local-repository.service';
|
||||
import { MemberListLocalRepository } from 'src/app/module/chat/data/repository/member/member-list-local-repository.service'
|
||||
import { Result } from 'neverthrow';
|
||||
import { RoomType } from 'src/app/core/chat/entity/group';
|
||||
import { SessionStore } from 'src/app/store/session.service';
|
||||
import { MessageOutPutDataDTO } from '../../../data/dto/message/messageOutputDTO';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class SendLocalMessagesUseCaseService {
|
||||
|
||||
constructor(
|
||||
private MessageSocketRepositoryService: MessageSocketRepositoryService,
|
||||
private messageLocalDataSourceService: MessageLocalDataSourceService,
|
||||
private AttachmentRepositoryService: AttachmentLocalDataSource,
|
||||
private roomLocalDataSourceService: RoomLocalRepository,
|
||||
private MemberListLocalRepository: MemberListLocalRepository,
|
||||
private messageSocketRepositoryService: MessageSocketRepositoryService,
|
||||
) { }
|
||||
|
||||
async execute() {
|
||||
|
||||
const allRooms = await this.roomLocalDataSourceService.findAll()
|
||||
const messages = await this.messageLocalDataSourceService.getOfflineMessages()
|
||||
|
||||
if(allRooms.isOk()) {
|
||||
if(allRooms.value.length == 0) {
|
||||
|
||||
} else {
|
||||
|
||||
for(const message of messages) {
|
||||
const room = allRooms.value.find(e => e.id == message.roomId)
|
||||
|
||||
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(',')[1]
|
||||
}))
|
||||
console.log('to upload', messages)
|
||||
const requestId = InstanceId +'@'+ uuidv4();
|
||||
|
||||
await this.messageLocalDataSourceService.update(message.$id, { sending: true })
|
||||
|
||||
let sendMessageResult: Result<MessageOutPutDataDTO, any>
|
||||
if(room.roomType == RoomType.Group) {
|
||||
const DTO = MessageMapper.fromDomain(message, message.requestId)
|
||||
sendMessageResult = await this.MessageSocketRepositoryService.sendGroupMessage(DTO)
|
||||
} else {
|
||||
|
||||
if(message.receiverId) {
|
||||
const DTO = MessageMapper.fromDomain(message, message.requestId)
|
||||
sendMessageResult = await this.messageSocketRepositoryService.sendDirectMessage(DTO)
|
||||
} else {
|
||||
const getRoomMembers = await this.MemberListLocalRepository.directMember({
|
||||
roomId:message.roomId,
|
||||
currentUserId: SessionStore.user.UserId
|
||||
})
|
||||
if(getRoomMembers.isOk()) {
|
||||
message.receiverId = getRoomMembers.value.wxUserId
|
||||
const DTO = MessageMapper.fromDomain(message, message.requestId)
|
||||
sendMessageResult = await this.messageSocketRepositoryService.sendGroupMessage(DTO)
|
||||
} else {
|
||||
console.log('not found direct users', getRoomMembers.error)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
clone.sending = false
|
||||
console.log({clone})
|
||||
console.log('send message local '+ messages.length)
|
||||
|
||||
this.messageLocalDataSourceService.update(message.$id, {id: sendMessageResult.value.id, sending: false})
|
||||
} else {
|
||||
this.messageLocalDataSourceService.update(message.$id, {sending: false})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { MessageLocalDataSourceService } from '../../../data/repository/message/message-local-data-source.service';
|
||||
import { messageListDetermineChanges } from '../../../data/async/list/rooms/messageListChangedetector';
|
||||
import { MessageTable } from '../../../infra/database/dexie/schema/message';
|
||||
import { MessageRemoteDataSourceService } from '../../../data/repository/message/message-remote-data-source.service';
|
||||
import { MessageSocketRepositoryService } from '../../../data/repository/message/message-live-signalr-data-source.service';
|
||||
import { ok } from 'neverthrow';
|
||||
import { RoomLocalRepository } from '../../../data/repository/room/room-local-repository.service';
|
||||
import { SessionStore } from 'src/app/store/session.service';
|
||||
import { Logger } from 'src/app/services/logger/main/service';
|
||||
import { XTracerAsync, TracingType } from 'src/app/services/monitoring/opentelemetry/tracer';
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class SyncAllRoomMessagesService {
|
||||
|
||||
constructor(
|
||||
private messageLocalDataSourceService: MessageLocalDataSourceService,
|
||||
private messageRemoteDataSourceService: MessageRemoteDataSourceService,
|
||||
private MessageSocketRepositoryService: MessageSocketRepositoryService,
|
||||
private roomLocalDataSourceService: RoomLocalRepository,
|
||||
) { }
|
||||
|
||||
@XTracerAsync({name:'SyncAllRoomMessagesService', module:'chat', bugPrint: true})
|
||||
async execute(tracing?: TracingType) {
|
||||
|
||||
const allRooms = await this.roomLocalDataSourceService.findAll()
|
||||
|
||||
if(allRooms.isOk()) {
|
||||
if(allRooms.value.length == 0) {
|
||||
tracing.addEvent('no need to sync')
|
||||
} else {
|
||||
tracing.addEvent('total sync '+ allRooms.value.length)
|
||||
}
|
||||
|
||||
let n =0
|
||||
for(const room of allRooms.value) {
|
||||
|
||||
const result = await this.messageRemoteDataSourceService.getMessagesFromRoom(room.id)
|
||||
const localResult = await this.messageLocalDataSourceService.getItems(room.id)
|
||||
|
||||
tracing.addEvent('async n '+ n)
|
||||
n++
|
||||
|
||||
if(result.isOk()) {
|
||||
|
||||
const { addedItems, changedItems, deletedItems } = messageListDetermineChanges(result.value.data, localResult)
|
||||
|
||||
|
||||
for(const message of changedItems) {
|
||||
let clone: MessageTable = message
|
||||
clone.roomId = room.id
|
||||
|
||||
this.messageLocalDataSourceService.update(clone.$id, clone)
|
||||
|
||||
const me = message.info.find(e => e.memberId == SessionStore.user.UserId && typeof e.deliverAt == 'string' )
|
||||
|
||||
if(!me) {
|
||||
this.MessageSocketRepositoryService.sendDeliverAt({
|
||||
memberId: SessionStore.user.UserId,
|
||||
messageId: message.id,
|
||||
roomId: message.roomId,
|
||||
requestId: uuidv4()
|
||||
})
|
||||
|
||||
tracing.addEvent('send delever roomId'+ room.id)
|
||||
}
|
||||
}
|
||||
|
||||
for(const message of addedItems) {
|
||||
let clone: MessageTable = message
|
||||
clone.roomId = room.id
|
||||
|
||||
// const me = message.info.find(e => e.memberId == SessionStore.user.UserId && typeof e.deliverAt == 'string' )
|
||||
// if(!me) {
|
||||
// this.MessageSocketRepositoryService.sendDeliverAt({
|
||||
// memberId: SessionStore.user.UserId,
|
||||
// messageId: message.id,
|
||||
// roomId: message.roomId,
|
||||
// requestId: uuidv4()
|
||||
// })
|
||||
|
||||
// tracing.addEvent('send delever roomId'+ room.id)
|
||||
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
this.messageLocalDataSourceService.insertMany(addedItems.reverse())
|
||||
|
||||
} else {
|
||||
Logger.error('failed to get room message '+room.id)
|
||||
}
|
||||
}
|
||||
|
||||
return ok(true)
|
||||
} else {
|
||||
console.log('sync all error', allRooms)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user