create direct message

This commit is contained in:
Peter Maquiran
2024-08-19 16:01:58 +01:00
parent 29d0a9b55e
commit ae50d9b3bd
46 changed files with 500 additions and 297 deletions
@@ -3,7 +3,8 @@ import { MessageAttachmentFileType, MessageAttachmentSource } from "./messageOut
import { base64Schema } from "src/app/utils/zod";
export const MessageInputDTOSchema = z.object({
roomId: z.string().uuid(),
roomId: z.string().uuid().optional(),
receiverId: z.number().optional(),
senderId: z.number(),
message: z.string().nullable().optional(),
messageType: z.number(),
@@ -27,7 +27,7 @@ export const MessageOutPutDataDTOSchema = z.object({
canEdit: z.boolean(),
oneShot: z.boolean(),
requireUnlock: z.boolean(),
requestId: z.string().optional(),
requestId: z.string().optional().nullable(),
reactions: z.object({
id: z.string(),
reactedAt: z.string(),
@@ -1,51 +0,0 @@
import { Injectable } from '@angular/core';
import { err, ok } from 'neverthrow';
import { SignalRService } from '../../infra/socket/signal-r.service';
interface msgObj {
roomId: string;
senderId: string;
message:string;
messageType:1;
canEdit:Boolean;
oneShot:Boolean;
requestId: string;
}
@Injectable({
providedIn: 'root'
})
export class MessageLiveDataSourceService {
constructor(
private messageLiveSignalRDataSourceService: SignalRService
) {}
async sendMessage(data: msgObj) {
try {
const result = await this.messageLiveSignalRDataSourceService.sendMessage(data)
return ok(result)
} catch (e) {
return err(e)
}
}
listenToMessages() {
return this.messageLiveSignalRDataSourceService.getMessage()
}
listenToDeleteMessages() {
return this.messageLiveSignalRDataSourceService.getMessageDelete()
}
listenToUpdateMessages() {
return this.messageLiveSignalRDataSourceService.getMessageUpdate()
}
}
@@ -0,0 +1,99 @@
import { Injectable } from '@angular/core';
import { err, ok } from 'neverthrow';
import { SignalRService } from '../../../infra/socket/signal-r.service';
import { SessionStore } from 'src/app/store/session.service';
import { MessageDeleteInputDTO } from '../../dto/message/messageDeleteInputDTO';
import { v4 as uuidv4 } from 'uuid'
import { InstanceId } from '../../../domain/chat-service.service';
import { MessageUpdateInput } from '../../../domain/use-case/message-update-by-id-use-case.service';
import { MessageOutPutDataDTO } from '../../dto/message/messageOutputDTO';
import { MessageInputDTO } from '../../dto/message/messageInputDtO';
interface msgObj {
roomId: string;
senderId: string;
message:string;
messageType:1;
canEdit:Boolean;
oneShot:Boolean;
requestId: string;
}
@Injectable({
providedIn: 'root'
})
export class MessageSocketRepositoryService {
constructor(
private socket: SignalRService
) {}
async sendMessage(data: msgObj) {
try {
const result = await this.socket.sendMessage(data)
return ok(result)
} catch (e) {
return err(e)
}
}
async sendDirectMessage(data: MessageInputDTO) {
const result = await this.socket.sendData<MessageOutPutDataDTO>({
method: 'SendDirectMessage',
data: data as any,
})
return result;
}
listenToMessages() {
return this.socket.getMessage()
}
listenToDeleteMessages() {
return this.socket.getMessageDelete()
}
listenToUpdateMessages() {
return this.socket.getMessageUpdate()
}
reactToMessageSocket(data) {
this.socket.sendData({
method: 'ReactMessage',
data
})
}
updateMessage(input: MessageUpdateInput) {
this.socket.sendData({
method: 'EditMessage',
data: input,
})
}
sendTyping(roomId) {
return this.socket.sendTyping({
roomId,
UserName:SessionStore.user.FullName,
userId: SessionStore.user.UserId
})
}
sendMessageDelete(data: MessageDeleteInputDTO) {
data['requestId'] = InstanceId +'@'+ uuidv4();
return this.socket.sendMessageDelete(data)
}
}
@@ -3,10 +3,10 @@ import { liveQuery } from 'Dexie';
import { err, ok, Result } from 'neverthrow';
import { Observable, Subject } from 'rxjs';
import { filter } from 'rxjs/operators';
import { MessageEntity } from '../../domain/entity/message';
import { MessageEntity } from '../../../domain/entity/message';
import { DexieRepository } from 'src/app/infra/repository/dexie/dexie-repository.service';
import { MessageTable, MessageTableSchema } from 'src/app/module/chat/infra/database/dexie/schema/message';
import { chatDatabase } from '../../infra/database/dexie/service';
import { chatDatabase } from '../../../infra/database/dexie/service';
import { Observable as DexieObservable, PromiseExtended } from 'Dexie';
@Injectable({
@@ -1,15 +1,15 @@
import { Injectable } from '@angular/core';
import { HttpService } from 'src/app/services/http.service';
import { MessageInputDTO, MessageInputDTOSchema } from '../dto/message/messageInputDtO';
import { MessageInputDTO, MessageInputDTOSchema } from '../../dto/message/messageInputDtO';
import { ValidateSchema } from 'src/app/services/decorators/validate-schema.decorator';
import { APIReturn } from 'src/app/services/decorators/api-validate-schema.decorator';
import { MessageOutPutDataDTOSchema, MessageOutPutDTO, MessageOutPutDTOSchema } from '../dto/message/messageOutputDTO';
import { MessageOutPutDataDTOSchema, MessageOutPutDTO, MessageOutPutDTOSchema } from '../../dto/message/messageOutputDTO';
import { DataSourceReturn } from 'src/app/services/Repositorys/type';
import { SignalRService } from '../../infra/socket/signal-r.service';
import { MessageUpdateInput } from '../../domain/use-case/message-update-by-id-use-case.service';
import { SignalRService } from '../../../infra/socket/signal-r.service';
import { MessageUpdateInput } from '../../../domain/use-case/message-update-by-id-use-case.service';
import { SessionStore } from 'src/app/store/session.service';
import { MessageDeleteInputDTO } from '../dto/message/messageDeleteInputDTO';
import { InstanceId } from '../../domain/chat-service.service';
import { MessageDeleteInputDTO } from '../../dto/message/messageDeleteInputDTO';
import { InstanceId } from '../../../domain/chat-service.service';
import { v4 as uuidv4 } from 'uuid'
@Injectable({
@@ -46,35 +46,5 @@ export class MessageRemoteDataSourceService {
return await this.httpService.get(`${this.baseUrl}/attachment/${id}`);
}
reactToMessageSocket(data) {
this.socket.sendData({
method: 'ReactMessage',
data
})
}
updateMessage(input: MessageUpdateInput) {
this.socket.sendData({
method: 'EditMessage',
data: input,
})
}
sendTyping(roomId) {
return this.socket.sendTyping({
roomId,
UserName:SessionStore.user.FullName,
userId: SessionStore.user.UserId
})
}
sendMessageDelete(data: MessageDeleteInputDTO) {
data['requestId'] = InstanceId +'@'+ uuidv4();
return this.socket.sendMessageDelete(data)
}
}
@@ -4,7 +4,7 @@ import { SessionStore } from 'src/app/store/session.service';
import { MessageReactionInput, MessageReactionUseCaseService } from 'src/app/module/chat/domain/use-case/message-reaction-by-id-use-case.service';
import { MessageUpdateInput, MessageUpdateUseCaseService } from 'src/app/module/chat/domain/use-case/message-update-by-id-use-case.service';
import { MemberAdminUseCaseService, MemberSetAdminDTO } from 'src/app/module/chat/domain/use-case/member-admin-use-case.service';
import { MessageCreateUseCaseService } from 'src/app/module/chat/domain/use-case/message-create-use-case.service';
import { MessageCreateUseCaseService, MessageEnum } from 'src/app/module/chat/domain/use-case/message-create-use-case.service';
import { SignalRService } from '../infra/socket/signal-r.service';
import { SocketMessageDeleteUseCaseService } from 'src/app/module/chat/domain/use-case/socket/socket-message-delete-use-case.service';
import { SocketMessageUpdateUseCaseService } from 'src/app/module/chat/domain/use-case/socket/socket-message-update-use-case.service';
@@ -151,8 +151,8 @@ export class ChatServiceService {
return this.MemberAdminUseCaseService.execute(input)
}
sendMessage(input: MessageEntity) {
return this.MessageCreateUseCaseService.execute(input);
sendMessage(input: MessageEntity, messageEnum: MessageEnum) {
return this.MessageCreateUseCaseService.execute(input, messageEnum);
}
asyncAllRoomMessage() {
@@ -0,0 +1,4 @@
export enum RoomType {
Group = 1,
Direct = 2
}
+4 -2
View File
@@ -6,7 +6,8 @@ import { base64Schema } from "src/app/utils/zod";
export const MessageEntitySchema = z.object({
$id: z.any().optional(),
id: z.string().optional(),
roomId: z.string(),
roomId: z.string().uuid().optional(),
receiverId: z.number().optional(),
message: z.string().optional(),
messageType: z.number(),
canEdit: z.boolean(),
@@ -38,7 +39,8 @@ export class MessageEntity implements Message {
$id: number
id: string
roomId: string
roomId?: string
receiverId?: number
message: string
messageType: number = 0
canEdit: boolean = false
@@ -1,7 +1,6 @@
import { MessageInputDTO } from "../../data/dto/message/messageInputDtO";
import { MessageOutPutDataDTO } from "../../data/dto/message/messageOutputDTO";
import { MessageEntity } from "../entity/message";
import { attachments } from '../../../../../../../../../Downloads/equilibriumito-gabinete-digital-fo-23cf0fc4cbaa/equilibriumito-gabinete-digital-fo-23cf0fc4cbaa/src/app/models/beast-orm';
export class MessageMapper {
static toDomain(DTO: MessageOutPutDataDTO) : MessageEntity {
@@ -10,6 +9,7 @@ export class MessageMapper {
static fromDomain(entity:MessageEntity, requestId): MessageInputDTO {
return {
receiverId: entity.receiverId,
canEdit: entity.canEdit,
message: entity.message,
messageType: entity.messageType,
@@ -26,7 +26,7 @@ export class MessageMapper {
applicationId: e.applicationId || 0,
docId: Number(e.docId) || 0,
mimeType: e.mimeType
}))[0]
}))[0] || {}
}
}
@@ -1,7 +1,7 @@
import { Injectable } from '@angular/core';
import { filter, map } from 'rxjs/operators';
import { InstanceId } from '../chat-service.service';
import { MessageLiveDataSourceService } from 'src/app/module/chat/data/repository/message-live-signalr-data-source.service'
import { MessageSocketRepositoryService } from 'src/app/module/chat/data/repository/message/message-live-signalr-data-source.service'
import { MessageEntity } from '../entity/message';
@Injectable({
@@ -10,12 +10,12 @@ import { MessageEntity } from '../entity/message';
export class ListenMessageByRoomIdNewUseCase {
constructor(
private MessageLiveDataSourceService: MessageLiveDataSourceService
private MessageSocketRepositoryService: MessageSocketRepositoryService
) { }
execute({roomId}: {roomId: string}) {
return this.MessageLiveDataSourceService.listenToMessages().pipe(
return this.MessageSocketRepositoryService.listenToMessages().pipe(
filter((message) => !message?.requestId?.startsWith(InstanceId) && message?.roomId == roomId),
map(message => Object.assign(new MessageEntity(), message))
)
@@ -1,6 +1,6 @@
import { Injectable } from '@angular/core';
import { filter } from 'rxjs/operators';
import { MessageLiveDataSourceService } from '../../data/repository/message-live-signalr-data-source.service';
import { MessageSocketRepositoryService } from '../../data/repository/message/message-live-signalr-data-source.service';
@Injectable({
providedIn: 'root'
@@ -8,7 +8,7 @@ import { MessageLiveDataSourceService } from '../../data/repository/message-live
export class ListenMessageUpdateByRoomIdUseCase {
constructor(
private messageLiveSignalRDataSourceService: MessageLiveDataSourceService,
private messageLiveSignalRDataSourceService: MessageSocketRepositoryService,
) { }
execute({roomId}) {
@@ -1,5 +1,5 @@
import { Injectable } from '@angular/core';
import { MessageLiveDataSourceService } from 'src/app/module/chat/data/repository/message-live-signalr-data-source.service'
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';
@@ -9,12 +9,12 @@ import { filter, map } from 'rxjs/operators';
export class ListenSendMessageUseCase {
constructor(
private MessageLiveDataSourceService: MessageLiveDataSourceService
private MessageSocketRepositoryService: MessageSocketRepositoryService
) { }
execute({roomId}: {roomId: string}) {
return this.MessageLiveDataSourceService.listenToMessages().pipe(
return this.MessageSocketRepositoryService.listenToMessages().pipe(
filter((message) => message?.requestId?.startsWith(InstanceId) && message?.roomId == roomId),
map(message => message)
)
@@ -8,8 +8,9 @@ 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-local-data-source.service';
import { err } from 'neverthrow';
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 { SignalRService } from '../../infra/socket/signal-r.service';
@@ -20,6 +21,11 @@ const MessageInputUseCaseSchema = z.object({
message: z.string()
})
export enum MessageEnum {
Direct = 1,
group = 2
}
export type MessageInputUseCase = z.infer< typeof MessageInputUseCaseSchema>
@Injectable({
@@ -31,10 +37,11 @@ export class MessageCreateUseCaseService {
private AttachmentLocalRepositoryService: AttachmentLocalDataSource,
private messageLocalDataSourceService: MessageLocalDataSourceService,
private messageLiveSignalRDataSourceService: SignalRService,
private messageSocketRepositoryService: MessageSocketRepositoryService
) { }
async execute(message: MessageEntity) {
async execute(message: MessageEntity, messageEnum: MessageEnum) {
const validation = zodSafeValidation<MessageEntity>(MessageEntitySchema, message)
@@ -85,7 +92,14 @@ export class MessageCreateUseCaseService {
message.sending = true
const DTO = MessageMapper.fromDomain(message, message.requestId)
const sendMessageResult = await this.messageLiveSignalRDataSourceService.sendMessage<MessageOutPutDataDTO>(DTO)
let sendMessageResult: Result<MessageOutPutDataDTO, any>
if(messageEnum == MessageEnum.group) {
sendMessageResult = await this.messageLiveSignalRDataSourceService.sendMessage<MessageOutPutDataDTO>(DTO)
} else {
sendMessageResult = await this.messageSocketRepositoryService.sendDirectMessage(DTO)
}
// return this sendMessageResult
if(sendMessageResult.isOk()) {
@@ -101,7 +115,9 @@ export class MessageCreateUseCaseService {
$id : message.$id
}
return this.messageLocalDataSourceService.update(message.$id, {...clone, sending: false, roomId: message.roomId})
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
@@ -1,7 +1,9 @@
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-remote-data-source.service';
import { MessageRemoteDataSourceService } from '../../data/repository/message/message-remote-data-source.service';
import { MessageSocketRepositoryService } from '../../data/repository/message/message-live-signalr-data-source.service';
export const MessageDeleteInputDTOSchema = z.object({
requestId: z.string().optional(),
@@ -17,7 +19,7 @@ export type MessageDeleteInputDTO = z.infer<typeof MessageDeleteInputDTOSchema>
})
export class MessageDeleteLiveUseCaseService {
constructor(
public repository: MessageRemoteDataSourceService
public repository: MessageSocketRepositoryService
) { }
@SafeValidateSchema(MessageDeleteInputDTOSchema, 'MessageDeleteUseCaseService')
@@ -1,7 +1,8 @@
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-remote-data-source.service';
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({
@@ -20,7 +21,7 @@ export type MessageReactionInput = z.infer< typeof MessageReactionInputDTOSchema
export class MessageReactionUseCaseService {
constructor(
public repository: MessageRemoteDataSourceService
public repository: MessageSocketRepositoryService
) { }
@ValidateSchema(MessageReactionInputDTOSchema)
@@ -1,8 +1,8 @@
import { Injectable } from '@angular/core';
import { err, ok } from 'neverthrow';
import { SessionStore } from 'src/app/store/session.service';
import { MessageLocalDataSourceService } from '../../data/repository/message-local-data-source.service';
import { MessageRemoteDataSourceService } from '../../data/repository/message-remote-data-source.service';
import { MessageLocalDataSourceService } from '../../data/repository/message/message-local-data-source.service';
import { MessageRemoteDataSourceService } from '../../data/repository/message/message-remote-data-source.service';
import { SignalRService } from '../../infra/socket/signal-r.service';
@Injectable({
@@ -1,7 +1,9 @@
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-remote-data-source.service';
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(),
@@ -20,7 +22,7 @@ export type MessageUpdateInput = z.infer< typeof MessageUpdateInputDTOSchema>
export class MessageUpdateUseCaseService {
constructor(
public repository: MessageRemoteDataSourceService
public repository: MessageSocketRepositoryService
) { }
@ValidateSchema(MessageUpdateInputDTOSchema)
@@ -1,5 +1,5 @@
import { Injectable } from '@angular/core';
import { MessageLocalDataSourceService } from '../../data/repository/message-local-data-source.service';
import { MessageLocalDataSourceService } from '../../data/repository/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';
@@ -1,5 +1,5 @@
import { Injectable, Input } from '@angular/core';
import { MessageLocalDataSourceService } from '../../../data/repository/message-local-data-source.service';
import { MessageLocalDataSourceService } from '../../../data/repository/message/message-local-data-source.service';
import { TracingType, XTracerAsync } from 'src/app/services/monitoring/opentelemetry/tracer';
import { ParamsValidation } from 'src/app/services/decorators/validate-schema.decorator';
import { MessageOutPutDataDTOSchema } from '../../../data/dto/message/messageOutputDTO';
@@ -1,5 +1,5 @@
import { Injectable } from '@angular/core';
import { MessageLocalDataSourceService } from '../../../data/repository/message-local-data-source.service';
import { MessageLocalDataSourceService } from '../../../data/repository/message/message-local-data-source.service';
import { MessageOutPutDataDTO } from '../../../data/dto/message/messageOutputDTO';
@Injectable({
@@ -1,5 +1,5 @@
import { Injectable } from '@angular/core';
import { MessageLocalDataSourceService } from '../../../data/repository/message-local-data-source.service';
import { MessageLocalDataSourceService } from '../../../data/repository/message/message-local-data-source.service';
import { MessageOutPutDataDTO, MessageOutPutDataDTOSchema } from '../../../data/dto/message/messageOutputDTO';
import { ParamsValidation, SafeValidateSchema, ValidateSchema } from 'src/app/services/decorators/validate-schema.decorator';
import { MessageInputDTOSchema } from '../../../data/dto/message/messageInputDtO';
@@ -1,8 +1,8 @@
import { Injectable } from '@angular/core';
import { MessageLocalDataSourceService } from '../../data/repository/message-local-data-source.service';
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-remote-data-source.service';
import { MessageRemoteDataSourceService } from '../../data/repository/message/message-remote-data-source.service';
import { ok } from 'neverthrow';
import { RoomLocalRepository } from '../../data/repository/room-local-repository.service';
@@ -5,7 +5,7 @@ import { z } from 'zod';
export const MessageTableSchema = z.object({
$id: z.number().optional(),
id: z.string().optional(),
roomId: z.string().uuid(),
roomId: z.string().uuid().optional(),
message: z.string().nullable().optional(),
messageType: z.number(),
canEdit: z.boolean(),
@@ -18,6 +18,7 @@ export const MessageTableSchema = z.object({
wxeMail: z.string(),
userPhoto: z.string(),
}),
receiverId: z.number().optional(),
sending: z.boolean().optional(),
reactions: z.object({
id: z.string(),
@@ -134,8 +134,8 @@ export class SignalRService {
return this.messageUpdateSubject.asObservable()
}
sendData(input: ISignalRInput) {
return this.connection.sendData(input)
sendData<T>(input: ISignalRInput) {
return this.connection.sendData<T>(input)
}
getData() {
+3 -3
View File
@@ -241,7 +241,7 @@ export class SignalRConnection {
}
sendData(input: ISignalRInput): Promise<Result<any, any>> {
sendData<T>(input: ISignalRInput): Promise<Result<T, any>> {
return new Promise((resolve, reject) => {
if(this.connectionStateSubject.value == true) {
@@ -249,10 +249,10 @@ export class SignalRConnection {
this.hubConnection.invoke(input.method, input.data)
this.sendDataSubject.pipe(
filter((message: any) => input.data.requestId == message?.requestId),
filter((message) => input.data.requestId == message?.data.requestId),
first()
).subscribe(value => {
resolve(ok(value))
resolve(ok(value.data as unknown as T))
console.log('Received valid value:', value);
});