diff --git a/src/app/core/chat/entity/group.ts b/src/app/core/chat/entity/group.ts index e12fe51b2..fc55b72b5 100644 --- a/src/app/core/chat/entity/group.ts +++ b/src/app/core/chat/entity/group.ts @@ -62,21 +62,26 @@ export class RoomEntity extends BaseEntity(RoomEntitySchema) implem super(); Object.assign(this, data) - if(data.roomType == RoomType.Direct) { - this.setName() + try { + if(data.roomType == RoomType.Direct) { + this.setName() - if(this.members.length == 2) { - if(!this.$id ) { - this.$id = this.getReceiverId() + if(this.members.length == 2) { + if(!this.$id ) { + this.$id = this.getReceiverId() + } + + if(!this.receiverId ) { + this.setReceiver() + } } - if(!this.receiverId ) { - this.setReceiver() - } + } - - + } catch (e) { + console.error('eee', e, this) } + } // direct room only diff --git a/src/app/module/chat/domain/use-case/room/room-bold-sync-use-case.service.ts b/src/app/module/chat/domain/use-case/room/room-bold-sync-use-case.service.ts index 9f73ce192..94f51e351 100644 --- a/src/app/module/chat/domain/use-case/room/room-bold-sync-use-case.service.ts +++ b/src/app/module/chat/domain/use-case/room/room-bold-sync-use-case.service.ts @@ -105,7 +105,7 @@ export class RoomBoldSyncUseCaseService { const room = await this.roomLocalDataSourceService.findOne({id: roomId}) - if(room.isOk()) { + if(room.isOk() && room.value) { const roomEntity = new RoomEntity(room.value) if (roomEntity.hasLastMessage()) { diff --git a/src/app/ui/chat/component/messages/messages.page.html b/src/app/ui/chat/component/messages/messages.page.html index e213350e3..6424b401f 100644 --- a/src/app/ui/chat/component/messages/messages.page.html +++ b/src/app/ui/chat/component/messages/messages.page.html @@ -164,9 +164,8 @@ - -
- +
+ {{ user }} ...
diff --git a/src/app/ui/chat/component/messages/messages.page.ts b/src/app/ui/chat/component/messages/messages.page.ts index 5c8ecffd9..679a20597 100644 --- a/src/app/ui/chat/component/messages/messages.page.ts +++ b/src/app/ui/chat/component/messages/messages.page.ts @@ -124,7 +124,7 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy roomStatus$: DexieObservable roomMessage$: DexieObservable roomMembers$: Observable - userTyping$: TypingTable[] | undefined + userTyping$: string[] newMessagesStream!: Subscription selectedMessage: any = null; @@ -253,15 +253,9 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy this.messageTypingSubject?.unsubscribe() this.messageTypingSubject = this.userTypingLocalRepository.getUserTypingLiveByRoomId(this.room.id).subscribe((e) => { const arrayNames = e.filter((b)=> b.userId != SessionStore.user.UserId).map(e => e.userName) - this.userTyping$ = e as any const uniqueArray = [...new Set(arrayNames)]; - - if(uniqueArray.length >= 1) { - (this.myInputRef.nativeElement as HTMLDivElement).innerHTML = uniqueArray + '...' - } else { - (this.myInputRef.nativeElement as HTMLDivElement).innerHTML = '' - } + this.userTyping$ = uniqueArray }) as any @@ -827,7 +821,7 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy // }) this.room.id = message.value.roomId - this.subscribeToChanges() + // this.subscribeToChanges() } } diff --git a/src/app/ui/chat/modal/messages/messages.page.html b/src/app/ui/chat/modal/messages/messages.page.html index 9c589772f..88d7dc574 100644 --- a/src/app/ui/chat/modal/messages/messages.page.html +++ b/src/app/ui/chat/modal/messages/messages.page.html @@ -10,8 +10,8 @@
- {{ room?.roomName }} - {{ RoomStore.room.roomName }} +
@@ -35,9 +35,9 @@ - + - {{ user.wxFullName }}, + {{ user.wxFullName }}, @@ -51,7 +51,7 @@
-
+
@@ -187,9 +187,8 @@ - -
- +
+ {{ user }} ...
diff --git a/src/app/ui/chat/modal/messages/messages.page.scss b/src/app/ui/chat/modal/messages/messages.page.scss index f504c5395..510ac30c5 100644 --- a/src/app/ui/chat/modal/messages/messages.page.scss +++ b/src/app/ui/chat/modal/messages/messages.page.scss @@ -102,7 +102,7 @@ } .header-bottom-contacts { - width: 275px; + // width: 275px; font-size: rem(15); color: #797979; white-space: nowrap; diff --git a/src/app/ui/chat/modal/messages/messages.page.ts b/src/app/ui/chat/modal/messages/messages.page.ts index 9537dce01..8d2a17ad7 100644 --- a/src/app/ui/chat/modal/messages/messages.page.ts +++ b/src/app/ui/chat/modal/messages/messages.page.ts @@ -10,7 +10,6 @@ import { ThemeService } from 'src/app/services/theme.service' import { VoiceRecorder, GenericResponse } from 'capacitor-voice-recorder'; import { Haptics, ImpactStyle } from '@capacitor/haptics'; -import { ViewEventPage } from 'src/app/modals/view-event/view-event.page'; import { SearchPage } from 'src/app/pages/search/search.page'; import { Storage } from '@ionic/storage'; import { CameraResultType } from '@capacitor/camera'; @@ -19,9 +18,7 @@ import { SessionStore } from 'src/app/store/session.service'; import { ViewMediaPage } from 'src/app/modals/view-media/view-media.page'; //====== -import { Observable as DexieObservable } from 'Dexie'; -import { Observable, Subscription } from 'rxjs'; -import { MessageTable } from 'src/app/infra/database/dexie/instance/chat/schema/message'; +import { Subscription } from 'rxjs'; 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 { IMessageType, MessageAttachmentFileType, MessageAttachmentSource, MessageEntity } from 'src/app/core/chat/entity/message'; @@ -31,24 +28,14 @@ import { compressImageBase64 } from 'src/app/utils/imageCompressore'; import { FilePickerService } from 'src/app/infra/file-picker/file-picker.service' import { RecordingData } from 'capacitor-voice-recorder'; import { Logger } from 'src/app/services/logger/main/service'; -import { MessagesOptionsPage } from '../messages-options/messages-options.page'; import { ChatOptionsPopoverPage } from '../chat-options-popover/chat-options-popover.page'; import { CameraService } from 'src/app/infra/camera/camera.service' import { FilePickerMobileService } from 'src/app/infra/file-picker/mobile/file-picker-mobile.service' import { FilePickerWebService } from 'src/app/infra/file-picker/web/file-picker-web.service' import { allowedDocExtension } from 'src/app/utils/allowedDocExtension'; import { JSFileToDataUrl } from 'src/app/utils/ToBase64'; -import { RoomLocalRepository } from 'src/app/module/chat/data/repository/room/room-local-repository.service' -import { MemberListLocalRepository } from 'src/app/module/chat/data/repository/member/member-list-local-repository.service' -import { UserTypingLocalRepository } from 'src/app/module/chat/data/repository/typing/user-typing-local-data-source.service'; -import { UserTypingRemoteRepositoryService } from 'src/app/module/chat/data/repository/typing/user-typing-live-data-source.service'; -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'; import { ViewOncesImagePageInput, ViewOncesImagePage } from '../view-onces/view-onces.page'; import { LastMessage } from '../../utils/lastMessage'; @@ -56,7 +43,7 @@ import { File } from '@awesome-cordova-plugins/file/ngx'; import { FileOpener } from '@awesome-cordova-plugins/file-opener/ngx'; import { FileSystemMobileService } from 'src/app/infra/file-system/mobile/file-system-mobile.service'; import { RoomViewModel } from '../../store/model/room'; - +import { RoomStore } from '../../store/roomStore' const IMAGE_DIR = 'stored-images'; @@ -78,7 +65,6 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy { dmUsers: any; roomId: string; el: any; - members: any; scrollingOnce: boolean = true; private scrollChangeCallback: () => void; @@ -88,13 +74,11 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy { showMessageOptions = false; selectedMsgId: string; - dicIndex = 0; task: ExpedientTaskModalPageNavParamsTask; LoadedDocument: any = null; recording = false; allowTyping = true; - storedFileNames = []; lastAudioRecorded = ''; audioRecorded: any = ""; audioDownloaded: any = ""; @@ -119,10 +103,6 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy { sessionStore = SessionStore SessionStore = SessionStore - roomData$: Observable - roomStatus$: DexieObservable - roomMessage$: DexieObservable - roomMembers$: Observable //userTyping$: DexieObservable userTyping$: TypingTable[] | undefined newMessagesStream!: Subscription @@ -132,19 +112,10 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy { textField = '' roomType!: RoomType - messageReceiveSubject: Subscription - messageDeleteSubject: Subscription - messageUpdateSubject: Subscription - messageSendSubject: Subscription - messages1: {[key: string]: MessageViewModal[]} = {} - MessageAttachmentFileType = MessageAttachmentFileType MessageAttachmentFileSource = MessageAttachmentSource messageOnReconnectSubject: Subscription - date: {[key: string]: Object} = {} - totalMembers = 0 - isAdmin = true RoomTypeEnum = RoomType IMessageType = IMessageType handleClickActive = false @@ -168,67 +139,14 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy { private CameraService: CameraService, private FilePickerMobileService: FilePickerMobileService, private FilePickerWebService: FilePickerWebService, - private RoomLocalRepository: RoomLocalRepository, - private MemberListLocalRepository: MemberListLocalRepository, - private userTypingLocalRepository: UserTypingLocalRepository, - private UserTypingRemoteRepositoryService: UserTypingRemoteRepositoryService, - private messageLocalDataSourceService: MessageLocalDataSourceService, private file: File, private fileOpener: FileOpener, - private fileSystemMobileService: FileSystemMobileService + private fileSystemMobileService: FileSystemMobileService, + public RoomStore: RoomStore ) { - - this.roomId = this.navParams.get('roomId'); - this.room = this.navParams.get('room'); - - console.log('room', this.room) - - - this.roomData$ = this.RoomLocalRepository.getRoomByIdLive(this.roomId) - - this.roomData$.subscribe(e => { - // console.log(e) - if(e) { - this.roomType = e.roomType - } - - }) - - this.getMessages(); - this.listenToIncomingMessage(); - this.listenToDeleteMessage(); - this.listenToUpdateMessage(); - this.listenToSendMessage(); - - - // this.roomMessage$ = this.messageRepositoryService.getItemsLive(this.roomId) - 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) - - this.userTypingLocalRepository.getUserTypingLive().subscribe((e) => { - const arrayNames = e.map(e => e.userName) - this.userTyping$ = e as any - - const uniqueArray = [...new Set(arrayNames)]; - - (this.myInputRef.nativeElement as HTMLDivElement).innerHTML = '::'+ uniqueArray - }) - - this.chatServiceService.removeBoldFromRoom({roomId: this.roomId}) - this.chatServiceService.getRoomById(this.roomId) + this.RoomStore.start(this.room) } @HostListener('document:click', ['$event']) @@ -242,107 +160,6 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy { } - async getMessages() { - - - // dont remove this line - this.messages1[this.roomId] = [] - let messages = await this.messageLocalDataSourceService.getItems(this.roomId) - - this.messages1[this.roomId] = [] - 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.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 && message.attachments[0].source != MessageAttachmentSource.Webtrix) { - - this.chatServiceService.getMessageAttachmentByMessageId(message).then((result)=> { - if(result.isOk()) { - message.attachments[0].safeFile = result.value - - if(result.value.startsWith('blob:http')) { - message.attachments[0].blobURl = true - } - } - }) - - } - } - } - messageStatus(message: MessageViewModal) { if(this.allViewed(message)) { return 'allViewed' @@ -355,11 +172,11 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy { } } allReceived(message: MessageViewModal) { - return message.info.filter(e => typeof e.deliverAt == 'string').length == this.totalMembers + return message.info.filter(e => typeof e.deliverAt == 'string').length == this.RoomStore.totalMembers } allViewed(message: MessageViewModal) { - const totalMembers = this.members.filter((e) => message.sender.wxUserId != e.wxUserId ).length + const totalMembers = this.RoomStore.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() {} @@ -406,112 +223,6 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy { } - - listenToIncomingMessage() { - this.messageReceiveSubject?.unsubscribe(); - 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.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) => { - console.log('delete class', deleteMessage); - - 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'); - // } - }); - } - - listenToUpdateMessage() { - this.messageUpdateSubject?.unsubscribe(); - - this.messageUpdateSubject = this.chatServiceService.listenToUpdateMessage(this.roomId).subscribe((updateMessage) => { - - const index = this.messages1[this.roomId].findIndex(e => e?.id === updateMessage.id); // Use triple equals for comparison - - 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'); - } - }); - } - - - listenToSendMessage() { - this.messageSendSubject?.unsubscribe(); - - this.messageSendSubject = this.chatServiceService.listenToSendMessage(this.roomId).subscribe((updateMessage) => { - - const index = this.messages1[this.roomId].findIndex(e => e?.requestId === updateMessage.requestId); // Use triple equals for comparison - - if (index !== -1) { // Check if the item was found - - this.messages1[this.roomId][index].id = updateMessage.id - this.messages1[this.roomId][index].info = updateMessage.info - - let attachmentIndex = 0; - - for(const attachment of updateMessage.attachments) { - - this.messages1[this.roomId][index].attachments[attachmentIndex].id = attachment.id - attachmentIndex++; - } - - } else { - // console.log('message not found'); - } - }); - } - async loadFiles() { this.storage.get('fileName').then((fileName) => { @@ -639,27 +350,6 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy { } catch (err) { } } - async goToEvent(event: any) { - - let classs; - if (window.innerWidth < 701) { - classs = 'modal modal-desktop' - } else { - classs = 'modal modal-desktop showAsideOptions' - } - const modal = await this.modalController.create({ - component: ViewEventPage, - componentProps: { - eventId: event.id, - CalendarId: event.calendarId - }, - cssClass: classs, - }); - await modal.present(); - modal.onDidDismiss().then((res) => { - - }); - } onContentScrolled(e) { this.startPosition = e.srcElement.scrollTop; @@ -688,37 +378,17 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy { async sendMessage() { - const message = new MessageViewModal(); - message.message = this.textField - message.roomId = this.roomId - - message.sender = { - userPhoto: '', - wxeMail: SessionStore.user.Email, - wxFullName: SessionStore.user.FullName, - wxUserId: SessionStore.user.UserId - } - message.sentAt = new Date().toISOString() + this.RoomStore.sendMessage(this.textField) 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) { - const roomId = this.roomId + const roomId = this.room.id let audioFile; this.storage.get('recordData').then(async (recordData:RecordingData) => { @@ -731,41 +401,15 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy { } const audioMimeType: string = recordData.value.mimeType - const encodedData = btoa(this.audioRecorded); - const message = new MessageViewModal(); - message.roomId = this.roomId - - message.sentAt = new Date().toISOString() - - message.sender = { - userPhoto: '', - wxeMail: SessionStore.user.Email, - wxFullName: SessionStore.user.FullName, - wxUserId: SessionStore.user.UserId - } - - message.attachments = [{ + this.RoomStore.sendMessage('', [{ file: this.audioRecorded.split(',')[1], fileName: "audio", source: MessageAttachmentSource.Device, fileType: MessageAttachmentFileType.Audio, 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() @@ -783,9 +427,6 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy { } - docIndex(index: number) { - this.dicIndex = index - } async openViewDocumentModal(file: any) { @@ -880,9 +521,9 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy { const popover = await this.popoverController.create({ component: ChatPopoverPage, componentProps: { - roomId: this.roomId, + roomId: this.room.id, members: [], - isAdmin: this.isAdmin, + isAdmin: this.RoomStore.isAdmin, roomType: this.roomType }, cssClass: 'messages-options', @@ -916,7 +557,7 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy { this.scrollToBottom(); }, 100) - this.messages1[this.roomId].splice(index, 1); + // this.messages1[this.room.id].splice(index, 1); } } @@ -940,34 +581,13 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy { if(compressedImage.isOk()) { - const message = new MessageViewModal(); - message.roomId = this.roomId - - message.sender = { - userPhoto: '', - wxeMail: SessionStore.user.Email, - wxFullName: SessionStore.user.FullName, - wxUserId: SessionStore.user.UserId - } - - message.attachments = [{ + this.RoomStore.sendMessage('', [{ file: compressedImage.value.split(',')[1], fileName: "foto", source: MessageAttachmentSource.Device, fileType: MessageAttachmentFileType.Image, 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) + }]) } @@ -994,44 +614,17 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy { await modal.present(); modal.onDidDismiss().then(async res => { const data = res.data; - const roomId = this.roomId if (data.selected) { - const message = new MessageViewModal(); - message.message = this.textField - message.roomId = this.roomId - - message.sentAt = new Date().toISOString() - - message.sender = { - userPhoto: '', - wxeMail: SessionStore.user.Email, - wxFullName: SessionStore.user.FullName, - wxUserId: SessionStore.user.UserId - } - message.attachments = [{ + this.RoomStore.sendMessage('', [{ fileName: res.data.selected.Assunto, source: MessageAttachmentSource.Webtrix, fileType: MessageAttachmentFileType.Doc, applicationId: res.data.selected.ApplicationType, docId: parseInt(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 = '' + }]) } }); @@ -1057,35 +650,14 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy { if(compressedImage.isOk()) { - const message = new MessageViewModal(); - message.roomId = this.roomId - message.sentAt = new Date().toISOString() - // message.oneShot = oneShot - message.sender = { - userPhoto: '', - wxeMail: SessionStore.user.Email, - wxFullName: SessionStore.user.FullName, - wxUserId: SessionStore.user.UserId - } - - message.attachments = [{ + this.RoomStore.sendMessage('', [{ file: compressedImage.value, fileName: "foto", source: MessageAttachmentSource.Device, fileType: MessageAttachmentFileType.Image, 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) + }]) } } @@ -1119,7 +691,7 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy { async addFileToChat(types) { console.log('add file ') - const roomId = this.roomId + const roomId = this.room.id if (this.platform.is('ios')) { console.log('ios add file ') @@ -1134,27 +706,13 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy { if(result.isOk()) { console.log('RESULT', result.value.files[0].data) - const message = new MessageViewModal(); - message.roomId = this.roomId - message.sentAt = new Date().toISOString() - - message.sender = { - userPhoto: '', - wxeMail: SessionStore.user.Email, - wxFullName: SessionStore.user.FullName, - wxUserId: SessionStore.user.UserId - } - - message.attachments = [{ + this.RoomStore.sendMessage('', [{ file: result.value.files[0].data, fileName: result.value.files[0].name, source: MessageAttachmentSource.Device, fileType: MessageAttachmentFileType.Doc, description: result.value.files[0].name - }] - - this.messages1[this.roomId].push(message) - this.chatServiceService.sendMessage(message, this.roomType) + }]) return } @@ -1179,39 +737,13 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy { if(fileBase64.isOk()) { - const message = new MessageViewModal(); - message.roomId = this.roomId - message.sentAt = new Date().toISOString() - - message.sender = { - userPhoto: '', - wxeMail: SessionStore.user.Email, - wxFullName: SessionStore.user.FullName, - wxUserId: SessionStore.user.UserId - } - - message.attachments = [{ + this.RoomStore.sendMessage('', [{ file: fileBase64.value.split(',')[1], fileName: file.value.name, source: MessageAttachmentSource.Device, fileType: MessageAttachmentFileType.Doc, 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) - + }]) } @@ -1223,7 +755,7 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy { } async openChatOptions(ev?: any) { - const roomId = this.roomId + const roomId = this.room.id const popover = await this.popoverController.create({ @@ -1231,8 +763,8 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy { cssClass: 'chat-options-popover', event: ev, componentProps: { - room: this.roomId, - members: this.members, + room: this.room.id, + members: this.RoomStore.members, eventSelectedDate: new Date(), }, translucent: true @@ -1268,55 +800,6 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy { return JSON.parse(str); } - -// async openFile(pdfString, filename, type) { - -// console.log('url while open ',pdfString) - -// /* const modal = await this.modalController.create({ -// component: ViewDocumentSecondOptionsPage, -// componentProps: { -// fileUrl: pdfString, -// filename: filename -// }, -// cssClass: 'modal modal-desktop' -// }); -// await modal.present(); -// /* -// await modal.present(); */ - -// // var blob = new Blob([pdfString], { type: 'application/pdf' }); - - -// let pathFile = '' -// const fileName = filename -// if (this.platform.is('ios')) { -// pathFile = this.file.documentsDirectory -// } else { -// pathFile = this.file.externalRootDirectory -// } - -// console.log('file data', pdfString) -// console.log(pathFile) - -// let removePre = this.removeTextBeforeSlash(pdfString,',') -// console.log('file data remove ', removePre) - -// await Filesystem.writeFile({ -// path: fileName, -// data: removePre, -// directory: Directory.Cache, -// }).then((dir) => { -// console.log('DIR ', dir) -// this.fileOpener -// .open(dir.uri, type) -// .then(() => console.log()) -// .catch(e => console.error(e)) -// }).catch((error) => { -// console.log('error writing the file', error) -// }); -// } - async fetchBlobFromURL(blobUrl: string): Promise { try { const response = await fetch(blobUrl); @@ -1345,35 +828,6 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy { }); } - // async openFile(blobUrl:string, filename, fileType) { - // console.log(blobUrl, filename, fileType) - // let pathFile: string; - - // if (this.platform.is('ios')) { - // pathFile = this.file.documentsDirectory - // } else { - // pathFile = this.file.externalRootDirectory - // } - - // let a = await this.fetchBlobFromURL(blobUrl) - - // console.log({e:await this.convertBlobToDataURL(a)}) - // let removePre = this.removeTextBeforeSlash(await this.convertBlobToDataURL(a),',') - - // Filesystem.writeFile({ - // path: filename, - // data: removePre, - // directory: Directory.Cache, - - // }).then(dir => { - // console.log('DIR ', dir) - // this.fileOpener - // .open(dir.uri, fileType) - // .then(() => console.log()) - // .catch(e => console.error(e)) - // }) - // .catch(e => console.log('Error writing file', e)) - // } async openFile(blobUrl:string, filename, fileType) { @@ -1394,14 +848,7 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy { } } - removeTextBeforeSlash(inputString, controlString) { - if (inputString.includes(controlString)) { - const parts = inputString.split(controlString); - return parts.length > 1 ? parts[1] : inputString; - } else { - return inputString; - } - } + downloadFileFromBrowser(fileName: string, msg: MessageViewModal): void { if(msg.attachments[0]?.blobURl) { @@ -1497,23 +944,9 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy { } - // dataURItoBlobIso(dataURI: any) { - // const byteString = window.atob(dataURI); - // const arrayBuffer = new ArrayBuffer(byteString.length); - // const int8Array = new Uint8Array(arrayBuffer); - // for (let i = 0; i < byteString.length; i++) { - // int8Array[i] = byteString.charCodeAt(i); - // } - // const blob = new Blob([int8Array], { type: 'application/pdf' }); - // return blob; - // } - - messageDelete(message: MessageViewModal) { - this.chatServiceService.messageDelete({ - messageId: message.id, - roomId: this.roomId, - }) + + this.RoomStore.messageDelete(message) } async editMessage(message: any) { @@ -1523,7 +956,7 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy { cssClass: 'edit-message', componentProps: { message: message.message, - roomId: this.roomId, + roomId: this.room.id, } }); @@ -1532,12 +965,11 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy { return modal.onDidDismiss().then((res) => { if(res.data) { - this.chatServiceService.updateMessage({ - memberId: SessionStore.user.UserId, - message: res.data.message, - messageId: message.id, - requestId: '', - roomId: this.roomId + + + this.RoomStore.updateMessage({ + messageId:message.id, + message: res.data.message }) } @@ -1555,20 +987,13 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy { addReaction(message: any, emoji: string) { // Logic to add reaction to the message - console.log(`Reacting to message ${message.id} with emoji ${emoji.codePointAt(0).toString(16)}`); this.selectedMessage = null; // Close the picker after adding reaction - this.chatServiceService.reactToMessage({ - memberId: SessionStore.user.UserId, - messageId: message.id, - roomId: this.roomId, - reaction: emoji, - requestId: '' - }) + this.RoomStore.addReaction(message, emoji) } sendTyping() { - this.UserTypingRemoteRepositoryService.sendTyping(this.roomId) + this.RoomStore.sendTyping() } } diff --git a/src/app/ui/chat/store/roomStore.ts b/src/app/ui/chat/store/roomStore.ts index 7cda3c435..a55cf5c00 100644 --- a/src/app/ui/chat/store/roomStore.ts +++ b/src/app/ui/chat/store/roomStore.ts @@ -3,51 +3,454 @@ import { MessageViewModal } from './model/message'; import { MessageLocalDataSourceService } from 'src/app/module/chat/data/repository/message/message-local-data-source.service'; import { whatsappDate } from '../../shared/utils/whatappdate'; import { XBallon } from '../utils/messageBallon'; +import { Observable, Subscription } from 'rxjs'; +import { RoomTable } from 'src/app/infra/database/dexie/instance/chat/schema/room'; +import { RoomLocalRepository } from 'src/app/module/chat/data/repository/room/room-local-repository.service' +import { RoomViewModel } from './model/room'; +import { IDBoolean } from 'src/app/infra/database/dexie/type'; +import { ChatServiceService } from 'src/app/module/chat/domain/chat-service.service'; +import { MessageAttachmentSource, MessageEntitySchema } from 'src/app/core/chat/entity/message'; +import { SessionStore } from 'src/app/store/session.service'; +import { Logger } from 'src/app/services/logger/main/service'; +import { Observable as DexieObservable } from 'Dexie'; +import { tap } from 'rxjs/operators'; +import { MemberTable } from 'src/app/infra/database/dexie/instance/chat/schema/members'; +import { MessageTable } from 'src/app/infra/database/dexie/instance/chat/schema/message'; +import { TypingTable } from 'src/app/infra/database/dexie/instance/chat/schema/typing'; +import { MemberListLocalRepository } from 'src/app/module/chat/data/repository/member/member-list-local-repository.service' +import { UserTypingLocalRepository } from 'src/app/module/chat/data/repository/typing/user-typing-local-data-source.service'; +import { Result } from 'neverthrow'; +import { MessageOutPutDataDTO } from 'src/app/core/chat/repository/dto/messageOutputDTO'; +import { UserTypingRemoteRepositoryService } from 'src/app/module/chat/data/repository/typing/user-typing-live-data-source.service'; @Injectable({ providedIn: 'root' }) export class RoomStore { - roomId: string; + messages1: {[key: string]: MessageViewModal[]} = {} + room!: RoomViewModel date: {[key: string]: Object} = {} + messageReceiveSubject: Subscription + messageDeleteSubject: Subscription + messageUpdateSubject: Subscription + messageSendSubject: Subscription + messageTypingSubject: Subscription + messageOnReconnectSubject: Subscription + messageOnSetRoomId: Subscription + newMessagesStream!: Subscription + + roomData$: Observable + roomStatus$: DexieObservable + roomMessage$: DexieObservable + roomMembers$: Observable + userTyping$: string[] = [] + + totalMembers = 0 + members: MemberTable[] = [] + isAdmin = true; + + scrollToBottomClicked = ()=> {} constructor( private messageLocalDataSourceService: MessageLocalDataSourceService, + private RoomLocalRepository: RoomLocalRepository, + private chatServiceService: ChatServiceService, + private MemberListLocalRepository: MemberListLocalRepository, + private userTypingLocalRepository: UserTypingLocalRepository, + private UserTypingRemoteRepositoryService: UserTypingRemoteRepositoryService, ) {} - openRoom() { + async start(room: RoomViewModel) { + + this.room = room + + if(this.room.local == IDBoolean.false) { + this.subscribeToChanges() + await this.getMessages() + } else { + await this.getMessages() + } + } + + stop() { + this.messageReceiveSubject?.unsubscribe(); + this.messageReceiveSubject?.unsubscribe(); + this.messageDeleteSubject?.unsubscribe(); + this.messageUpdateSubject?.unsubscribe(); + this.messageSendSubject?.unsubscribe(); + this.messageTypingSubject?.unsubscribe(); + this.messageOnReconnectSubject?.unsubscribe(); + this.messageOnSetRoomId?.unsubscribe(); + this.newMessagesStream?.unsubscribe(); + } + + subscribeToChanges() { + this.listenToIncomingMessage(); + this.listenToDeleteMessage(); + this.listenToUpdateMessage(); + this.listenToSendMessage(); + + this.roomMembers$ = this.MemberListLocalRepository.getRoomMemberByIdLive(this.room.id).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.room.id) + + this.messageTypingSubject?.unsubscribe() + this.messageTypingSubject = this.userTypingLocalRepository.getUserTypingLiveByRoomId(this.room.id).subscribe((e) => { + const arrayNames = e.filter((b)=> b.userId != SessionStore.user.UserId).map(e => e.userName) + + const uniqueArray = [...new Set(arrayNames)]; + this.userTyping$ = uniqueArray + + }) as any + + this.updateRoomDetails() + } + + + listenToSendMessage() { + this.messageSendSubject?.unsubscribe(); + + this.messageSendSubject = this.chatServiceService.listenToSendMessage(this.room.id).subscribe((updateMessage) => { + + const index = this.messages1[this.room.$id].findIndex(e => e?.requestId === updateMessage.requestId); // Use triple equals for comparison + + if (index !== -1) { // Check if the item was found + + this.messages1[this.room.$id][index].id = updateMessage.id + this.messages1[this.room.$id][index].info = updateMessage.info + + let attachmentIndex = 0; + + for(const message of updateMessage.attachments) { + + this.messages1[this.room.$id][index].attachments[attachmentIndex].id = message.id + attachmentIndex++; + } + + } else { + console.log('not found message to update ui'); + } + }); + } + + listenToUpdateMessage() { + this.messageUpdateSubject?.unsubscribe(); + + console.log('liste to update') + this.messageUpdateSubject = this.chatServiceService.listenToUpdateMessage(this.room.id).subscribe((updateMessage) => { + + const index = this.messages1[this.room.$id].findIndex(e => e?.id === updateMessage.id); // Use triple equals for comparison + + if (index !== -1) { // Check if the item was found + this.messages1[this.room.$id][index].info = updateMessage.info + this.messages1[this.room.$id][index].message = updateMessage.message + this.messages1[this.room.$id][index].reactions = updateMessage.reactions + } else { + // console.log('message not found'); + } + }); + } + + + listenToIncomingMessage() { + this.messageReceiveSubject?.unsubscribe(); + this.messageReceiveSubject = this.chatServiceService.listenToIncomingMessage(this.room.id).subscribe(async (_message) => { + + const date = whatsappDate(_message.sentAt, false) + if(!this.date[date]) { + this.date[date] = true + const Ballon = XBallon(_message) + this.messages1[this.room.$id].push(Ballon) + } + + const message = new MessageViewModal(_message) + this.messages1[this.room.$id].push(new MessageViewModal(message)) + + if(message.hasAttachment) { + + 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.removeBold() + }, 1000) + }); } - messages1: {[key: string]: MessageViewModal[]} = {} + + removeBold() { + if(!this.room?.local) { + this.chatServiceService.removeBoldFromRoom({roomId: this.room.$id}) + } + } + + listenToDeleteMessage() { + this.messageDeleteSubject?.unsubscribe(); + + this.messageDeleteSubject = this.chatServiceService.listenToDeleteMessage(this.room.id).subscribe((deleteMessage) => { + console.log('delete class', deleteMessage); + + const index = this.messages1[this.room.$id].findIndex(e => + typeof e?.id == 'string' && e?.id === deleteMessage.id || + typeof e?.requestId == 'string' && e?.requestId == deleteMessage.requestId); + + try { + console.log(this.messages1[this.room.$id][index]) + this.messages1[this.room.$id][index].delete() + } catch (e) { + console.log('delete', e) + } + }); + } async getMessages() { // dont remove this line - this.messages1[this.roomId] = [] - let messages = await this.messageLocalDataSourceService.getItems(this.roomId) + this.messages1[this.room.$id] = [] - this.messages1[this.roomId] = [] - this.date = {} - const allMessage = []; + let messages = await this.chatServiceService.messageLocalGetById({ + roomId: this.room.id, + receiverId: this.room?.receiverId?.toString() + }) - 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) + if(messages.isOk()) { + this.messages1[this.room.$id] = [] + this.date = {} + const allMessage = []; + + console.time("mappingTime"); + const sortMessages = messages.value.sort((a, b) => new Date(a.sentAt).getTime() - new Date(b.sentAt).getTime()) + + for(const message of sortMessages) { + 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.room.$id] + this.messages1[this.room.$id] = allMessage + + + + // if(messages.length >= 1) { + // this.messages1[this.room.$id].push(LastMessage) + // } + + this.loadAttachment() + setTimeout(() => { + this.sendReadMessage() + }, 1000) + + if(this.room.$id) { + this.onReconnectGetMessages() } - allMessage.push(new MessageViewModal(message)) } - console.timeEnd("mappingTime"); - this.messages1[this.roomId] = allMessage + } + + async loadAttachment() { + for(const message of this.messages1[this.room.$id]) { + if(message.hasAttachment && message.attachments[0].source != MessageAttachmentSource.Webtrix) { + + this.chatServiceService.getMessageAttachmentByMessageId(message).then((result)=> { + if(result.isOk()) { + message.attachments[0].safeFile = result.value + + if(result.value.startsWith('blob:http')) { + message.attachments[0].blobURl = true + } + } + }) + + } + } + } + + sendReadMessage() { + + if(this.room.local == IDBoolean.false) { + for(const message of this.messages1[this.room.$id]) { + + 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.room.id + }) + } else { + console.log('no need', message ) + } + } + } + } else { + console.log('dont read for this room') + } + } + + onReconnectGetMessages() { + this.messageOnReconnectSubject?.unsubscribe() + this.messageOnReconnectSubject = this.chatServiceService.listenToMessageLoadHistory({roomId: this.room.id}).subscribe((messages) => { + + for(const message of messages.data) { + const found = this.messages1[this.room.$id].find((e) => e.id == message.id) + + if(!found) { + const msg = new MessageViewModal(message as any) + Object.assign(msg, message) + this.messages1[this.room.$id].push(msg) + } + } + + this.messages1[this.room.$id].sort((a, b) => { + return new Date(a.sentAt).getTime() - new Date(b.sentAt).getTime() + }) + }) + } + + + updateRoomDetails() { + this.chatServiceService.getRoomById(this.room.id) + } + + + createMessage() { + const message = new MessageViewModal(); + + if(this.room.id) { + message.roomId = this.room.id + } + + message.sentAt = new Date().toISOString() + + message.sender = { + userPhoto: '', + wxeMail: SessionStore.user.Email, + wxFullName: SessionStore.user.FullName, + wxUserId: SessionStore.user.UserId + } + + message.sentAt = new Date().toISOString() + if(this.room.receiverId) { + message.receiverId = this.room.receiverId + } + + return message + } + + async messageResult(result: Promise> ) { + let message = await result + + + if(message.isOk() && this.room.local == IDBoolean.true) { + this.room.local = IDBoolean.false; + + // console.log('enter') + // await this.chatServiceService.roomSetLocalToFalseById({ + // $roomId: this.room.$id, + // roomId: message.value.roomId + // }) + + this.room.id = message.value.roomId + // this.subscribeToChanges() + } + } + + + addReaction(message: any, emoji: string) { + // Logic to add reaction to the message + console.log(`Reacting to message ${message.id} with emoji ${emoji.codePointAt(0).toString(16)}`); + + this.chatServiceService.reactToMessage({ + memberId: SessionStore.user.UserId, + messageId: message.id, + roomId: this.room.id, + reaction: emoji, + requestId: '' + }) + + } + + sendTyping() { + this.UserTypingRemoteRepositoryService.sendTyping(this.room.id) + } + + updateMessage({messageId, message}) { + this.chatServiceService.updateMessage({ + memberId: SessionStore.user.UserId, + message, + messageId, + requestId: '', + roomId: this.room.id + }) + } + + messageDelete(message: MessageViewModal) { + this.chatServiceService.messageDelete({ + messageId: message.id, + roomId: this.room.id, + }) + } + + + async sendMessage(text:string, attachment?: typeof MessageEntitySchema._type.attachments) { + + const message = this.createMessage(); + message.message = text + + const date = whatsappDate(message.sentAt, false) + if(!this.date[date]) { + this.date[date] = true + const Ballon = XBallon(message) + this.messages1[this.room.$id].push(Ballon) + } + + if(attachment) { + message.attachments = attachment + } + + this.messages1[this.room.$id].push(message) + let sendMessage = this.chatServiceService.sendMessage(message, this.room.roomType) + this.messageResult(sendMessage) - // if(messages.length >= 1) { - // this.messages1[this.roomId].push(LastMessage) - // } } } diff --git a/version/git-version.ts b/version/git-version.ts index 161943121..06ab192a8 100644 --- a/version/git-version.ts +++ b/version/git-version.ts @@ -1,11 +1,11 @@ export let versionData = { - "shortSHA": "8d332f73a", - "SHA": "8d332f73a8dafc3ea98b2eb8e35322d89d185883", + "shortSHA": "a4d81a68e", + "SHA": "a4d81a68e6bcc0593aa28a328cc175e2a86960e6", "branch": "feature/chat-new-api-peter", "lastCommitAuthor": "'Peter Maquiran'", - "lastCommitTime": "'Wed Sep 18 12:32:31 2024 +0100'", - "lastCommitMessage": "fix bold", - "lastCommitNumber": "6080", - "changeStatus": "On branch feature/chat-new-api-peter\nYour branch is up to date with 'origin/feature/chat-new-api-peter'.\n\nChanges to be committed:\n (use \"git restore --staged ...\" to unstage)\n\tnew file: doc/database.md\n\tmodified: src/app/infra/database/dexie/service.ts\n\tmodified: src/app/module/chat/domain/use-case/room/room-bold-sync-use-case.service.ts\n\tmodified: src/app/module/chat/domain/use-case/room/room-set-last-message.service.ts\n\tmodified: src/app/ui/chat/component/contacts/contacts.page.ts", + "lastCommitTime": "'Wed Sep 18 15:24:50 2024 +0100'", + "lastCommitMessage": "add documentation and remove console logs", + "lastCommitNumber": "6081", + "changeStatus": "On branch feature/chat-new-api-peter\nYour branch is ahead of 'origin/feature/chat-new-api-peter' by 1 commit.\n (use \"git push\" to publish your local commits)\n\nChanges to be committed:\n (use \"git restore --staged ...\" to unstage)\n\tmodified: src/app/core/chat/entity/group.ts\n\tmodified: src/app/module/chat/domain/use-case/room/room-bold-sync-use-case.service.ts\n\tmodified: src/app/ui/chat/component/messages/messages.page.html\n\tmodified: src/app/ui/chat/component/messages/messages.page.ts\n\tmodified: src/app/ui/chat/modal/messages/messages.page.html\n\tmodified: src/app/ui/chat/modal/messages/messages.page.scss\n\tmodified: src/app/ui/chat/modal/messages/messages.page.ts\n\tmodified: src/app/ui/chat/store/roomStore.ts\n\tmodified: version/git-version.ts", "changeAuthor": "peter.maquiran" } \ No newline at end of file