mirror of
https://code.equilibrium.co.ao/ITO/doneit-web.git
synced 2026-04-19 04:57:52 +00:00
realtime
This commit is contained in:
@@ -1,12 +0,0 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { UserTypingAsyncService } from 'src/app/module/chat/data/async/socket/user-typing-async.service'
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class ChatServiceService {
|
||||
|
||||
constructor(
|
||||
private UserTypingAsyncService: UserTypingAsyncService
|
||||
) { }
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { SignalRService } from 'src/app/module/chat/infra/socket/signal-r.service'
|
||||
import { SyncMessageRepositoryService } from './data/service/sync-repository/sync-message-repository.service';
|
||||
import { UserTypingAsyncService } from 'src/app/module/chat/data/async/socket/user-typing-async.service'
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
|
||||
@@ -16,7 +18,8 @@ export class ChatModule {
|
||||
|
||||
constructor(
|
||||
private message: SyncMessageRepositoryService,
|
||||
private SignalRService: SignalRService
|
||||
private SignalRService: SignalRService,
|
||||
private UserTypingAsyncService: UserTypingAsyncService
|
||||
) {
|
||||
|
||||
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { MessageRepositoryAyncService } from './message-repository-aync.service';
|
||||
|
||||
describe('MessageRepositoryAyncService', () => {
|
||||
let service: MessageRepositoryAyncService;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({});
|
||||
service = TestBed.inject(MessageRepositoryAyncService);
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -3,10 +3,9 @@ import { Injectable } from '@angular/core';
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class MessageRepositoryAyncService {
|
||||
export class MessageRepositorySyncService {
|
||||
|
||||
constructor() {
|
||||
|
||||
// alert('hellor')
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Observable, Subject } from 'rxjs';
|
||||
import { DexieRepository } from 'src/app/infra/repository/dexie/dexie-repository.service';
|
||||
import { chatDatabase } from '../../../infra/database/dexie/service';
|
||||
import { Observable as DexieObservable, PromiseExtended } from 'Dexie';
|
||||
import { AttachmentTable } from '../../../infra/database/dexie/schema/attachment';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class AttachmentLocalDataSourceService extends DexieRepository<AttachmentTable> {
|
||||
|
||||
messageSubject = new Subject();
|
||||
|
||||
constructor() {
|
||||
super(chatDatabase.attachment)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
+14
-1
@@ -2,7 +2,6 @@ import { Injectable } from '@angular/core';
|
||||
import { err, ok } from 'neverthrow';
|
||||
import { SignalRService } from '../../../infra/socket/signal-r.service';
|
||||
|
||||
|
||||
interface msgObj {
|
||||
roomId: string;
|
||||
senderId: string;
|
||||
@@ -35,4 +34,18 @@ export class MessageLiveDataSourceService {
|
||||
|
||||
}
|
||||
|
||||
listenToMessages() {
|
||||
return this.messageLiveSignalRDataSourceService.getMessage()
|
||||
}
|
||||
|
||||
|
||||
listenToDeleteMessages() {
|
||||
return this.messageLiveSignalRDataSourceService.getMessageDelete()
|
||||
}
|
||||
|
||||
|
||||
listenToUpdateMessages() {
|
||||
return this.messageLiveSignalRDataSourceService.getMessageUpdate()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Dexie, EntityTable, liveQuery } from 'Dexie';
|
||||
import { liveQuery } from 'Dexie';
|
||||
import { err, ok, Result } from 'neverthrow';
|
||||
import { from, Observable, Subject } from 'rxjs';
|
||||
import { Observable, Subject } from 'rxjs';
|
||||
import { filter } from 'rxjs/operators';
|
||||
import { MessageInputDTO } from '../../dto/message/messageInputDtO';
|
||||
import { MessageEntity } from '../../../domain/entity/message';
|
||||
import { DexieRepository } from 'src/app/infra/repository/dexie/dexie-repository.service';
|
||||
import { MessageTable } from 'src/app/module/chat/infra/database/dexie/schema/message';
|
||||
import { chatDatabase } from '../../../infra/database/dexie/service';
|
||||
import { Observable as DexieObservable, PromiseExtended } from 'Dexie';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
@@ -61,7 +61,7 @@ export class MessageLocalDataSourceService extends DexieRepository<MessageTable>
|
||||
}
|
||||
|
||||
|
||||
async sendMessage(data: MessageInputDTO) {
|
||||
async sendMessage(data: MessageTable) {
|
||||
|
||||
(data as MessageTable).sending = true
|
||||
|
||||
@@ -76,9 +76,8 @@ export class MessageLocalDataSourceService extends DexieRepository<MessageTable>
|
||||
}
|
||||
|
||||
|
||||
|
||||
// @ValidateSchema(tableSchema)
|
||||
async createMessage(data: MessageInputDTO) {
|
||||
async createMessage(data: MessageTable) {
|
||||
|
||||
try {
|
||||
const result = await chatDatabase.message.add(data)
|
||||
@@ -90,7 +89,7 @@ export class MessageLocalDataSourceService extends DexieRepository<MessageTable>
|
||||
|
||||
}
|
||||
|
||||
async createManyMessage(data: MessageInputDTO[]) {
|
||||
async createManyMessage(data: MessageTable[]) {
|
||||
|
||||
try {
|
||||
const result = await chatDatabase.message.bulkAdd(data)
|
||||
@@ -147,12 +146,12 @@ export class MessageLocalDataSourceService extends DexieRepository<MessageTable>
|
||||
}
|
||||
}
|
||||
|
||||
getItems(roomId: string) {
|
||||
return chatDatabase.message.where('roomId').equals(roomId).toArray()
|
||||
getItems(roomId: string): PromiseExtended<MessageEntity[]> {
|
||||
return chatDatabase.message.where('roomId').equals(roomId).sortBy('$id') as any
|
||||
}
|
||||
|
||||
getItemsLive(roomId: string) {
|
||||
return liveQuery(() => chatDatabase.message.where('roomId').equals(roomId).sortBy('$id'))
|
||||
getItemsLive(roomId: string): DexieObservable<MessageEntity[]> {
|
||||
return liveQuery(() => chatDatabase.message.where('roomId').equals(roomId).sortBy('$id') as any)
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class MessageMemoryDataSourceService {
|
||||
|
||||
messages: {[roomId: string]: string[]} = {}
|
||||
|
||||
constructor() {}
|
||||
}
|
||||
@@ -31,4 +31,10 @@ export class MessageRemoteDataSourceService {
|
||||
return await this.httpService.get(`${this.baseUrl}/Room/${id}/Messages`);
|
||||
}
|
||||
|
||||
|
||||
@APIReturn(MessageOutPutDTOSchema, 'get/Messages/attachment')
|
||||
async getAttachment(id: string): DataSourceReturn<MessageOutPutDTO> {
|
||||
return await this.httpService.get(`${this.baseUrl}/attachment/${id}`);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { WebSocketMessage, WebSocketService } from '../../../infra/socket/socket';
|
||||
import { err, ok } from 'neverthrow';
|
||||
|
||||
import { SignalRService } from '../../../infra/socket/signal-r.service';
|
||||
import { AddMemberToRoomInputDTO } from '../../dto/room/addMemberToRoomInputDto';
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class RoomLiveDataSourceService {
|
||||
|
||||
// constructor(private socket: WebSocketService) {}
|
||||
constructor(
|
||||
private socket: SignalRService,
|
||||
) {}
|
||||
|
||||
// async getRoomById(data: WebSocketMessage) {
|
||||
|
||||
@@ -24,4 +26,19 @@ export class RoomLiveDataSourceService {
|
||||
|
||||
// }
|
||||
|
||||
async addMemberToRoom(data: AddMemberToRoomInputDTO) {
|
||||
|
||||
const result = await this.socket.sendData({
|
||||
method: 'AddRoomMember',
|
||||
data: {
|
||||
requestId: uuidv4(),
|
||||
roomId: data.id,
|
||||
members: data.members
|
||||
}
|
||||
})
|
||||
|
||||
console.log({result})
|
||||
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
+12
-1
@@ -12,9 +12,20 @@ import { TypingTable } from '../../../infra/database/dexie/schema/typing';
|
||||
})
|
||||
export class UserTypingLocalDataSourceService {
|
||||
|
||||
constructor() { }
|
||||
constructor() {
|
||||
this.clear();
|
||||
}
|
||||
|
||||
|
||||
async clear() {
|
||||
try {
|
||||
const result = await chatDatabase.typing.clear()
|
||||
return ok(result)
|
||||
} catch (e) {
|
||||
return err(false)
|
||||
}
|
||||
}
|
||||
|
||||
async addUserTyping(data: TypingTable) {
|
||||
|
||||
data.id = data.chatRoomId + '@' + data.userName
|
||||
|
||||
@@ -10,14 +10,15 @@ export const MessageInputDTOSchema = z.object({
|
||||
oneShot: z.boolean(),
|
||||
requireUnlock: z.boolean(),
|
||||
requestId: z.string(),
|
||||
attachments: z.array(z.object({
|
||||
attachment: z.object({
|
||||
fileType: z.nativeEnum(MessageAttachmentFileType),
|
||||
source: z.nativeEnum(MessageAttachmentSource),
|
||||
file: z.string(),
|
||||
fileName: z.string(),
|
||||
applicationId: z.string(),
|
||||
docId: z.string()
|
||||
})).optional()
|
||||
docId: z.string(),
|
||||
mimeType: z.string().optional()
|
||||
}).optional()
|
||||
});
|
||||
|
||||
|
||||
|
||||
@@ -24,7 +24,6 @@ export const MessageOutPutDataDTOSchema = z.object({
|
||||
message: z.string().nullable(),
|
||||
messageType: z.number(),
|
||||
sentAt: z.string(),
|
||||
deliverAt: z.string().datetime().nullable(),
|
||||
canEdit: z.boolean(),
|
||||
oneShot: z.boolean(),
|
||||
requireUnlock: z.boolean(),
|
||||
@@ -39,10 +38,11 @@ export const MessageOutPutDataDTOSchema = z.object({
|
||||
attachments: z.array(z.object({
|
||||
fileType: z.nativeEnum(MessageAttachmentFileType),
|
||||
source: z.nativeEnum(MessageAttachmentSource),
|
||||
file: z.string(),
|
||||
fileName: z.string(),
|
||||
file: z.string().optional(),
|
||||
fileName: z.string().optional(),
|
||||
applicationId: z.string().optional(),
|
||||
docId: z.string().optional()
|
||||
docId: z.string().optional(),
|
||||
id: z.string()
|
||||
}))
|
||||
});
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
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 } 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'
|
||||
@@ -14,7 +12,10 @@ import { InstanceId } from '../../domain/chat-service.service';
|
||||
import { MessageMapper } from '../../domain/mapper/messageMapper';
|
||||
import { MessageOutPutDataDTO } from '../dto/message/messageOutputDTO';
|
||||
import { MessageTable } from 'src/app/module/chat/infra/database/dexie/schema/message';
|
||||
|
||||
import { MessageLocalDataSourceService } from '../data-source/message/message-local-data-source.service';
|
||||
import { MessageLiveDataSourceService } from '../data-source/message/message-live-signalr-data-source.service';
|
||||
import { AttachmentLocalDataSourceService } from 'src/app/module/chat/data/data-source/attachment/message-local-data-source.service'
|
||||
import { Subject } from 'rxjs';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
@@ -25,7 +26,8 @@ export class MessageRepositoryService {
|
||||
private messageRemoteDataSourceService: MessageRemoteDataSourceService,
|
||||
private messageLiveDataSourceService: MessageLiveDataSourceService,
|
||||
private messageLiveSignalRDataSourceService: SignalRService,
|
||||
private messageLocalDataSourceService: MessageLocalDataSourceService
|
||||
private messageLocalDataSourceService: MessageLocalDataSourceService,
|
||||
private AttachmentLocalDataSourceService: AttachmentLocalDataSourceService
|
||||
) {}
|
||||
|
||||
|
||||
@@ -37,17 +39,30 @@ export class MessageRepositoryService {
|
||||
|
||||
}
|
||||
|
||||
async sendMessage(entity: MessageEntity) {
|
||||
|
||||
const requestId = InstanceId +'@'+ uuidv4();
|
||||
async createMessage(entity: MessageEntity) {
|
||||
//const requestId = InstanceId +'@'+ uuidv4();
|
||||
|
||||
const localActionResult = await this.messageLocalDataSourceService.sendMessage(entity)
|
||||
|
||||
return localActionResult.map(e => {
|
||||
entity.$id = e
|
||||
return entity
|
||||
})
|
||||
}
|
||||
|
||||
async sendMessage(entity: MessageEntity) {
|
||||
const messageSubject = new Subject<MessageTable | string>();
|
||||
|
||||
const roomId = entity.roomId
|
||||
|
||||
entity.sending = true
|
||||
const localActionResult = await this.messageLocalDataSourceService.sendMessage(entity)
|
||||
|
||||
if(localActionResult.isOk()) {
|
||||
const DTO = MessageMapper.fromDomain(entity, requestId)
|
||||
const DTO = MessageMapper.fromDomain(entity, entity.requestId)
|
||||
const sendMessageResult = await this.messageLiveSignalRDataSourceService.sendMessage<MessageOutPutDataDTO>(DTO)
|
||||
// return this sendMessageResult
|
||||
|
||||
if(sendMessageResult.isOk()) {
|
||||
|
||||
@@ -62,6 +77,8 @@ export class MessageRepositoryService {
|
||||
$id : localActionResult.value
|
||||
}
|
||||
|
||||
// console.log('sendMessageResult.value', sendMessageResult.value)
|
||||
// this.attachment(sendMessageResult.value.attachments[0].id)
|
||||
return this.messageLocalDataSourceService.update(localActionResult.value, {...clone, sending: false, roomId: entity.roomId})
|
||||
} else {
|
||||
await this.messageLocalDataSourceService.update(localActionResult.value, {sending: false, $id: localActionResult.value})
|
||||
@@ -113,12 +130,14 @@ export class MessageRepositoryService {
|
||||
|
||||
if(result.isOk()) {
|
||||
|
||||
const { addedItems, changedItems } = messageListDetermineChanges(result.value.data, localResult)
|
||||
const { addedItems, changedItems, deletedItems } = messageListDetermineChanges(result.value.data, localResult)
|
||||
|
||||
console.log({addedItems, changedItems});
|
||||
|
||||
for(const message of changedItems) {
|
||||
let clone: MessageTable = message
|
||||
clone.roomId = id
|
||||
await this.messageLocalDataSourceService.findOrUpdate(clone)
|
||||
this.messageLocalDataSourceService.findOrUpdate(clone)
|
||||
}
|
||||
|
||||
for(const message of addedItems) {
|
||||
@@ -126,7 +145,14 @@ export class MessageRepositoryService {
|
||||
clone.roomId = id
|
||||
|
||||
}
|
||||
await this.messageLocalDataSourceService.createManyMessage(addedItems.reverse())
|
||||
this.messageLocalDataSourceService.createManyMessage(addedItems.reverse())
|
||||
|
||||
|
||||
for(const message of deletedItems) {
|
||||
this.messageLocalDataSourceService.deleteByMessageId(message.id)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
return result
|
||||
}
|
||||
@@ -135,6 +161,10 @@ export class MessageRepositoryService {
|
||||
return this.messageLocalDataSourceService.getItemsLive(roomId)
|
||||
}
|
||||
|
||||
getItems (roomId: string) {
|
||||
return this.messageLocalDataSourceService.getItems(roomId)
|
||||
}
|
||||
|
||||
subscribeToNewMessages(roomId: any) {
|
||||
return this.messageLocalDataSourceService.subscribeToNewMessage(roomId)
|
||||
}
|
||||
@@ -147,4 +177,9 @@ export class MessageRepositoryService {
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
attachment(roomId: string) {
|
||||
console.log('attachment')
|
||||
return this.messageRemoteDataSourceService.getAttachment(roomId)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ import { MessageLiveDataSourceService } from '../data-source/message/message-liv
|
||||
import { MemberListUPdateStatusInputDTO } from '../../domain/use-case/socket/member-list-update-status-use-case.service';
|
||||
import { MemberSetAdminDTO } from '../../domain/use-case/member-admin-use-case.service';
|
||||
import { MemberListMapper } from '../../domain/mapper/memberLIstMapper';
|
||||
import { SignalRService } from '../../infra/socket/signal-r.service';
|
||||
|
||||
|
||||
function date(isoDateString) {
|
||||
@@ -43,8 +44,7 @@ export class RoomRepositoryService {
|
||||
private roomRemoteDataSourceService: RoomRemoteDataSourceService,
|
||||
// private roomMemoryDataSourceService: Store<RoomRemoteDataSourceState>,
|
||||
private roomLocalDataSourceService: RoomLocalDataSourceService,
|
||||
private roomLiveDataSourceService: RoomLiveDataSourceService,
|
||||
private messageLiveDataSourceService: MessageLiveDataSourceService,
|
||||
private roomLiveSignalRDataSourceService: RoomLiveDataSourceService,
|
||||
) {}
|
||||
|
||||
@captureAndReraiseAsync('RoomRepositoryService/list')
|
||||
@@ -80,13 +80,13 @@ export class RoomRepositoryService {
|
||||
this.list()
|
||||
}, timeRemaining)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
return result
|
||||
}
|
||||
@@ -223,9 +223,12 @@ export class RoomRepositoryService {
|
||||
|
||||
@captureAndReraiseAsync('RoomRepositoryService/addMemberToRoom')
|
||||
async addMemberToRoom(data: AddMemberToRoomInputDTO) {
|
||||
const result = await this.roomRemoteDataSourceService.addMemberToRoom(data)
|
||||
|
||||
return result
|
||||
return this.roomLiveSignalRDataSourceService.addMemberToRoom(data)
|
||||
|
||||
// const result = await this.roomRemoteDataSourceService.addMemberToRoom(data)
|
||||
|
||||
// return result
|
||||
}
|
||||
|
||||
async updateMemberStatus(data: MemberListUPdateStatusInputDTO) {
|
||||
|
||||
@@ -9,10 +9,13 @@ 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';
|
||||
import { SocketMessageCreateUseCaseService } from 'src/app/module/chat/domain/use-case/socket/socket-message-create-use-case.service';
|
||||
import { ListenMessageByRoomIdNewUseCase } from 'src/app/module/chat/domain/use-case/listen-message-by-roomId.service';
|
||||
import { MemberListUpdateStatusUseCaseService } from 'src/app/module/chat/domain/use-case/socket/member-list-update-status-use-case.service';
|
||||
import { ListenMessageDeleteByRoomIdService } from './use-case/listene-message-delete-by-roomId.service';
|
||||
import { ListenMessageUpdateByRoomIdUseCase } from './use-case/listen-message-update-by-roomId.service';
|
||||
import { ListenSendMessageUseCase } from './use-case/listen-send-message.service'
|
||||
import { filter } from 'rxjs/operators';
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import { MessageInputDTO } from '../data/dto/message/messageInputDtO';
|
||||
import { MessageEntity } from './entity/message';
|
||||
|
||||
export const InstanceId = uuidv4();
|
||||
@@ -33,7 +36,11 @@ export class ChatServiceService {
|
||||
private SocketMessageCreateUseCaseService: SocketMessageCreateUseCaseService,
|
||||
private MemberListUpdateStatusUseCaseService: MemberListUpdateStatusUseCaseService,
|
||||
private MemberAdminUseCaseService: MemberAdminUseCaseService,
|
||||
private MessageCreateUseCaseService: MessageCreateUseCaseService
|
||||
private MessageCreateUseCaseService: MessageCreateUseCaseService,
|
||||
private ListenMessageByRoomIdNewUseCase: ListenMessageByRoomIdNewUseCase,
|
||||
private ListenMessageDeleteService: ListenMessageDeleteByRoomIdService,
|
||||
private ListenMessageUpdateByRoomIdUseCase: ListenMessageUpdateByRoomIdUseCase,
|
||||
private ListenSendMessageUseCase: ListenSendMessageUseCase
|
||||
) {
|
||||
this.messageLiveSignalRDataSourceService.getMessageDelete()
|
||||
.pipe()
|
||||
@@ -106,9 +113,26 @@ export class ChatServiceService {
|
||||
return this.MemberAdminUseCaseService.execute(input)
|
||||
}
|
||||
|
||||
|
||||
sendMessage(input: MessageEntity) {
|
||||
return this.MessageCreateUseCaseService.execute(input);
|
||||
}
|
||||
|
||||
listenToIncomingMessage(roomId:string) {
|
||||
return this.ListenMessageByRoomIdNewUseCase.execute({roomId})
|
||||
}
|
||||
|
||||
listenToDeleteMessage(roomId: string) {
|
||||
return this.ListenMessageDeleteService.execute({roomId})
|
||||
}
|
||||
|
||||
listenToUpdateMessage(roomId: string) {
|
||||
return this.ListenMessageUpdateByRoomIdUseCase.execute({roomId})
|
||||
}
|
||||
|
||||
|
||||
listenToSendMessage(roomId: string) {
|
||||
return this.ListenSendMessageUseCase.execute({roomId})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -21,11 +21,15 @@ const MessageEntitySchema = z.object({
|
||||
attachments: z.array(z.object({
|
||||
fileType: z.nativeEnum(MessageAttachmentFileType),
|
||||
source: z.nativeEnum(MessageAttachmentSource),
|
||||
file: z.string().optional(),
|
||||
fileName: z.string().optional(),
|
||||
applicationId: z.string().optional(),
|
||||
docId: z.string().optional()
|
||||
})),
|
||||
attachmentsSource: z.array(z.object({
|
||||
file: z.string(),
|
||||
fileName: z.string(),
|
||||
applicationId: z.string(),
|
||||
docId: z.string()
|
||||
}))
|
||||
id: z.string(),
|
||||
})),
|
||||
})
|
||||
|
||||
type Message = z.infer<typeof MessageEntitySchema>;
|
||||
@@ -56,8 +60,19 @@ export class MessageEntity implements Message {
|
||||
file?: string,
|
||||
fileName: string,
|
||||
applicationId?: string,
|
||||
docId?: string
|
||||
}[]
|
||||
docId?: string,
|
||||
mimeType?: string,
|
||||
description?: string
|
||||
}[] = []
|
||||
|
||||
attachmentsSource: {
|
||||
id: string,
|
||||
file: string
|
||||
}[] = []
|
||||
|
||||
reactions = []
|
||||
|
||||
requestId: string
|
||||
|
||||
constructor() {}
|
||||
|
||||
@@ -67,4 +82,8 @@ export class MessageEntity implements Message {
|
||||
}
|
||||
}
|
||||
|
||||
get hasAttachment() {
|
||||
return this.attachments.length >= 1
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ export class MessageMapper {
|
||||
roomId: entity.roomId,
|
||||
senderId: entity.sender.wxUserId,
|
||||
requestId: requestId,
|
||||
attachments: entity.attachments
|
||||
attachment: entity.attachments[0]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
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/data-source/message/message-live-signalr-data-source.service'
|
||||
import { MessageEntity } from '../entity/message';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class ListenMessageByRoomIdNewUseCase {
|
||||
|
||||
constructor(
|
||||
private MessageLiveDataSourceService: MessageLiveDataSourceService
|
||||
) { }
|
||||
|
||||
execute({roomId}: {roomId: string}) {
|
||||
|
||||
return this.MessageLiveDataSourceService.listenToMessages().pipe(
|
||||
filter((message) => !message?.requestId?.startsWith(InstanceId) && message?.roomId == roomId),
|
||||
map(message => Object.assign(new MessageEntity(), message))
|
||||
)
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { filter } from 'rxjs/operators';
|
||||
import { MessageLiveDataSourceService } from '../../data/data-source/message/message-live-signalr-data-source.service';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class ListenMessageUpdateByRoomIdUseCase {
|
||||
|
||||
constructor(
|
||||
private messageLiveSignalRDataSourceService: MessageLiveDataSourceService,
|
||||
) { }
|
||||
|
||||
execute({roomId}) {
|
||||
return this.messageLiveSignalRDataSourceService.listenToUpdateMessages().pipe(
|
||||
filter((message) => roomId == message?.roomId )
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { MessageLiveDataSourceService } from 'src/app/module/chat/data/data-source/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 MessageLiveDataSourceService: MessageLiveDataSourceService
|
||||
) { }
|
||||
|
||||
execute({roomId}: {roomId: string}) {
|
||||
|
||||
return this.MessageLiveDataSourceService.listenToMessages().pipe(
|
||||
filter((message) => message?.requestId?.startsWith(InstanceId) && message?.roomId == roomId),
|
||||
map(message => message)
|
||||
)
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
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) => {
|
||||
|
||||
console.log({message}, 'delete')
|
||||
return roomId == message?.roomId
|
||||
} )
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,8 @@ import { MessageEntity } from '../entity/message';
|
||||
import { SessionStore } from 'src/app/store/session.service';
|
||||
import { MessageRepositoryService } from "src/app/module/chat/data/repository/message-respository.service"
|
||||
import { z } from 'zod';
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import { InstanceId } from '../chat-service.service';
|
||||
|
||||
const MessageInputUseCaseSchema = z.object({
|
||||
memberId: z.number(),
|
||||
@@ -26,6 +28,8 @@ export class MessageCreateUseCaseService {
|
||||
|
||||
input.sendAttemp++;
|
||||
|
||||
input.requestId = InstanceId +'@'+ uuidv4();
|
||||
|
||||
const result = await this.MessageRepositoryService.sendMessage(input)
|
||||
|
||||
return result
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { MessageEntity } from '../entity/message';
|
||||
import { SessionStore } from 'src/app/store/session.service';
|
||||
import { MessageRepositoryService } from "src/app/module/chat/data/repository/message-respository.service"
|
||||
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(
|
||||
private MessageRepositoryService: MessageRepositoryService
|
||||
) { }
|
||||
|
||||
|
||||
async execute(input: MessageEntity) {
|
||||
|
||||
const result = await this.MessageRepositoryService.createMessage(input)
|
||||
|
||||
if(result.isOk()) {
|
||||
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { SyncMessageRepositoryService } from 'src/app/module/chat/data/service/sync-repository/sync-message-repository.service'
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class SyncLocalMessageService {
|
||||
|
||||
constructor(
|
||||
private SyncMessageRepositoryService: SyncMessageRepositoryService
|
||||
) { }
|
||||
|
||||
|
||||
async execute() {
|
||||
return this.SyncMessageRepositoryService.sendLocalMessages()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import { z } from "zod";
|
||||
import { EntityTable } from 'Dexie';
|
||||
|
||||
export const AttachmentTableSchema = z.object({
|
||||
id: z.string(),
|
||||
$id: z.string(),
|
||||
messageId: z.string(),
|
||||
file: z.string(),
|
||||
})
|
||||
|
||||
export type AttachmentTable = z.infer<typeof AttachmentTableSchema>
|
||||
export type DexieAttachmentsTableSchema = EntityTable<AttachmentTable, '$id'>;
|
||||
export const AttachmentTableColumn = '++$id, id, messageId, file'
|
||||
@@ -1,5 +1,6 @@
|
||||
import { z } from "zod";
|
||||
import { nativeEnum, z } from "zod";
|
||||
import { EntityTable } from 'Dexie';
|
||||
import { MessageAttachmentFileType, MessageAttachmentSource } from "src/app/module/chat/data/dto/message/messageOutputDTO";
|
||||
|
||||
export const MessageTable = z.object({
|
||||
$id: z.number().optional(),
|
||||
@@ -25,7 +26,14 @@ export const MessageTable = z.object({
|
||||
sender: z.object({}),
|
||||
}).array().optional(),
|
||||
info: z.array(z.object({})).optional(),
|
||||
attachments: z.array(z.object({})).optional()
|
||||
attachments: z.array(z.object({
|
||||
fileType: z.nativeEnum(MessageAttachmentFileType),
|
||||
source: z.nativeEnum(MessageAttachmentSource),
|
||||
file: z.string().optional(),
|
||||
fileName: z.string().optional(),
|
||||
applicationId: z.string().optional(),
|
||||
docId: z.string().optional()
|
||||
})).optional()
|
||||
})
|
||||
|
||||
export type MessageTable = z.infer<typeof MessageTable>
|
||||
|
||||
@@ -5,6 +5,7 @@ import { DexieMembersTableSchema, MemberTableColumn } from './schema/members';
|
||||
import { DexieRoomsTableSchema, RoomTableColumn } from './schema/room';
|
||||
import { DexieTypingsTableSchema, TypingTableColumn } from './schema/typing';
|
||||
import { MessageEntity } from '../../../domain/entity/message';
|
||||
import { AttachmentTable, AttachmentTableColumn, DexieAttachmentsTableSchema } from './schema/attachment';
|
||||
// import DexieMemory from 'dexie-in-memory';
|
||||
|
||||
// Database declaration (move this to its own module also)
|
||||
@@ -12,14 +13,16 @@ export const chatDatabase = new Dexie('chat-database-infra') as Dexie & {
|
||||
message: DexieMessageTable,
|
||||
members: DexieMembersTableSchema,
|
||||
room: DexieRoomsTableSchema,
|
||||
typing: DexieTypingsTableSchema
|
||||
typing: DexieTypingsTableSchema,
|
||||
attachment: DexieAttachmentsTableSchema,
|
||||
};
|
||||
|
||||
chatDatabase.version(1).stores({
|
||||
message: messageTableColumn,
|
||||
members: MemberTableColumn,
|
||||
room: RoomTableColumn,
|
||||
typing: TypingTableColumn
|
||||
typing: TypingTableColumn,
|
||||
attachment: AttachmentTableColumn
|
||||
});
|
||||
|
||||
chatDatabase.message.mapToClass(MessageEntity)
|
||||
|
||||
@@ -15,12 +15,12 @@ const { App } = Plugins;
|
||||
const SignalRInputSchema = z.object({
|
||||
method: z.string(),
|
||||
data: z.object({
|
||||
requestId: z.string()
|
||||
})
|
||||
requestId: z.string(),
|
||||
}).catchall(z.unknown()), // Allows any additional properties with unknown values
|
||||
})
|
||||
|
||||
|
||||
export type ISignalRInput = z.infer<typeof SignalRInputSchema>
|
||||
export type ISignalRInput = z.infer<typeof SignalRInputSchema>;
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
@@ -92,6 +92,7 @@ export class SignalRService {
|
||||
})
|
||||
|
||||
this.connection.getMessageDelete().subscribe((data) => {
|
||||
console.log('delete middleware', data)
|
||||
this.messageDelete.next(data)
|
||||
})
|
||||
|
||||
|
||||
@@ -306,7 +306,7 @@ export class SignalRConnection {
|
||||
console.log('DeleteMessage', _message)
|
||||
this.messageDelete.next(_message);
|
||||
this.sendDataSubject.next({
|
||||
method: 'ReceiveMessage',
|
||||
method: 'DeleteMessage',
|
||||
data: _message
|
||||
})
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user