Files
doneit-web/src/app/module/chat/domain/use-case/room/room-set-last-message.service.ts
T
Peter Maquiran 9c8ecc182f fix chat
2024-10-08 13:16:01 +01:00

245 lines
8.3 KiB
TypeScript

import { Injectable } from '@angular/core';
import { IMessageSocketRepository } from 'src/app/core/chat/repository/message/message-socket-repository';
import { IRoomLocalRepository } from 'src/app/core/chat/repository/room/room-local-repository';
import { filter, map, tap } from 'rxjs/operators';
import { MessageEntity } from 'src/app/core/chat/entity/message';
import { HttpAdapter } from 'src/app/infra/http/adapter';
import { IMessageGetAllByRoomIdOutPut } from 'src/app/core/chat/usecase/message/message-get-all-by-room-Id';
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';
import { IDBoolean } from 'src/app/infra/database/dexie/type';
@Injectable({
providedIn: 'root'
})
export class RoomSetLastMessageService {
constructor(
private roomLocalRepository: IRoomLocalRepository,
private messageSocketRepository: IMessageSocketRepository,
private messageLocalRepository: IMessageLocalRepository,
private http: HttpAdapter,
) {
this.listenToIncomingMessage()
this.listenToOnSendDataToSocket()
this.loadHistory()
this.listenToUpdateMessage()
}
private listenToUpdateMessage() {
let roomList: RoomTable[] = []
this.roomLocalRepository.getItemsLive().pipe(
tap((_roomList) => {
roomList = _roomList
})
).subscribe();
this.messageSocketRepository.listenToUpdateMessages().subscribe(async(_message) => {
const message = {..._message}
for(const room of roomList) {
if(room.messages?.[0]?.id == message.id) {
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')
}
}
}
})
this.messageSocketRepository.listenToDeleteMessages().subscribe(async(_message) => {
const message = {..._message}
for(const room of roomList) {
if(room.messages?.[0]?.id == message.id) {
// 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')
}
}
}
})
}
private listenToIncomingMessage() {
return this.messageSocketRepository.listenToMessages()
.subscribe(async (e) => {
const message = Object.assign(new MessageEntity(), e.data)
if(message?.roomId) {
console.log('listenToIncomingMessage', message.roomId)
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 (findRoom.isOk() && !findRoom.value && e.payload.receiverId) {
// console.log('new room', e)
const findLocalDirectRoom = await this.roomLocalRepository.findOne({
receiverId: e.payload.receiverId
})
if(findLocalDirectRoom.isOk() && findLocalDirectRoom.value) {
findLocalDirectRoom.value.id = message.roomId
findLocalDirectRoom.value.local = IDBoolean.false
findLocalDirectRoom.value.messages = [message];
await findLocalDirectRoom.value.save()
}
}
}
});
}
// local storage
private listenToOnSendDataToSocket() {
this.messageLocalRepository.onCreateObservable().subscribe(async (message) => {
if(message?.roomId) {
setTimeout(async() => {
if(message.origin != 'history') {
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)
}
})
}
private loadHistory() {
const regex = new RegExp("Room\\/([0-9a-fA-F]{8})-([0-9a-fA-F]{4})-([0-9a-fA-F]{4})-([0-9a-fA-F]{4})-([0-9a-fA-F]{12})\\/Messages");
return this.http.listen().pipe(
filter((response: any)=> {
return response?.isOk() && regex.test(response.value.url) && response.value.url.endsWith('/Messages')
}),
map((response: any) => response.value.data as IMessageGetAllByRoomIdOutPut)
).subscribe(async (data)=> {
const loadHistoryFirstMessage = data.data[0]
if(loadHistoryFirstMessage) {
const roomId = loadHistoryFirstMessage.roomId
const room = await this.roomLocalRepository.findOne({id: roomId})
if(room.isOk() && room.value) {
const roomEntity = new RoomEntity(room.value)
if(!roomEntity.hasLastMessage()) {
await this.roomLocalRepository.update(loadHistoryFirstMessage.roomId, {
messages: [loadHistoryFirstMessage]
})
} else if (roomEntity.hasLastMessage()) {
const localLastMessageDate = new Date(room.value.messages[0].sentAt).getTime()
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, {
// 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, {
// 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 {
console.log('cant find room locally')
}
}
})
}
}