replicate to mobile

This commit is contained in:
Peter Maquiran
2024-09-06 14:38:30 +01:00
parent 27eeebb767
commit e7887d4e5a
10 changed files with 399 additions and 79 deletions
+253 -50
View File
@@ -24,7 +24,7 @@ import { Observable, Subscription } from 'rxjs';
import { MessageTable } from 'src/app/infra/database/dexie/instance/chat/schema/message';
import { ChatServiceService } from 'src/app/module/chat/domain/chat-service.service';
import { EditMessagePage } from 'src/app/ui/chat/modal/edit-message/edit-message.page';
import { MessageAttachmentFileType, MessageAttachmentSource, MessageEntity } from 'src/app/core/chat/entity/message';
import { IMessageType, MessageAttachmentFileType, MessageAttachmentSource } from 'src/app/core/chat/entity/message';
import { MemberTable } from 'src/app/infra/database/dexie/instance/chat/schema/members';
import { TypingTable } from 'src/app/infra/database/dexie/instance/chat/schema/typing';
import { compressImageBase64 } from 'src/app/utils/imageCompressore';
@@ -45,6 +45,11 @@ import { UserTypingRemoteRepositoryService } from 'src/app/module/chat/data/repo
import { MessageLocalDataSourceService } from 'src/app/module/chat/data/repository/message/message-local-data-source.service';
import { RoomType } from "src/app/core/chat/entity/group";
import { RoomTable } from 'src/app/infra/database/dexie/instance/chat/schema/room';
import { whatsappDate } from 'src/app/ui/shared/utils/whatappdate';
import { MessageViewModal } from '../../store/model/message';
import { XBallon } from '../../utils/messageBallon';
import { tap } from 'rxjs/operators';
import { ChatPopoverPage } from '../chat-popover/chat-popover.page';
@@ -107,11 +112,12 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
audioPermissionStatus: 'granted' | 'denied' | 'prompt' | null = null
sessionStore = SessionStore
SessionStore = SessionStore
roomData$: Observable<RoomTable | undefined>
roomStatus$: DexieObservable<Boolean >
roomMessage$: DexieObservable<MessageTable[]>
roomMembers$: DexieObservable<MemberTable[] | undefined>
roomMembers$: Observable<MemberTable[]>
//userTyping$: DexieObservable<TypingTable[] | undefined>
userTyping$: TypingTable[] | undefined
newMessagesStream!: Subscription
@@ -125,10 +131,18 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
messageDeleteSubject: Subscription
messageUpdateSubject: Subscription
messageSendSubject: Subscription
messages1: {[key: string]: MessageEntity[]} = {}
messages1: {[key: string]: MessageViewModal[]} = {}
MessageAttachmentFileType = MessageAttachmentFileType
MessageAttachmentFileSource = MessageAttachmentSource
messageOnReconnectSubject: Subscription
date: {[key: string]: Object} = {}
totalMembers = 0
isAdmin = true
RoomTypeEnum = RoomType
IMessageType = IMessageType
constructor(
public popoverController: PopoverController,
@@ -176,7 +190,17 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
// this.roomMessage$ = this.messageRepositoryService.getItemsLive(this.roomId)
this.roomMembers$ = this.MemberListLocalRepository.getRoomMemberByIdLive(this.roomId) as any
this.roomMembers$ = this.MemberListLocalRepository.getRoomMemberByIdLive(this.roomId).pipe(
tap((members) => {
this.totalMembers = members.length
this.members = members
for(const member of members) {
if(member.wxUserId == SessionStore.user.UserId) {
this.isAdmin = member.isAdmin
}
}
})
)
this.roomStatus$ = this.MemberListLocalRepository.allMemberOnline(this.roomId)
// this.roomRepositoryService.getRoomById(this.roomId)
@@ -189,47 +213,130 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
(this.myInputRef.nativeElement as HTMLDivElement).innerHTML = '::'+ uniqueArray
})
this.chatServiceService.removeBoldFromRoom({roomId: this.roomId})
this.chatServiceService.getRoomById(this.roomId)
}
async getMessages() {
// dont remove this line
this.messages1[this.roomId] = []
let messages = await this.messageLocalDataSourceService.getItems(this.roomId)
this.messages1[this.roomId] = []
this.messages1[this.roomId] = messages
this.loadAttachment()
this.date = {}
const allMessage = [];
// let ids = {}
// messages = messages.filter((message: any) => {
// if (message.$createAt) {
// if (!ids[message.$createAt]) {
// ids[message.$createAt] = true;
// return true; // Keep this message
// } else {
// console.log('delete');
// return false; // Remove this message
// }
// }
// return true; // Keep messages without an id
// });
console.time("mappingTime");
for(const message of messages) {
const date = whatsappDate(message.sentAt, false)
if(!this.date[date]) {
this.date[date] = true
const Ballon = XBallon(message)
allMessage.push(Ballon)
}
allMessage.push(new MessageViewModal(message))
}
console.timeEnd("mappingTime");
this.messages1[this.roomId] = allMessage
this.loadAttachment()
setTimeout(() => {
this.scrollToBottomClicked()
}, 100)
this.sendReadMessage()
}, 1000)
this.messageOnReconnectSubject?.unsubscribe()
this.messageOnReconnectSubject = this.chatServiceService.listenToMessageLoadHistory({roomId: this.roomId}).subscribe((messages) => {
for(const message of messages.data) {
const found = this.messages1[this.roomId].find((e) => e.id == message.id)
if(!found) {
const msg = new MessageViewModal(message as any)
Object.assign(msg, message)
this.messages1[this.roomId].push(msg)
}
}
})
}
sendReadMessage() {
for(const message of this.messages1[this.roomId]) {
if(!message.meSender()) {
const me = message.haveSeen(message.info)
if(!me) {
Logger.info('send read at, sender '+ message.sender.wxFullName+ ' '+ message.message +'message id'+ message.id)
this.chatServiceService.sendReadAt({
memberId: SessionStore.user.UserId,
messageId: message.id,
requestId: '',
roomId: this.roomId
})
}
}
}
}
async loadAttachment() {
for(const message of this.messages1[this.roomId]) {
if(message.hasAttachment) {
console.log('get attachment')
if(message.hasAttachment && message.attachments[0].source != MessageAttachmentSource.Webtrix) {
this.chatServiceService.getMessageAttachmentByMessageId(message).then((result)=> {
if(result.isOk()) {
message.attachments[0].safeFile = result.value
const result = await this.chatServiceService.getMessageAttachmentByMessageId(message)
if(result.value.startsWith('blob:http')) {
message.attachments[0].blobURl = true
}
}
})
console.log('result')
if(result.isOk()) {
console.log(result.value, message)
message.attachments[0].safeFile = result.value
} else {
console.log('error', result.error)
}
}
}
}
messageStatus(message: MessageViewModal) {
if(this.allViewed(message)) {
return 'allViewed'
} else if(this.allReceived(message)) {
return 'allReceived'
} else if (message.messageStatus == 'send') {
return 'enviado'
} else {
return 'enviar'
}
}
allReceived(message: MessageViewModal) {
return message.info.filter(e => typeof e.deliverAt == 'string').length == this.totalMembers
}
allViewed(message: MessageViewModal) {
const totalMembers = this.members.filter((e) => message.sender.wxUserId != e.wxUserId ).length
return message.info.filter(e => typeof e.readAt == 'string' && message.sender.wxUserId != e.memberId ).length == totalMembers
}
ngOnInit() {}
@@ -277,38 +384,62 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
listenToIncomingMessage() {
this.messageReceiveSubject?.unsubscribe();
this.messageReceiveSubject = this.chatServiceService.listenToIncomingMessage(this.roomId).subscribe(async (message) => {
this.messages1[this.roomId].push(message as MessageEntity)
this.messageReceiveSubject = this.chatServiceService.listenToIncomingMessage(this.roomId).subscribe(async (_message) => {
const date = whatsappDate(_message.sentAt, false)
if(!this.date[date]) {
this.date[date] = true
const Ballon = XBallon(_message)
this.messages1[this.roomId].push(Ballon)
}
const message = new MessageViewModal(_message)
this.messages1[this.roomId].push(new MessageViewModal(message))
if(message.hasAttachment) {
const result = await this.chatServiceService.getMessageAttachmentByMessageId(message)
const result = await this.chatServiceService.downloadMessageAttachmentByMessageId({
$messageId: message.id,
id: message.attachments[0].id
})
if(result.isOk()) {
message.attachments[0].safeFile = result.value
if((result.value as unknown as string).startsWith('blob:http')) {
message.attachments[0].blobURl = true
} else {
message.attachments[0].blobURl = false
}
}
}
setTimeout(() => {
this.scrollToBottomClicked()
}, 100)
setTimeout(() => {
this.chatServiceService.removeBoldFromRoom({roomId: this.roomId})
}, 1000)
});
}
listenToDeleteMessage() {
this.messageDeleteSubject?.unsubscribe();
this.messageDeleteSubject = this.chatServiceService.listenToDeleteMessage(this.roomId).subscribe((deleteMessage) => {
const index = this.messages1[this.roomId].findIndex(e => e?.id === deleteMessage.id); // Use triple equals for comparison
console.log('delete class', deleteMessage);
if (index !== -1) { // Check if the item was found
this.messages1[this.roomId].splice(index, 1);
// console.log('removed index', index);
} else {
// console.log('message not found');
}
const index = this.messages1[this.roomId].findIndex(e => e?.id === deleteMessage.id); // Use triple equals for comparison
this.messages1[this.roomId][index].delete()
// if (index !== -1) { // Check if the item was found
// console.log('delete ==')
// this.messages1[this.roomId].splice(index, 1);
// // console.log('removed index', index);
// } else {
// // console.log('message not found');
// }
});
}
@@ -322,6 +453,7 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
if (index !== -1) { // Check if the item was found
this.messages1[this.roomId][index].message = updateMessage.message
this.messages1[this.roomId][index].reactions = updateMessage.reactions
this.messages1[this.roomId][index].reactions = updateMessage.reactions
} else {
// console.log('message not found');
}
@@ -528,8 +660,9 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
window.removeEventListener('scroll', this.scrollChangeCallback, true);
}
sendMessage() {
const message = new MessageEntity();
async sendMessage() {
const message = new MessageViewModal();
message.message = this.textField
message.roomId = this.roomId
@@ -539,11 +672,23 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
wxFullName: SessionStore.user.FullName,
wxUserId: SessionStore.user.UserId
}
this.chatServiceService.sendMessage(message, this.roomType)
this.messages1[this.roomId].push(message)
message.sentAt = new Date().toISOString()
this.textField = ''
const date = whatsappDate(message.sentAt, false)
if(!this.date[date]) {
this.date[date] = true
const Ballon = XBallon(message)
this.messages1[this.roomId].push(Ballon)
}
this.messages1[this.roomId].push(message)
setTimeout(() => {
this.scrollToBottomClicked()
}, 100)
const data = await this.chatServiceService.sendMessage(message, this.roomType)
}
async sendAudio(fileName) {
@@ -559,13 +704,12 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
this.audioRecorded = `data:${recordData.value.mimeType};base64,${recordData?.value?.recordDataBase64}`;
}
const audioMimeType: string = recordData.value.mimeType
//Converting base64 to blob
const encodedData = btoa(this.audioRecorded);
const message = new MessageEntity();
const message = new MessageViewModal();
message.roomId = this.roomId
message.sentAt = new Date().toISOString()
message.sender = {
@@ -580,16 +724,29 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
fileName: "audio",
source: MessageAttachmentSource.Device,
fileType: MessageAttachmentFileType.Audio,
mimeType: audioMimeType,
mimeType: audioMimeType, // 'audio/webm',
safeFile: this.sanitiser.bypassSecurityTrustResourceUrl(this.audioRecorded)
}]
message.sentAt = new Date().toISOString()
const date = whatsappDate(message.sentAt, false)
if(!this.date[date]) {
this.date[date] = true
const Ballon = XBallon(message)
this.messages1[this.roomId].push(Ballon)
}
this.messages1[this.roomId].push(message)
this.chatServiceService.sendMessage(message, this.roomType)
setTimeout(() => {
this.scrollToBottomClicked()
}, 100)
this.deleteRecording();
});
this.deleteRecording();
}
@@ -701,9 +858,12 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
async openMessagesOptions(ev?: any) {
const popover = await this.popoverController.create({
component: MessagesOptionsPage,
component: ChatPopoverPage,
componentProps: {
roomId: this.roomId,
members: [],
isAdmin: this.isAdmin,
roomType: this.roomType
},
cssClass: 'messages-options',
event: ev,
@@ -747,7 +907,7 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
if(compressedImage.isOk()) {
const message = new MessageEntity();
const message = new MessageViewModal();
message.roomId = this.roomId
message.sender = {
@@ -765,6 +925,14 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
mimeType: 'image/'+picture.value.format
}]
const date = whatsappDate(message.sentAt, false)
if(!this.date[date]) {
this.date[date] = true
const Ballon = XBallon(message)
this.messages1[this.roomId].push(Ballon)
}
this.messages1[this.roomId].push(message)
this.chatServiceService.sendMessage(message, this.roomType)
@@ -797,10 +965,12 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
if (data.selected) {
const message = new MessageEntity();
const message = new MessageViewModal();
message.message = this.textField
message.roomId = this.roomId
message.sentAt = new Date().toISOString()
message.sender = {
userPhoto: '',
wxeMail: SessionStore.user.Email,
@@ -813,9 +983,20 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
fileType: MessageAttachmentFileType.Doc,
applicationId: res.data.selected.ApplicationType,
docId: res.data.selected.Id,
description: res.data.selected.Assunto
}]
const date = whatsappDate(message.sentAt, false)
if(!this.date[date]) {
this.date[date] = true
const Ballon = XBallon(message)
this.messages1[this.roomId].push(Ballon)
}
this.messages1[this.roomId].push(message)
setTimeout(() => {
this.scrollToBottomClicked()
}, 100)
this.chatServiceService.sendMessage(message, this.roomType)
this.textField = ''
@@ -843,8 +1024,10 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
if(compressedImage.isOk()) {
const message = new MessageEntity();
const message = new MessageViewModal();
message.roomId = this.roomId
message.sentAt = new Date().toISOString()
// message.oneShot = oneShot
message.sender = {
userPhoto: '',
@@ -861,6 +1044,13 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
mimeType: 'image/'+file.value.format
}]
const date = whatsappDate(message.sentAt, false)
if(!this.date[date]) {
this.date[date] = true
const Ballon = XBallon(message)
this.messages1[this.roomId].push(Ballon)
}
this.messages1[this.roomId].push(message)
this.chatServiceService.sendMessage(message, this.roomType)
}
@@ -895,8 +1085,9 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
if(result.isOk()) {
console.log('RESULT', result.value.files[0].data)
const message = new MessageEntity();
const message = new MessageViewModal();
message.roomId = this.roomId
message.sentAt = new Date().toISOString()
message.sender = {
userPhoto: '',
@@ -938,8 +1129,9 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
if(fileBase64.isOk()) {
const message = new MessageEntity();
const message = new MessageViewModal();
message.roomId = this.roomId
message.sentAt = new Date().toISOString()
message.sender = {
userPhoto: '',
@@ -956,7 +1148,18 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
mimeType: file.value.type
}]
const date = whatsappDate(message.sentAt, false)
if(!this.date[date]) {
this.date[date] = true
const Ballon = XBallon(message)
this.messages1[this.roomId].push(Ballon)
}
this.messages1[this.roomId].push(message)
setTimeout(() => {
this.scrollToBottomClicked()
}, 100)
this.chatServiceService.sendMessage(message, this.roomType)
}
@@ -1182,7 +1385,7 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
// }
messageDelete(message: MessageEntity) {
messageDelete(message: MessageViewModal) {
this.chatServiceService.messageDelete({
messageId: message.id,
roomId: this.roomId,