mirror of
https://code.equilibrium.co.ao/ITO/doneit-web.git
synced 2026-04-19 13:02:56 +00:00
create offline direct message
This commit is contained in:
@@ -26,7 +26,7 @@ export function messageListDetermineChanges(serverList: MessageTable[], localLis
|
||||
item.$id = localItem.$id
|
||||
}
|
||||
|
||||
return localItem && (item.editedAt !== localItem.editedAt || item.sentAt != item.sentAt || item.reactions.some((r, index) => {
|
||||
return localItem && (item.editedAt !== localItem.editedAt || item.isDeleted !== localItem.isDeleted || item.sentAt != item.sentAt || item.reactions.some((r, index) => {
|
||||
const localReaction = localItem.reactions[index];
|
||||
return !localReaction || r.reactedAt !== localReaction.reactedAt;
|
||||
}));
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { RoomType } from "src/app/core/chat/entity/group";
|
||||
import { RoomTable } from "src/app/infra/database/dexie/instance/chat/schema/room";
|
||||
import { RoomListItemOutPutDTO } from "src/app/module/chat/domain/use-case/room/room-get-list-use-case.service";
|
||||
import { SessionStore } from "src/app/store/session.service";
|
||||
|
||||
export function roomListDetermineChanges(serverRooms: RoomListItemOutPutDTO[], localRooms: RoomTable[]) {
|
||||
const serverRoomMap = new Map(serverRooms.map(room => [room.chatRoom.id, room]));
|
||||
@@ -8,7 +9,7 @@ export function roomListDetermineChanges(serverRooms: RoomListItemOutPutDTO[], l
|
||||
|
||||
const roomsToInsert = serverRooms.filter(room => !localRoomMap.has(room.chatRoom.id));
|
||||
const roomsToUpdate = serverRooms.filter(room => {
|
||||
const localRoom = localRoomMap.get(room.chatRoom.id);
|
||||
const localRoom = localRoomMap.get(room.chatRoom.id);
|
||||
|
||||
return localRoom && (
|
||||
room.chatRoom.roomName !== localRoom.roomName && room.chatRoom.roomType == RoomType.Group ||
|
||||
|
||||
@@ -5,10 +5,11 @@ import { DexieRepository } from 'src/app/infra/repository/dexie/dexie-repository
|
||||
import { Observable as DexieObservable, PromiseExtended } from 'Dexie';
|
||||
import { DexieMessageTable, MessageTable, MessageTableSchema } from 'src/app/infra/database/dexie/instance/chat/schema/message';
|
||||
import { chatDatabase } from 'src/app/infra/database/dexie/service';
|
||||
import { IMessageLocalRepository } from 'src/app/core/chat/repository/message/message-local-repository';
|
||||
import { IDirectMessages, IMessageLocalRepository } from 'src/app/core/chat/repository/message/message-local-repository';
|
||||
import { BehaviorSubject, combineLatest, from, Observable } from 'rxjs';
|
||||
import { filter, map } from 'rxjs/operators';
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import { err, ok } from 'neverthrow';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
@@ -79,9 +80,6 @@ export class MessageLocalDataSourceService extends DexieRepository<MessageTable,
|
||||
return chatDatabase.message.where('roomId').equals(roomId).sortBy('sentAt') as any
|
||||
}
|
||||
|
||||
getItemsLive(roomId: string): DexieObservable<MessageEntity[]> {
|
||||
return liveQuery(() => chatDatabase.message.where('roomId').equals(roomId).sortBy('sentAt') as any)
|
||||
}
|
||||
|
||||
async getOfflineMessages () {
|
||||
try {
|
||||
@@ -96,7 +94,6 @@ export class MessageLocalDataSourceService extends DexieRepository<MessageTable,
|
||||
}
|
||||
|
||||
|
||||
|
||||
getLastMessageForRooms(roomIds: string[]): Observable<any[]> {
|
||||
const observables = roomIds.map(roomId =>
|
||||
from (liveQuery(async() =>{
|
||||
@@ -114,5 +111,20 @@ export class MessageLocalDataSourceService extends DexieRepository<MessageTable,
|
||||
|
||||
return combineLatest(observables); // Combine all observables into one array of results
|
||||
}
|
||||
|
||||
async getDirectMessages(input: IDirectMessages) {
|
||||
try {
|
||||
const result = await chatDatabase.message
|
||||
.where('receiverId')
|
||||
.equals(input.receiverId)
|
||||
.or('roomId')
|
||||
.equals(input.roomId)
|
||||
.toArray()
|
||||
|
||||
return ok(result as MessageEntity[])
|
||||
} catch (e) {
|
||||
return err(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,19 +1,38 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { liveQuery, Observable } from 'Dexie';
|
||||
import { DexieRepository } from 'src/app/infra/repository/dexie/dexie-repository.service';
|
||||
import { from } from 'rxjs';
|
||||
import { BehaviorSubject, from } from 'rxjs';
|
||||
import { RoomTable, RoomTableSchema } from 'src/app/infra/database/dexie/instance/chat/schema/room';
|
||||
import { chatDatabase } from 'src/app/infra/database/dexie/service';
|
||||
import { IRoomLocalRepository } from 'src/app/core/chat/repository/room/room-local-repository';
|
||||
import { IDBoolean } from 'src/app/infra/database/dexie/type';
|
||||
import { RoomType } from 'src/app/core/chat/entity/group';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class RoomLocalRepository extends DexieRepository<RoomTable, RoomTable> implements IRoomLocalRepository {
|
||||
|
||||
private listenCreateSyncSubject : BehaviorSubject<RoomTable> = new BehaviorSubject<RoomTable>(null);
|
||||
|
||||
constructor() {
|
||||
super(chatDatabase.room, RoomTableSchema)
|
||||
|
||||
chatDatabase.room.hook('creating', (primaryKey, obj, transaction) => {
|
||||
|
||||
if(obj.id && !obj.$id && obj.roomType == RoomType.Group) {
|
||||
obj.$id = obj.id
|
||||
}
|
||||
|
||||
if(obj.id) {
|
||||
obj.local = IDBoolean.false
|
||||
} else {
|
||||
obj.local = IDBoolean.true
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
chatDatabase.room.hook('updating', (modifications, primKey, oldValue, transaction) => {
|
||||
|
||||
// if((modifications as Partial<RoomTable>).messages?.[0].requestId == oldValue.messages?.[0].requestId) {
|
||||
@@ -22,6 +41,12 @@ export class RoomLocalRepository extends DexieRepository<RoomTable, RoomTable> i
|
||||
// (modifications as Partial<RoomTable>).messages[0].sentAt = oldValue.messages?.[0]?.sentAt
|
||||
// }
|
||||
|
||||
if((modifications as Partial<RoomTable>).id || oldValue.id) {
|
||||
(modifications as Partial<RoomTable>).local = IDBoolean.false
|
||||
} else {
|
||||
(modifications as Partial<RoomTable>).local = IDBoolean.true
|
||||
}
|
||||
|
||||
return modifications
|
||||
});
|
||||
|
||||
|
||||
@@ -42,8 +42,13 @@ import { BoldRemoveByRoomIdInput, BoldRemoveByRoomIdService } from 'src/app/modu
|
||||
import { MemberListHttpSyncUseCase } from 'src/app/module/chat/domain/use-case/member/member-list-http-sync-use-case.ts.service'
|
||||
import { RoomBoldSyncUseCaseService } from 'src/app/module/chat/domain/use-case/room/room-bold-sync-use-case.service'
|
||||
import { RoomSetLastMessageService } from 'src/app/module/chat/domain/use-case/room/room-set-last-message.service';
|
||||
import { RoomCreateLocalDirectMessageInputDTOInputDTO, RoomCreateLocalDirectMessageService } from 'src/app/module/chat/domain/use-case/room/room-create-local-direct-message.service';
|
||||
import { RoomGetListOnCreateUseCaseService } from 'src/app/module/chat/domain/use-case/room/room-get-list-on-create-use-case.service';
|
||||
import { IRoomSetLocalToFalseByIdInput, RoomSetLocalToFalseByIdService } from 'src/app/module/chat/domain/use-case/room/room-set-local-to-false-by-id.service';
|
||||
import { IUserPhotoGetByIdInput, UserPhotoGetByIdUseCase } from 'src/app/module/chat/domain/use-case/user-photo/user-photo-get-by-id-use-case.service'
|
||||
import { IMessageLocalGetByIdServiceInput, MessageLocalGetByIdService } from 'src/app/module/chat/domain/use-case/message/message-local-get-by-id.service'
|
||||
import { ContactListService } from './use-case/contact/contact-list.service';
|
||||
import { IRoomGetLocalByIdServiceInput, RoomGetLocalByIdService } from './use-case/room/room-getlocal-by-id.service';
|
||||
|
||||
|
||||
export const getInstanceId = (): string => {
|
||||
@@ -103,7 +108,12 @@ export class ChatServiceService {
|
||||
private RoomBoldSyncUseCaseService: RoomBoldSyncUseCaseService, // dont remove
|
||||
private RoomSetLastMessageService: RoomSetLastMessageService, // dont remove
|
||||
private UserPhotoGetByIdUseCase: UserPhotoGetByIdUseCase,
|
||||
private RoomGetListOnCreateUseCaseService: RoomGetListOnCreateUseCaseService
|
||||
private RoomGetListOnCreateUseCaseService: RoomGetListOnCreateUseCaseService,
|
||||
private RoomCreateLocalDirectMessageService: RoomCreateLocalDirectMessageService,
|
||||
private contactListService: ContactListService,
|
||||
private messageLocalGetByIdService: MessageLocalGetByIdService,
|
||||
private roomGetLocalByIdService: RoomGetLocalByIdService,
|
||||
private roomSetLocalToFalseByIdService: RoomSetLocalToFalseByIdService
|
||||
) {
|
||||
this.MessageSocketRepositoryService.listenToDeleteMessages()
|
||||
.pipe()
|
||||
@@ -160,6 +170,17 @@ export class ChatServiceService {
|
||||
await this.asyncAllRoomMessage();
|
||||
}
|
||||
|
||||
messageLocalGetById(input: IMessageLocalGetByIdServiceInput) {
|
||||
return this.messageLocalGetByIdService.execute(input)
|
||||
}
|
||||
roomGetLocalById(input: IRoomGetLocalByIdServiceInput) {
|
||||
return this.roomGetLocalByIdService.execute(input)
|
||||
}
|
||||
|
||||
roomSetLocalToFalseById(input: IRoomSetLocalToFalseByIdInput) {
|
||||
return this.roomSetLocalToFalseByIdService.execute(input)
|
||||
}
|
||||
|
||||
removeMemberToRoom(data: UserRemoveListInputDTO) {
|
||||
return this.RemoveMemberUseCaseService.execute(data)
|
||||
}
|
||||
@@ -262,6 +283,15 @@ export class ChatServiceService {
|
||||
return this.MessageMarkAsReadUseCaseService.execute(sendReadAt)
|
||||
}
|
||||
|
||||
|
||||
roomCreateLocalDirectMessage(input: RoomCreateLocalDirectMessageInputDTOInputDTO) {
|
||||
return this.RoomCreateLocalDirectMessageService.execute(input)
|
||||
}
|
||||
|
||||
getContactList() {
|
||||
return this.contactListService.execute()
|
||||
}
|
||||
|
||||
markAllMessagesAsRead(input: MessageMarkAllMessageAsReadByRoomIdInputSchema) {
|
||||
return this.MessageMarkAllMessageAsReadByRoomIdService.execute(input)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { RoomType } from 'src/app/core/chat/entity/group';
|
||||
import { IRoomLocalRepository } from 'src/app/core/chat/repository/room/room-local-repository';
|
||||
import { ContactRepositoryService } from 'src/app/services/Repositorys/contacts/repository/contacts-repository.service';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class ContactListService {
|
||||
|
||||
constructor(
|
||||
private contactsRepositoryService: ContactRepositoryService,
|
||||
private roomLocalRepository: IRoomLocalRepository
|
||||
) {}
|
||||
|
||||
async execute() {
|
||||
const [userContact, localDirectRooms] = await Promise.all([
|
||||
this.contactsRepositoryService.getUsers(),
|
||||
this.roomLocalRepository.find({roomType: RoomType.Direct})
|
||||
])
|
||||
|
||||
if(userContact.isOk() && localDirectRooms.isOk()) {
|
||||
const existNames = localDirectRooms.value.map(e => e.roomName);
|
||||
|
||||
return userContact.map((list) => {
|
||||
|
||||
return list.data.result.filter((e) => {
|
||||
return !existNames.includes(e.wxFullName)
|
||||
})
|
||||
})
|
||||
} else if (userContact.isErr()) {
|
||||
return userContact
|
||||
} else if (localDirectRooms.isErr()) {
|
||||
return localDirectRooms
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -157,25 +157,9 @@ export class MessageCreateUseCaseService {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const DTO = MessageMapper.fromDomain(message, message.requestId)
|
||||
delete DTO.roomId
|
||||
sendMessageResult = await this.messageSocketRepositoryService.sendDirectMessage(DTO)
|
||||
}
|
||||
|
||||
// return this sendMessageResult
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { IMessageLocalRepository } from 'src/app/core/chat/repository/message/message-local-repository';
|
||||
import { z } from 'zod';
|
||||
|
||||
const messageLocalGetByIdServiceInputSchema = z.object({
|
||||
roomId: z.string().uuid().optional(),
|
||||
receiverId: z.string().optional(),
|
||||
})
|
||||
|
||||
export type IMessageLocalGetByIdServiceInput = z.infer<typeof messageLocalGetByIdServiceInputSchema>
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class MessageLocalGetByIdService {
|
||||
|
||||
constructor(
|
||||
private messageLocalRepository: IMessageLocalRepository
|
||||
) { }
|
||||
|
||||
execute(input: IMessageLocalGetByIdServiceInput) {
|
||||
if(input.roomId && input.receiverId) {
|
||||
|
||||
return this.messageLocalRepository.getDirectMessages({
|
||||
roomId: input.roomId,
|
||||
receiverId: input.receiverId
|
||||
})
|
||||
}
|
||||
else if(input.roomId) {
|
||||
return this.messageLocalRepository.find({roomId: input.roomId})
|
||||
} else if (input.receiverId) {
|
||||
return this.messageLocalRepository.find({receiverId: parseInt(input.receiverId)})
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+14
-16
@@ -9,9 +9,9 @@ import { RoomLocalRepository } from '../../../data/repository/room/room-local-re
|
||||
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 { MessageTable } from 'src/app/infra/database/dexie/instance/chat/schema/message';
|
||||
import { MessageOutPutDataDTO } from 'src/app/core/chat/repository/dto/messageOutputDTO';
|
||||
import { IDBoolean } from 'src/app/infra/database/dexie/type';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
@@ -36,9 +36,12 @@ export class SendLocalMessagesUseCaseService {
|
||||
if(allRooms.value.length == 0) {
|
||||
|
||||
} else {
|
||||
//const removeLocalRooms = allRooms.value.filter((e)=> e.local == IDBoolean.false)
|
||||
|
||||
console.log({localM: messages});
|
||||
|
||||
for(const message of messages) {
|
||||
const room = allRooms.value.find(e => e.id == message.roomId)
|
||||
const room = allRooms.value.find(e => e.id == message.roomId || e.$id == message.roomId)
|
||||
|
||||
if(room) {
|
||||
|
||||
@@ -68,21 +71,16 @@ export class SendLocalMessagesUseCaseService {
|
||||
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
|
||||
const DTO = MessageMapper.fromDomain(message, message.requestId)
|
||||
sendMessageResult = await this.messageSocketRepositoryService.sendDirectMessage(DTO)
|
||||
|
||||
if(sendMessageResult.isOk() && room.local == IDBoolean.true) {
|
||||
|
||||
this.roomLocalDataSourceService.update(room.$id, {
|
||||
local: IDBoolean.false,
|
||||
id: sendMessageResult.value.roomId
|
||||
})
|
||||
if(getRoomMembers.isOk() && getRoomMembers.value) {
|
||||
message.receiverId = getRoomMembers.value.wxUserId
|
||||
const DTO = MessageMapper.fromDomain(message, message.requestId)
|
||||
sendMessageResult = await this.messageSocketRepositoryService.sendGroupMessage(DTO)
|
||||
} else {
|
||||
console.error('direct users not found', getRoomMembers)
|
||||
}
|
||||
room.local = IDBoolean.false
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import { RoomLocalRepository } from '../../../data/repository/room/room-local-re
|
||||
import { Logger } from 'src/app/services/logger/main/service';
|
||||
import { XTracerAsync, TracingType } from 'src/app/services/monitoring/opentelemetry/tracer';
|
||||
import { MessageTable } from 'src/app/infra/database/dexie/instance/chat/schema/message';
|
||||
import { IDBoolean } from 'src/app/infra/database/dexie/type';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
@@ -34,7 +35,10 @@ export class SyncAllRoomMessagesService {
|
||||
}
|
||||
|
||||
let n =0
|
||||
const roomPromises = allRooms.value.map(async (room) => {
|
||||
|
||||
const removeLocalRooms = allRooms.value.filter((e)=> e.local != IDBoolean.true)
|
||||
|
||||
const roomPromises = removeLocalRooms.map(async (room) => {
|
||||
const [result, localResult] = await Promise.all([
|
||||
this.messageRemoteDataSourceService.getMessagesFromRoom(room.id),
|
||||
this.messageLocalDataSourceService.getItems(room.id)
|
||||
@@ -46,8 +50,9 @@ export class SyncAllRoomMessagesService {
|
||||
if (result.isOk()) {
|
||||
const { addedItems, changedItems, deletedItems } = messageListDetermineChanges(result.value.data, localResult);
|
||||
|
||||
console.log({changedItems})
|
||||
for (const message of changedItems) {
|
||||
delete message.sentAt
|
||||
|
||||
let clone: MessageTable = { ...message, roomId: room.id };
|
||||
this.messageLocalDataSourceService.update(clone.$id, clone);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { z } from 'zod';
|
||||
import { IRoomLocalRepository } from 'src/app/core/chat/repository/room/room-local-repository';
|
||||
import { SessionStore } from 'src/app/store/session.service';
|
||||
import { RoomType } from 'src/app/core/chat/entity/group';
|
||||
import { IDBoolean } from 'src/app/infra/database/dexie/type';
|
||||
|
||||
|
||||
export const RoomCreateLocalDirectMessageInputDTOSchema = z.object({
|
||||
roomName: z.string(),
|
||||
members: z.array(z.number()),
|
||||
receiverId: z.number().optional(),
|
||||
});
|
||||
export type RoomCreateLocalDirectMessageInputDTOInputDTO = z.infer<typeof RoomCreateLocalDirectMessageInputDTOSchema>
|
||||
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class RoomCreateLocalDirectMessageService {
|
||||
|
||||
constructor(
|
||||
private roomLocalRepository: IRoomLocalRepository
|
||||
) { }
|
||||
|
||||
async execute(input: RoomCreateLocalDirectMessageInputDTOInputDTO) {
|
||||
return await this.roomLocalRepository.insert({
|
||||
roomName: input.roomName,
|
||||
bold: 0,
|
||||
createdAt: new Date().toISOString(),
|
||||
createdBy: {
|
||||
userPhoto: '',
|
||||
wxeMail: SessionStore.user.Email,
|
||||
wxFullName: SessionStore.user.FullName,
|
||||
wxUserId: SessionStore.user.UserId
|
||||
},
|
||||
$id: input.receiverId.toString(),
|
||||
messages: [],
|
||||
roomType: RoomType.Direct,
|
||||
local: IDBoolean.true,
|
||||
receiverId: input.receiverId,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -27,16 +27,24 @@ export class DeleteRoomUseCaseService {
|
||||
|
||||
if(result.isOk()) {
|
||||
|
||||
const result = await this.roomLocalDataSourceService.delete(id)
|
||||
// this.messageLiveDataSourceService.sendMessage({
|
||||
// type: 'createRoom',
|
||||
// payload: {a: '5'}
|
||||
// })
|
||||
const room = await this.roomLocalDataSourceService.findOne({
|
||||
id: id
|
||||
})
|
||||
|
||||
if(room.isOk()) {
|
||||
const result = await this.roomLocalDataSourceService.delete(room.value.$id)
|
||||
}
|
||||
|
||||
return result
|
||||
} else if (isHttpResponse(result.error)) {
|
||||
if(result.error.status == 404) {
|
||||
await this.roomLocalDataSourceService.delete(id)
|
||||
const room = await this.roomLocalDataSourceService.findOne({
|
||||
id: id
|
||||
})
|
||||
|
||||
if(room.isOk()) {
|
||||
const result = await this.roomLocalDataSourceService.delete(room.value.$id)
|
||||
}
|
||||
}
|
||||
// this.httpErrorHandle.httpStatusHandle(result.error)
|
||||
}
|
||||
|
||||
@@ -59,6 +59,8 @@ export class GetRoomByIdUseCaseService {
|
||||
|
||||
@captureAndReraiseAsync('RoomRepositoryService/getRoomById')
|
||||
async execute(id: RoomByIdInputDTO) {
|
||||
|
||||
console.log('iiiiiiiiiiii', id)
|
||||
const result = await this.roomRemoteDataSourceService.getRoom(id)
|
||||
|
||||
if(result.isOk()) {
|
||||
|
||||
@@ -7,6 +7,9 @@ import { IRoomRemoteRepository } from 'src/app/core/chat/repository/room/room-re
|
||||
import { IRoomLocalRepository } from 'src/app/core/chat/repository/room/room-local-repository';
|
||||
import { MessageEntitySchema } from 'src/app/core/chat/entity/message';
|
||||
import { GetRoomListMapper } from 'src/app/core/chat/mapper/getRoomListMapper';
|
||||
import { IDBoolean } from 'src/app/infra/database/dexie/type';
|
||||
import { RoomType } from 'src/app/core/chat/entity/group';
|
||||
import { Logger } from 'src/app/services/logger/main/service';
|
||||
|
||||
|
||||
const CreatedBySchema = z.object({
|
||||
@@ -64,12 +67,44 @@ export class GetRoomListUseCaseService {
|
||||
if(localList.isOk()) {
|
||||
if(result.isOk()) {
|
||||
|
||||
const { roomsToDelete, roomsToInsert, roomsToUpdate } = roomListDetermineChanges(result.value.data, localList.value)
|
||||
const filterValidateRooms = result.value.data.filter(e => {
|
||||
if(e.chatRoom.roomType == RoomType.Direct) {
|
||||
|
||||
if(e.chatRoom.user1 != null && e.chatRoom.user2 != null) {
|
||||
return true
|
||||
} else {
|
||||
Logger.error("direct room invalid data", {
|
||||
data: e.chatRoom,
|
||||
user1: e.chatRoom.user1,
|
||||
user2: e.chatRoom.user2
|
||||
})
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
})
|
||||
|
||||
const { roomsToDelete, roomsToInsert, roomsToUpdate } = roomListDetermineChanges(filterValidateRooms, localList.value)
|
||||
|
||||
console.log({roomsToDelete, roomsToInsert, roomsToUpdate})
|
||||
|
||||
if(roomsToInsert) {
|
||||
const roomsToInsertEntity = GetRoomListMapper.toDomain(roomsToInsert)
|
||||
for( const room of roomsToInsertEntity) {
|
||||
this.roomLocalDataSourceService.insert(room)
|
||||
|
||||
this.roomLocalDataSourceService.insert(room).then((result) => {
|
||||
|
||||
if( result.isErr() &&
|
||||
room.roomType == RoomType.Direct &&
|
||||
result.error.DBErrorName == 'ConstraintError') {
|
||||
this.roomLocalDataSourceService.update(room.$id, room).then((result) => {
|
||||
if(result.isErr()) {
|
||||
console.log('failed to update room id')
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
if(room.expirationDate) {
|
||||
this.CronJobService.createCronJob('remove expired room', new Date(room.expirationDate), this.execute)
|
||||
}
|
||||
@@ -80,7 +115,9 @@ export class GetRoomListUseCaseService {
|
||||
this.roomLocalDataSourceService.updateMany(roomsToUpdateEntity)
|
||||
|
||||
for( const room of roomsToDelete) {
|
||||
this.roomLocalDataSourceService.delete(room.id)
|
||||
if(room.local == IDBoolean.false) {
|
||||
this.roomLocalDataSourceService.delete(room.id)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { IRoomLocalRepository } from 'src/app/core/chat/repository/room/room-local-repository';
|
||||
import { z } from 'zod';
|
||||
|
||||
const RoomGetLocalByIdServiceInputSchema = z.object({
|
||||
$roomId: z.string()
|
||||
})
|
||||
|
||||
export type IRoomGetLocalByIdServiceInput = z.infer<typeof RoomGetLocalByIdServiceInputSchema >
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class RoomGetLocalByIdService {
|
||||
|
||||
constructor(
|
||||
private roomLocalDataSourceService: IRoomLocalRepository,
|
||||
) { }
|
||||
|
||||
async execute(input: IRoomGetLocalByIdServiceInput) {
|
||||
return await this.roomLocalDataSourceService.findOne({$id: input.$roomId})
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import { IMessageGetAllByRoomIdOutPut } from 'src/app/core/chat/usecase/message/
|
||||
import { RoomEntity } from 'src/app/core/chat/entity/group';
|
||||
import { RoomTable } from 'src/app/infra/database/dexie/instance/chat/schema/room';
|
||||
import { IMessageLocalRepository } from 'src/app/core/chat/repository/message/message-local-repository';
|
||||
import { messageListDetermineChanges } from '../../../data/async/list/rooms/messageListChangedetector';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
@@ -42,9 +43,16 @@ export class RoomSetLastMessageService {
|
||||
for(const room of roomList) {
|
||||
if(room.messages?.[0]?.id == message.id) {
|
||||
console.log('listenToUpdateMessage', message.roomId)
|
||||
const result = await this.roomLocalRepository.update(message.roomId, {
|
||||
|
||||
const result = await this.roomLocalRepository.update(room.$id, {
|
||||
messages: [message]
|
||||
})
|
||||
|
||||
if(result.isErr()) {
|
||||
console.log('failed to update last message')
|
||||
} else {
|
||||
console.log('set last message')
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -54,10 +62,19 @@ export class RoomSetLastMessageService {
|
||||
|
||||
for(const room of roomList) {
|
||||
if(room.messages?.[0]?.id == message.id) {
|
||||
console.log({...room.messages?.[0],isDeleted: true})
|
||||
const result = await this.roomLocalRepository.update(message.roomId, {
|
||||
messages: [{...room.messages?.[0],isDeleted: true}]
|
||||
|
||||
// incoming _message does not have sender
|
||||
const messageToUpdate = ({...room.messages?.[0],isDeleted: true})
|
||||
|
||||
const result = await this.roomLocalRepository.update(room.$id, {
|
||||
messages: [messageToUpdate]
|
||||
})
|
||||
|
||||
if(result.isErr()) {
|
||||
console.log('failed to update last message')
|
||||
} else {
|
||||
console.log('set last message')
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -69,31 +86,61 @@ export class RoomSetLastMessageService {
|
||||
).subscribe(async (message) => {
|
||||
if(message?.roomId) {
|
||||
console.log('listenToIncomingMessage', message.roomId)
|
||||
const result = await this.roomLocalRepository.update(message.roomId, {
|
||||
messages: [message]
|
||||
|
||||
const findRoom = await this.roomLocalRepository.findOne({
|
||||
id: message.roomId
|
||||
})
|
||||
|
||||
if(result.isErr()) {
|
||||
console.log('failed to update last message')
|
||||
} else {
|
||||
console.log('set last message')
|
||||
if(findRoom.isOk() && findRoom.value) {
|
||||
const result = await this.roomLocalRepository.update(findRoom.value.$id, {
|
||||
messages: [message]
|
||||
})
|
||||
|
||||
if(result.isErr()) {
|
||||
console.log('failed to update last message')
|
||||
} else {
|
||||
console.log('set last message')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
// local storage
|
||||
private listenToOnSendDataToSocket() {
|
||||
this.messageLocalRepository.onCreateObservable().subscribe(async (message) => {
|
||||
if(message?.roomId) {
|
||||
|
||||
setTimeout(async() => {
|
||||
if(message.origin != 'history') {
|
||||
const result = await this.roomLocalRepository.update(message.roomId, {
|
||||
messages: [message]
|
||||
|
||||
const findRoom = await this.roomLocalRepository.findOne({
|
||||
id: message.roomId
|
||||
})
|
||||
|
||||
if(findRoom.isOk() && findRoom.value) {
|
||||
const result = await this.roomLocalRepository.update(findRoom.value.$id, {
|
||||
messages: [message]
|
||||
})
|
||||
|
||||
if(result.isErr()) {
|
||||
console.log('failed to update last message')
|
||||
} else {
|
||||
console.log('set last message')
|
||||
}
|
||||
} else if (message.receiverId) {
|
||||
// direct message and first message
|
||||
const findRoom = await this.roomLocalRepository.findOne({
|
||||
receiverId: message.receiverId
|
||||
})
|
||||
|
||||
if(findRoom.isOk() && findRoom.value) {
|
||||
const result = await this.roomLocalRepository.update(findRoom.value.$id, {
|
||||
messages: [message]
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}, 100)
|
||||
}
|
||||
@@ -128,17 +175,47 @@ export class RoomSetLastMessageService {
|
||||
const loadHistoryLastMessageDate = new Date(loadHistoryFirstMessage.sentAt).getTime()
|
||||
|
||||
if(loadHistoryFirstMessage.id == room.value.messages?.[0]?.id) {
|
||||
const { addedItems, changedItems, deletedItems } = messageListDetermineChanges([loadHistoryFirstMessage], room.value.messages);
|
||||
|
||||
for (const message of changedItems) {
|
||||
|
||||
const result = await this.roomLocalRepository.update(room.value.$id, {
|
||||
messages: [message]
|
||||
})
|
||||
}
|
||||
// do nothing
|
||||
} else if(loadHistoryLastMessageDate>localLastMessageDate) {
|
||||
await this.roomLocalRepository.update(loadHistoryFirstMessage.roomId, {
|
||||
// await this.roomLocalRepository.update(loadHistoryFirstMessage.roomId, {
|
||||
// messages: [loadHistoryFirstMessage]
|
||||
// })
|
||||
|
||||
const result = await this.roomLocalRepository.update(room.value.$id, {
|
||||
messages: [loadHistoryFirstMessage]
|
||||
})
|
||||
|
||||
if(result.isErr()) {
|
||||
console.log('failed to update last message')
|
||||
} else {
|
||||
console.log('set last message')
|
||||
}
|
||||
|
||||
} else if(loadHistoryLastMessageDate == localLastMessageDate) {
|
||||
// do nothing
|
||||
} else if(room.value.messages[0].isDeleted != loadHistoryFirstMessage.isDeleted) {
|
||||
await this.roomLocalRepository.update(loadHistoryFirstMessage.roomId, {
|
||||
// await this.roomLocalRepository.update(loadHistoryFirstMessage.roomId, {
|
||||
// messages: [loadHistoryFirstMessage]
|
||||
// })
|
||||
|
||||
const result = await this.roomLocalRepository.update(room.value.$id, {
|
||||
messages: [loadHistoryFirstMessage]
|
||||
})
|
||||
|
||||
if(result.isErr()) {
|
||||
console.log('failed to update last message')
|
||||
} else {
|
||||
console.log('set last message')
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { IRoomLocalRepository } from 'src/app/core/chat/repository/room/room-local-repository';
|
||||
import { IDBoolean } from 'src/app/infra/database/dexie/type';
|
||||
import { z } from 'zod';
|
||||
|
||||
const RoomSetLocalToFalseByIdInputSchema = z.object({
|
||||
$roomId: z.string(),
|
||||
roomId: z.string()
|
||||
})
|
||||
|
||||
export type IRoomSetLocalToFalseByIdInput = z.infer<typeof RoomSetLocalToFalseByIdInputSchema >
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class RoomSetLocalToFalseByIdService {
|
||||
|
||||
constructor(
|
||||
private roomLocalDataSourceService: IRoomLocalRepository,
|
||||
) { }
|
||||
|
||||
execute(input: IRoomSetLocalToFalseByIdInput) {
|
||||
return this.roomLocalDataSourceService.update(input.$roomId, {
|
||||
local: IDBoolean.false,
|
||||
id: input.roomId
|
||||
})
|
||||
}
|
||||
}
|
||||
+11
-6
@@ -2,6 +2,7 @@ import { Injectable } from '@angular/core';
|
||||
import { MessageLocalDataSourceService } from '../../../data/repository/message/message-local-data-source.service';
|
||||
import { MessageEntitySchema } from 'src/app/core/chat/entity/message';
|
||||
import { z } from 'zod';
|
||||
import { TracingType, XTracerAsync } from 'src/app/services/monitoring/opentelemetry/tracer';
|
||||
|
||||
const SocketMessageDeleteOutputSchema = MessageEntitySchema.pick({
|
||||
id: true,
|
||||
@@ -35,13 +36,17 @@ export class SocketMessageDeleteUseCaseService {
|
||||
) { }
|
||||
|
||||
|
||||
async execute(input: ISocketMessageDeleteOutput) {
|
||||
const result = await this.messageLocalDataSourceService.update(input.id, { isDeleted: true})
|
||||
@XTracerAsync({name:'Socket-Message-Delete-UseCase', module:'chat', bugPrint: true})
|
||||
async execute(input: ISocketMessageDeleteOutput, tracing?: TracingType) {
|
||||
const result = await this.messageLocalDataSourceService.findOne({id: input.id})
|
||||
|
||||
if(result.isOk()) {
|
||||
console.log('deleled', result.value)
|
||||
} else {
|
||||
console.log(result.error)
|
||||
if(result.isOk() && result.value) {
|
||||
|
||||
tracing?.addEvent("Message found")
|
||||
const updateResult = await this.messageLocalDataSourceService.update(result.value.$id, { isDeleted: true })
|
||||
return updateResult
|
||||
}else {
|
||||
tracing.hasError("failed to delete message")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user