diff --git a/src/app/core/chat/entity/group.ts b/src/app/core/chat/entity/group.ts index d77f79c36..7c885ca4d 100644 --- a/src/app/core/chat/entity/group.ts +++ b/src/app/core/chat/entity/group.ts @@ -67,6 +67,6 @@ export class RoomEntity extends BaseEntity(RoomEntitySchema) implem } hasLastMessage() { - return this.messages.length >= 1 + return this.messages?.length >= 1 } } diff --git a/src/app/core/chat/entity/message.ts b/src/app/core/chat/entity/message.ts index c4ce9568f..a37a5947e 100644 --- a/src/app/core/chat/entity/message.ts +++ b/src/app/core/chat/entity/message.ts @@ -2,7 +2,6 @@ import { z } from "zod"; import { base64Schema } from "src/app/utils/zod"; import { SessionStore } from "src/app/store/session.service"; - export enum MessageAttachmentSource { Webtrix = 1, Device, @@ -16,7 +15,7 @@ export enum MessageAttachmentFileType { } export enum IMessageType { - normal =1, + normal = 1, information } @@ -63,7 +62,10 @@ export const MessageEntitySchema = z.object({ safeFile: z.any().optional(), description: z.string().nullable().optional() })).optional(), - origin: z.enum(['history', 'local', 'incoming']).optional() + origin: z.enum(['history', 'local', 'incoming']).optional(), + requestId: z.string().optional(), + sendAttemp: z.number().optional(), + hasAttachment: z.boolean().optional() }) export type IMessage = z.infer; diff --git a/src/app/module/chat/data/repository/message/message-local-data-source.service.ts b/src/app/module/chat/data/repository/message/message-local-data-source.service.ts index 34dad019e..b716e064d 100644 --- a/src/app/module/chat/data/repository/message/message-local-data-source.service.ts +++ b/src/app/module/chat/data/repository/message/message-local-data-source.service.ts @@ -27,7 +27,6 @@ export class MessageLocalDataSourceService extends DexieRepository { this.creatingSubject.next(obj) - console.log('creating', obj) }); } diff --git a/src/app/module/chat/domain/chat-service.service.ts b/src/app/module/chat/domain/chat-service.service.ts index 6e63daeb9..6b4d1a073 100644 --- a/src/app/module/chat/domain/chat-service.service.ts +++ b/src/app/module/chat/domain/chat-service.service.ts @@ -30,8 +30,8 @@ import { MessageMarkAllMessageAsReadByRoomIdInputSchema, MessageMarkAllMessageAs import { GetRoomListUseCaseService } from 'src/app/module/chat/domain/use-case/room/room-get-list-use-case.service'; import { filter } from 'rxjs/operators'; import { v4 as uuidv4 } from 'uuid' -import { MessageEntity } from '../../../core/chat/entity/message'; -import { MessageAttachmentByMessageIdUseCase } from './use-case/message/message-attachment-by-message-id.service'; +import { IMessage, MessageEntity } from '../../../core/chat/entity/message'; +import { MessageAttachmentByMessageIdInput, MessageAttachmentByMessageIdUseCase } from './use-case/message/message-attachment-by-message-id.service'; import { AddMemberToRoomInputDTO } from '../domain/use-case/member/member-add-use-case.service'; import { RoomType } from "src/app/core/chat/entity/group"; import { HttpListenToMessageLoadHistoryAdapter } from './adapter' @@ -167,7 +167,7 @@ export class ChatServiceService { return this.MemberAdminUseCaseService.execute(input) } - sendMessage(input: MessageEntity, messageEnum: RoomType) { + sendMessage(input: IMessage, messageEnum: RoomType) { return this.MessageCreateUseCaseService.execute(input, messageEnum); } @@ -175,7 +175,7 @@ export class ChatServiceService { return this.SyncAllRoomMessagesService.execute() } - getMessageAttachmentByMessageId(input: MessageEntity) { + getMessageAttachmentByMessageId(input: MessageAttachmentByMessageIdInput) { return this.MessageAttachmentByMessageIdService.execute(input) } diff --git a/src/app/module/chat/domain/mapper/messageMapper.ts b/src/app/module/chat/domain/mapper/messageMapper.ts index d96923185..387b20142 100644 --- a/src/app/module/chat/domain/mapper/messageMapper.ts +++ b/src/app/module/chat/domain/mapper/messageMapper.ts @@ -1,4 +1,4 @@ -import { MessageEntity } from "../../../../core/chat/entity/message"; +import { MessageEntity, IMessage } from "../../../../core/chat/entity/message"; import { MessageOutPutDataDTO } from "src/app/core/chat/repository/dto/messageOutputDTO"; import { MessageInputDTO } from "../use-case/message/message-create-use-case.service"; @@ -7,7 +7,7 @@ export class MessageMapper { return DTO as MessageEntity } - static fromDomain(entity:MessageEntity, requestId): MessageInputDTO { + static fromDomain(entity:IMessage, requestId): MessageInputDTO { return { receiverId: entity.receiverId, canEdit: entity.canEdit, diff --git a/src/app/module/chat/domain/use-case/message/message-attachment-by-message-id.service.ts b/src/app/module/chat/domain/use-case/message/message-attachment-by-message-id.service.ts index eb4337800..8a4d21c70 100644 --- a/src/app/module/chat/domain/use-case/message/message-attachment-by-message-id.service.ts +++ b/src/app/module/chat/domain/use-case/message/message-attachment-by-message-id.service.ts @@ -4,15 +4,14 @@ import { AttachmentRemoteDataSourceService } from 'src/app/module/chat/data/repo import { AttachmentLocalDataSource } from 'src/app/module/chat/data/repository/attachment/attachment-local-repository.service' import { createBlobUrl } from 'src/app/utils/ToBase64'; import { err, Result } from 'neverthrow'; -import { Logger } from 'src/app/services/logger/main/service'; -import { MessageEntity } from '../../../../../core/chat/entity/message'; -import { AttachmentTableSchema } from 'src/app/infra/database/dexie/instance/chat/schema/attachment'; +import { MessageEntitySchema } from '../../../../../core/chat/entity/message'; import { TracingType, XTracerAsync } from 'src/app/services/monitoring/opentelemetry/tracer'; import { isHttpResponse } from 'src/app/infra/http/http.service'; -const MessageAttachmentByMessageIdSchema = AttachmentTableSchema.pick({ - $messageId: true, - id: true +const MessageAttachmentByMessageIdSchema = MessageEntitySchema.pick({ + $id: true, + id: true, + attachments: true, }) export type MessageAttachmentByMessageIdInput = z.infer @@ -28,7 +27,9 @@ export class MessageAttachmentByMessageIdUseCase { ) { } @XTracerAsync({name:'Message-Attachment-By-MessageIdUseCase', module:'chat', bugPrint: true, waitNThrow: 15000}) - async execute(input: MessageEntity, tracing?: TracingType): Promise> { + async execute(input: MessageAttachmentByMessageIdInput, tracing?: TracingType): Promise> { + + tracing.setAttribute('messageId', input.id) const getLocalAttachment = await this.AttachmentLocalDataSource.findOne({ $messageId: input.$id @@ -60,8 +61,9 @@ export class MessageAttachmentByMessageIdUseCase { } else { tracing.setAttribute('download', 'true') - const result = await this.AttachmentRemoteDataSourceService.getAttachment(input.attachments[0].id) tracing.setAttribute('attachmentId', input.attachments[0].id.toString()) + + const result = await this.AttachmentRemoteDataSourceService.getAttachment(input.attachments[0].id) if(result.isErr()) { tracing.hasError('failed to download message attachment', { error: result.error, @@ -78,7 +80,6 @@ export class MessageAttachmentByMessageIdUseCase { if(result.isOk()) { - console.log('convert') const dataUrl = await createBlobUrl(result.value) if(dataUrl.isOk()) { diff --git a/src/app/module/chat/domain/use-case/message/message-create-use-case.service.ts b/src/app/module/chat/domain/use-case/message/message-create-use-case.service.ts index 2448402c4..1fdafb5a6 100644 --- a/src/app/module/chat/domain/use-case/message/message-create-use-case.service.ts +++ b/src/app/module/chat/domain/use-case/message/message-create-use-case.service.ts @@ -1,5 +1,5 @@ import { Injectable } from '@angular/core'; -import { MessageAttachmentSource, MessageEntity, MessageEntitySchema, } from '../../../../../core/chat/entity/message'; +import { IMessage, MessageAttachmentSource, MessageEntity, MessageEntitySchema, } from '../../../../../core/chat/entity/message'; import { AttachmentLocalDataSource } from "src/app/module/chat/data/repository/attachment/attachment-local-repository.service"; import { z } from 'zod'; import { v4 as uuidv4 } from 'uuid'; @@ -100,9 +100,9 @@ export class MessageCreateUseCaseService { @XTracerAsync({name:'MessageCreateUseCaseService', module:'chat', bugPrint: true, waitNThrow: 5000}) - async execute(message: MessageEntity, messageEnum: RoomType, tracing?: TracingType) { + async execute(message: IMessage, messageEnum: RoomType, tracing?: TracingType) { - const validation = zodSafeValidation(MessageEntitySchema, message) + const validation = zodSafeValidation(MessageEntitySchema, message) if(validation.isOk()) { message.sendAttemp++; diff --git a/src/app/module/chat/domain/use-case/message/message-mark-as-read-use-case.service.ts b/src/app/module/chat/domain/use-case/message/message-mark-as-read-use-case.service.ts index 7cbf68b90..99084bf82 100644 --- a/src/app/module/chat/domain/use-case/message/message-mark-as-read-use-case.service.ts +++ b/src/app/module/chat/domain/use-case/message/message-mark-as-read-use-case.service.ts @@ -24,6 +24,14 @@ export class MessageMarkAsReadUseCaseService { @XTracerAsync({name:'MessageMarkAsReadUseCaseService', module:'chat', bugPrint: true}) async execute(sendReadAt: MessageMarkAsReadInput, tracing?: TracingType) { - return this.MessageSocketRepositoryService.sendReadAt(sendReadAt as any) + const result = await this.MessageSocketRepositoryService.sendReadAt(sendReadAt as any) + + if(result.isErr()) { + tracing.setAttribute('meesageId', sendReadAt.messageId) + tracing.hasError('failed to read message') + } + + return result + } } diff --git a/src/app/module/chat/domain/use-case/room/room-get-by-id-use-case.service.ts b/src/app/module/chat/domain/use-case/room/room-get-by-id-use-case.service.ts index 89f2f9efe..8bc8de50c 100644 --- a/src/app/module/chat/domain/use-case/room/room-get-by-id-use-case.service.ts +++ b/src/app/module/chat/domain/use-case/room/room-get-by-id-use-case.service.ts @@ -70,7 +70,6 @@ export class GetRoomByIdUseCaseService { const getRoomById = await this.roomLocalDataSourceService.findOne({id:validData.value.data.id}) if(getRoomById.isOk() && getRoomById.value) { - console.log(validData.value) const room = GetRoomByIdMapper.toDomain(validData.value) const added: Partial = addedDiff(getRoomById.value, room); @@ -90,7 +89,6 @@ export class GetRoomByIdUseCaseService { } } else if (getRoomById.isOk() && !getRoomById.value) { - console.log(validData.value) const room = GetRoomByIdMapper.toDomain(validData.value) this.roomLocalDataSourceService.insert(room) } diff --git a/src/app/ui/chat/chat.page.ts b/src/app/ui/chat/chat.page.ts index a66597855..d9fa0a0f2 100644 --- a/src/app/ui/chat/chat.page.ts +++ b/src/app/ui/chat/chat.page.ts @@ -71,6 +71,9 @@ export class ChatPage implements OnInit { RoomSelected!: RoomViewModel; + private worker: SharedWorker; + private port: MessagePort; + constructor( private modalController: ModalController, private timeService: TimeService, @@ -102,6 +105,15 @@ export class ChatPage implements OnInit { this.boldTable = distributionObject }) + this.worker = new SharedWorker('shared-worker.js'); + // this.worker.port.start() + this.port = this.worker.port; + + this.port.onmessage = (event) => { + console.log('Received from worker:', event.data); + } + + //this.port.postMessage('hello'); } @@ -346,6 +358,7 @@ export class ChatPage implements OnInit { openMessagesPage(roomId) { + this.port.postMessage('hello'); // this.chatService.refreshtoken(); this.roomId = roomId; this.RoomSelected = this.rooms.filter(e => e.id == roomId)[0] diff --git a/src/app/ui/chat/component/messages/messages.page.html b/src/app/ui/chat/component/messages/messages.page.html index 0ba296045..a4030c883 100644 --- a/src/app/ui/chat/component/messages/messages.page.html +++ b/src/app/ui/chat/component/messages/messages.page.html @@ -47,12 +47,13 @@
-
+
@@ -83,7 +84,6 @@ Mandou uma mensagen com visualização única
-
@@ -136,11 +136,8 @@ -
-
-
@@ -154,7 +151,9 @@
{{ message.message }}
- +
+ {{ message.message }} +
{{ reaction.reaction }} diff --git a/src/app/ui/chat/component/messages/messages.page.scss b/src/app/ui/chat/component/messages/messages.page.scss index 227365bce..aff902ed8 100644 --- a/src/app/ui/chat/component/messages/messages.page.scss +++ b/src/app/ui/chat/component/messages/messages.page.scss @@ -137,6 +137,21 @@ ion-content { } } + .info-ballon { + text-align: center; + font-size: rem(13); + color: #262420; + padding: 10px; + margin: 10px auto; + line-height: 2.2rem; + border-radius: 8px; + .ballon { + background: var(--chat-alert-msg-color); + padding: 0px 10px; + border-radius: 8px; + } + } + .messages { font-size: rem(13); font-family: Roboto; @@ -510,4 +525,4 @@ ion-footer { position: relative; top: -10px; margin-bottom: -15px; -} \ No newline at end of file +} diff --git a/src/app/ui/chat/component/messages/messages.page.ts b/src/app/ui/chat/component/messages/messages.page.ts index 840ddea40..3c3b6657a 100644 --- a/src/app/ui/chat/component/messages/messages.page.ts +++ b/src/app/ui/chat/component/messages/messages.page.ts @@ -49,8 +49,10 @@ import { MessageTable } from 'src/app/infra/database/dexie/instance/chat/schema/ import { RoomTable } from 'src/app/infra/database/dexie/instance/chat/schema/room'; import { TypingTable } from 'src/app/infra/database/dexie/instance/chat/schema/typing'; import { HttpClient } from '@angular/common/http'; -import { v4 as uuidv4 } from 'uuid' import { RoomViewModel } from '../../store/model/room'; +import { MessageViewModal } from '../../store/model/message'; +import { XBallon } from '../../utils/messageBallon'; +import { whatsappDate } from 'src/app/ui/shared/utils/whatappdate'; @Component({ selector: 'app-messages', templateUrl: './messages.page.html', @@ -91,7 +93,6 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy scrollToBottomBtn = false; longPressActive = false; downloadFile: string; - showAvatar = true; recording = false; @@ -125,7 +126,6 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy roomStatus$: DexieObservable roomMessage$: DexieObservable roomMembers$: Observable - //userTyping$: DexieObservable userTyping$: TypingTable[] | undefined newMessagesStream!: Subscription @@ -143,7 +143,7 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy messageTypingSubject: Subscription messageOnReconnectSubject: Subscription - messages1: {[key: string]: MessageEntity[]} = {} + messages1: {[key: string]: MessageViewModal[]} = {} MessageAttachmentFileType = MessageAttachmentFileType MessageAttachmentFileSource = MessageAttachmentSource IMessageType = IMessageType @@ -155,6 +155,8 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy private worker: SharedWorker; private port: MessagePort; + date: {[key: string]: Object} = {} + constructor( public popoverController: PopoverController, private modalController: ModalController, @@ -186,56 +188,53 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy this.checkAudioPermission() //this.sendChunks() - this.worker = new SharedWorker('shared-worker.js'); - this.port = this.worker.port; + // this.worker = new SharedWorker('shared-worker.js'); + // this.port = this.worker.port; - this.port.onmessage = (event) => { - console.log('Received from worker:', event.data); - } + // this.port.onmessage = (event) => { + // console.log('Received from worker:', event.data); + // } - this.port.postMessage('hello'); + // this.port.postMessage('hello'); } - sendChunks() { - const base64String = 'data:video/mp4;base64,AAAAHGZ0eXBtcDQyAAAAAGlzb21tcDQyAAACAGlzb21tcDQyaXNvbXJtZGEAAAAHZnJlZS1ybWRhAAAAGXZmY2MtbGF2ZjU4LmEyLTkyLm12NTZjAGZyZWUtcm1kYQAAAAVyZWZsYXYAAABWZGF0YTqBgIAAAAs9AAABM/f/+6mpg6z+d0+j5adJHVD+lk75p0ntRFEyTlHT/GRYbDg4ODhISEhAQK/jMCAxCBAIEwMmJgAABNmY2MtbGF2ZjU4LmEyLTkyLm12NTZjAGZyZWUtcm1kYQAAAAVyZWZsYXY='; - const chunkSize = Math.ceil(base64String.length / 2); - const chunks = [ - { chunk: base64String.slice(0, chunkSize), index: 0 }, - { chunk: base64String.slice(chunkSize), index: 1 } - ]; + // sendChunks() { + // const base64String = 'data:video/mp4;base64,AAAAHGZ0eXBtcDQyAAAAAGlzb21tcDQyAAACAGlzb21tcDQyaXNvbXJtZGEAAAAHZnJlZS1ybWRhAAAAGXZmY2MtbGF2ZjU4LmEyLTkyLm12NTZjAGZyZWUtcm1kYQAAAAVyZWZsYXYAAABWZGF0YTqBgIAAAAs9AAABM/f/+6mpg6z+d0+j5adJHVD+lk75p0ntRFEyTlHT/GRYbDg4ODhISEhAQK/jMCAxCBAIEwMmJgAABNmY2MtbGF2ZjU4LmEyLTkyLm12NTZjAGZyZWUtcm1kYQAAAAVyZWZsYXY='; + // const chunkSize = Math.ceil(base64String.length / 2); + // const chunks = [ + // { chunk: base64String.slice(0, chunkSize), index: 0 }, + // { chunk: base64String.slice(chunkSize), index: 1 } + // ]; - const identifier = uuidv4(); // You can set a unique identifier for the file + // const identifier = uuidv4(); // You can set a unique identifier for the file - const totalChunks = chunks.length; + // const totalChunks = chunks.length; - chunks.forEach((chunkData) => { - const payload = { - chunk: chunkData.chunk, - identifier, - index: chunkData.index, - totalChunks - }; + // chunks.forEach((chunkData) => { + // const payload = { + // chunk: chunkData.chunk, + // identifier, + // index: chunkData.index, + // totalChunks + // }; - this.http.post('https://gdapi-dev.dyndns.info/stage/api/v2/File/UploadBase64Chunks', payload) - .subscribe(response => { - console.log('Chunk sent successfully:', response); - }, error => { - console.error('Error sending chunk:', error); - }); - }); - } + // this.http.post('https://gdapi-dev.dyndns.info/stage/api/v2/File/UploadBase64Chunks', payload) + // .subscribe(response => { + // console.log('Chunk sent successfully:', response); + // }, error => { + // console.error('Error sending chunk:', error); + // }); + // }); + // } ngOnChanges(changes: SimpleChanges): void { - this.roomData$ = this.RoomLocalRepository.getRoomByIdLive(this.roomId) this.roomData$.subscribe(e => { - // console.log(e) if(e) { this.roomType = e.roomType } - }) this.getMessages(); @@ -244,7 +243,6 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy 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 @@ -258,7 +256,6 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy ) this.roomStatus$ = this.MemberListLocalRepository.allMemberOnline(this.roomId) - // this.chatServiceService.getRoomById(this.roomId) this.messageTypingSubject?.unsubscribe() this.messageTypingSubject = this.userTypingLocalRepository.getUserTypingLiveByRoomId(this.roomId).subscribe((e) => { @@ -307,7 +304,25 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy let messages = await this.messageLocalDataSourceService.getItems(this.roomId) this.messages1[this.roomId] = [] - this.messages1[this.roomId] = messages + this.date = {} + const allMessage = []; + + 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.time("mappingTime"); + + this.messages1[this.roomId] = allMessage + + console.timeEnd("mappingTime"); // if(messages.length >= 1) { // this.messages1[this.roomId].push(LastMessage) @@ -321,13 +336,11 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy this.messageOnReconnectSubject?.unsubscribe() this.messageOnReconnectSubject = this.chatServiceService.listenToMessageLoadHistory({roomId: this.roomId}).subscribe((messages) => { - console.log('message', messages); - for(const message of messages.data) { const found = this.messages1[this.roomId].find((e) => e.id == message.id) if(!found) { - const msg = new MessageEntity() + const msg = new MessageViewModal(message as any) Object.assign(msg, message) this.messages1[this.roomId].push(msg) } @@ -387,17 +400,19 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy for(const message of this.messages1[this.roomId]) { - const me = message.info.find(e => e.memberId == SessionStore.user.UserId && typeof e.readAt == 'string') + if(!message.meSender()) { + const me = message.haveSeen(message.info) - if(!me) { - Logger.info('send read at') + 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 - }) + this.chatServiceService.sendReadAt({ + memberId: SessionStore.user.UserId, + messageId: message.id, + requestId: '', + roomId: this.roomId + }) + } } } @@ -407,7 +422,7 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy this.messageReceiveSubject?.unsubscribe(); this.messageReceiveSubject = this.chatServiceService.listenToIncomingMessage(this.roomId).subscribe(async (message) => { - this.messages1[this.roomId].push(message as MessageEntity) + this.messages1[this.roomId].push(new MessageViewModal(message)) if(message.hasAttachment) { @@ -440,7 +455,7 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy 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].isDeleted = true + 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); @@ -474,6 +489,7 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy this.messageSendSubject = this.chatServiceService.listenToSendMessage(this.roomId).subscribe((updateMessage) => { + console.log({updateMessage}) const index = this.messages1[this.roomId].findIndex(e => e?.requestId === updateMessage.requestId); // Use triple equals for comparison @@ -717,7 +733,7 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy //Converting base64 to blob const encodedData = this.audioRecordedDataUrl; - const message = new MessageEntity(); + const message = new MessageViewModal(); message.roomId = this.roomId message.sentAt = new Date().toISOString() @@ -782,7 +798,7 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy async sendMessage() { - const message = new MessageEntity(); + const message = new MessageViewModal(); message.message = this.textField message.roomId = this.roomId @@ -960,7 +976,7 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy if(compressedImage.isOk()) { - const message = new MessageEntity(); + const message = new MessageViewModal(); message.roomId = this.roomId message.oneShot = oneShot @@ -981,7 +997,7 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy mimeType: 'image/'+picture.value.format }] - this.messages1[this.roomId].push(message) + this.messages1[this.roomId].push(new MessageViewModal(message)) setTimeout(() => { this.scrollToBottomClicked() }, 100) @@ -1017,7 +1033,7 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy // "title": res.data.selected.Assunto, // "description": res.data.selected.DocTypeDesc, - const message = new MessageEntity(); + const message = new MessageViewModal(); message.message = this.textField message.roomId = this.roomId @@ -1037,7 +1053,7 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy docId: res.data.selected.Id, }] - this.messages1[this.roomId].push(message) + this.messages1[this.roomId].push(new MessageViewModal(message)) setTimeout(() => { this.scrollToBottomClicked() }, 100) @@ -1105,7 +1121,7 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy if(compressedImage.isOk()) { - const message = new MessageEntity(); + const message = new MessageViewModal(); message.roomId = this.roomId message.sentAt = new Date().toISOString() @@ -1163,7 +1179,7 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy if(fileBase64.isOk()) { - const message = new MessageEntity(); + const message = new MessageViewModal(); message.roomId = this.roomId message.sentAt = new Date().toISOString() diff --git a/src/app/ui/chat/store/model/message.ts b/src/app/ui/chat/store/model/message.ts index 24fba9046..8abcc40b2 100644 --- a/src/app/ui/chat/store/model/message.ts +++ b/src/app/ui/chat/store/model/message.ts @@ -1,14 +1,14 @@ -import { SafeResourceUrl } from "@angular/platform-browser"; -import { IMessageType, MessageEntity, MessageEntitySchema } from "src/app/core/chat/entity/message"; +import { MessageEntity, MessageEntitySchema, IMessageType, IMessage } from "src/app/core/chat/entity/message"; import { SessionStore } from "src/app/store/session.service"; + export class MessageViewModal { + $id?: number id?: string roomId?: string receiverId?: number message?: string - messageType: number = 0 canEdit: boolean = false oneShot: boolean = false sentAt?: string @@ -17,18 +17,30 @@ export class MessageViewModal { sender!: typeof MessageEntitySchema._type.sender sending: boolean = false sendAttemp = 0 - + messageType = IMessageType.normal attachments: typeof MessageEntitySchema._type.attachments = [] reactions: typeof MessageEntitySchema._type.reactions = [] - requestId!: string + requestId: string isDeleted: typeof MessageEntitySchema._type.isDeleted = false status!: 'allViewed' | 'allReceived'| 'enviado'| 'enviar' messageUiType!: 'info-meeting'| 'my-message'| 'other-message' - - constructor(model: MessageEntity) { - Object.assign(this, model) + showReaction = false + showMessage = false + ballo = false + + constructor(model?: IMessage) { + if(model) { + Object.assign(this, model) + } this.setMessageUIType() + + if(this.isDeleted != true && this.messageType != IMessageType.information) { + this.showReaction = true + } + if(this.isDeleted == false && this.messageType == IMessageType.normal) { + this.showMessage = true + } } setMessageUIType() { @@ -41,28 +53,27 @@ export class MessageViewModal { } } - messageStatus(totalMembers: number) { - if(this.allViewed(totalMembers)) { - this.status = 'allViewed' - } else if(this.allReceived(totalMembers)) { - this.status = 'allReceived' - } else if (this.id) { - this.status = 'enviado' - } else { - this.status = 'enviar' + delete() { + this.showMessage = false + this.isDeleted = true + } + + + get messageStatus() { + if(this.id) { + return 'send' } } - allReceived(totalMembers: number) { - return this.info.filter(e => typeof e.deliverAt == 'string').length == totalMembers - } - - allViewed(totalMembers: number) { - return this.info.filter(e => typeof e.readAt == 'string').length == totalMembers - } - get hasAttachment() { return this.attachments.length >= 1 } + haveSeen(info: typeof MessageEntitySchema._type.info) { + return info.filter(e => typeof e.readAt == 'string' && e.memberId == SessionStore.user.UserId).length == 1 + } + + meSender() { + return this.sender.wxUserId == SessionStore.user.UserId + } } diff --git a/src/app/ui/chat/store/model/room.ts b/src/app/ui/chat/store/model/room.ts index 8291f68a1..8cc3f8c24 100644 --- a/src/app/ui/chat/store/model/room.ts +++ b/src/app/ui/chat/store/model/room.ts @@ -2,7 +2,6 @@ import { IRoom, RoomEntitySchema } from "src/app/core/chat/entity/group"; export class RoomViewModel implements IRoom { - id: typeof RoomEntitySchema._input.id roomName: typeof RoomEntitySchema._input.roomName createdBy: typeof RoomEntitySchema._input.createdBy @@ -27,35 +26,35 @@ export class RoomViewModel implements IRoom { const hoje = new Date(agora.getFullYear(), agora.getMonth(), agora.getDate()); const ontem = new Date(hoje); ontem.setDate(hoje.getDate() - 1); - + const diasDaSemana = ["Domingo", "Segunda-feira", "Terça-feira", "Quarta-feira", "Quinta-feira", "Sexta-feira", "Sábado"]; - + // Verifica se a mensagem foi enviada hoje if (dataMensagem >= hoje) { this.displayDate = dataMensagem.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit', hour12: false }); - return + return } - + // Verifica se a mensagem foi enviada ontem if (dataMensagem >= ontem && dataMensagem < hoje) { this.displayDate = "Ontem"; return } - + // Verifica se a mensagem foi enviada nesta semana const inicioDaSemana = new Date(hoje); inicioDaSemana.setDate(hoje.getDate() - hoje.getDay()); - + if (dataMensagem >= inicioDaSemana) { this.displayDate = diasDaSemana[dataMensagem.getDay()]; return } - + // Se a mensagem foi enviada antes desta semana this.displayDate = dataMensagem.toLocaleDateString("pt-BR"); // Formato: DD/MM/AAAA return - + } - + } -} \ No newline at end of file +} diff --git a/src/app/ui/chat/utils/messageBallon.ts b/src/app/ui/chat/utils/messageBallon.ts new file mode 100644 index 000000000..b8fc7c8ca --- /dev/null +++ b/src/app/ui/chat/utils/messageBallon.ts @@ -0,0 +1,23 @@ +import { SessionStore } from "src/app/store/session.service"; +import { MessageViewModal } from "../store/model/message"; +import { whatsappDate } from "../../shared/utils/whatappdate"; + +export function XBallon(message: any) { + const MessageBallon = new MessageViewModal(message as any) + MessageBallon.$id = 0 + MessageBallon.id = '' + MessageBallon.isDeleted = false + MessageBallon.sentAt = message.sentAt + MessageBallon.message = whatsappDate(message.sentAt, false) + MessageBallon.ballo = true + MessageBallon.sender = { + userPhoto: '', + wxeMail: SessionStore.user.Email, + wxFullName: SessionStore.user.FullName, + wxUserId: SessionStore.user.UserId + } + + MessageBallon.showMessage = false + MessageBallon.attachments = []; + return MessageBallon +} diff --git a/src/app/ui/shared/utils/whatappdate.ts b/src/app/ui/shared/utils/whatappdate.ts new file mode 100644 index 000000000..5558f2c35 --- /dev/null +++ b/src/app/ui/shared/utils/whatappdate.ts @@ -0,0 +1,37 @@ +export function whatsappDate(newDate: string, showTodayHours = true) { + + const dataMensagem = new Date(newDate); + const agora = new Date(); + + const hoje = new Date(agora.getFullYear(), agora.getMonth(), agora.getDate()); + const ontem = new Date(hoje); + ontem.setDate(hoje.getDate() - 1); + + const diasDaSemana = ["Domingo", "Segunda-feira", "Terça-feira", "Quarta-feira", "Quinta-feira", "Sexta-feira", "Sábado"]; + + // Verifica se a mensagem foi enviada hoje + if (dataMensagem >= hoje) { + if(showTodayHours) { + return dataMensagem.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit', hour12: false }); + } else { + return 'Hoje'; + } + + } + + // Verifica se a mensagem foi enviada ontem + if (dataMensagem >= ontem && dataMensagem < hoje) { + return "Ontem"; + } + + // Verifica se a mensagem foi enviada nesta semana + const inicioDaSemana = new Date(hoje); + inicioDaSemana.setDate(hoje.getDate() - hoje.getDay()); + + if (dataMensagem >= inicioDaSemana) { + return diasDaSemana[dataMensagem.getDay()]; + } + + // Se a mensagem foi enviada antes desta semana + return dataMensagem.toLocaleDateString("pt-BR"); // Formato: DD/MM/AAAA +} diff --git a/src/shared-worker.js b/src/shared-worker.js index b768e558f..30b386d7d 100644 --- a/src/shared-worker.js +++ b/src/shared-worker.js @@ -1,12 +1,23 @@ // src/shared-worker.js self.onconnect = function (event) { const port = event.ports[0]; - + port.onmessage = function (e) { const message = e.data; console.log('Received from client:', message); - + // Echo the message back to all connected clients port.postMessage('Echo: ' + message); } + + + // Optional: broadcast messages to all connected clients + function broadcast(message) { + self.clients.forEach(client => { + client.postMessage(message); + }); + } + + // Example of broadcasting a message + broadcast('Shared Worker connected'); }