show last messae and date

This commit is contained in:
Peter Maquiran
2024-08-30 15:31:29 +01:00
parent d6a08c6264
commit 3edbcc194e
13 changed files with 160 additions and 36 deletions
+8 -4
View File
@@ -1,6 +1,7 @@
import { SessionStore } from "src/app/store/session.service";
import { BaseEntity } from "src/app/utils/entity";
import { z } from "zod"
import { MessageEntitySchema } from "./message";
export enum RoomType {
Group = 1,
@@ -33,12 +34,13 @@ export const RoomEntitySchema = z.object({
createdAt: z.any(),
expirationDate: z.any().nullable(),
roomType: z.nativeEnum(RoomType),
members: z.array(MemberSchema).optional()
members: z.array(MemberSchema).optional(),
messages: MessageEntitySchema.array().optional()
})
export type IRoomEntity = z.infer<typeof RoomEntitySchema>
export type IRoom = z.infer<typeof RoomEntitySchema>
export class RoomEntity extends BaseEntity<RoomEntity>(RoomEntitySchema) implements IRoomEntity{
export class RoomEntity extends BaseEntity<RoomEntity>(RoomEntitySchema) implements IRoom{
id: typeof RoomEntitySchema._input.id
roomName: typeof RoomEntitySchema._input.roomName
@@ -47,8 +49,10 @@ export class RoomEntity extends BaseEntity<RoomEntity>(RoomEntitySchema) implem
expirationDate: typeof RoomEntitySchema._input.expirationDate
roomType: typeof RoomEntitySchema._input.roomType
members: typeof RoomEntitySchema._input.members
messages: typeof RoomEntitySchema._input.messages
displayDate = ''
constructor(data: IRoomEntity) {
constructor(data: IRoom) {
super();
Object.assign(this, data)
if(data.roomType == RoomType.Direct) {
+2 -2
View File
@@ -36,7 +36,7 @@ export const MessageEntitySchema = z.object({
wxUserId: z.number(),
wxFullName: z.string(),
wxeMail: z.string(),
userPhoto: z.string(),
userPhoto: z.string().nullable(),
}),
reactions: z.object({
id: z.string(),
@@ -61,7 +61,7 @@ export const MessageEntitySchema = z.object({
mimeType: z.string().optional(),
safeFile: z.any().optional(),
description: z.string().nullable().optional()
})).optional()
})).optional(),
})
export type IMessage = z.infer<typeof MessageEntitySchema>;
@@ -1,6 +1,5 @@
import { RoomListItemOutPutDTO } from "src/app/module/chat/domain/use-case/room/room-get-list-use-case.service";
import { RoomEntity } from "../entity/group";
import { captureAndReraiseAsync } from "src/app/services/decorators/captureAndReraiseAsync";
export class GetRoomListMapper{
@@ -24,7 +23,8 @@ export class GetRoomListMapper{
wxFullName: b.wxFullName,
wxUserId: b.wxUserId
}
}))
})),
messages: roomData.chatRoom.messages,
}));
}
@@ -1,6 +1,7 @@
import { z } from "zod";
import { EntityTable } from 'Dexie';
import { RoomType } from "src/app/core/chat/entity/group";
import { MessageEntity, MessageEntitySchema } from "src/app/core/chat/entity/message";
export const RoomTableSchema = z.object({
id: z.string(),
@@ -13,9 +14,10 @@ export const RoomTableSchema = z.object({
}),
createdAt: z.any(),
expirationDate: z.any().nullable(),
roomType: z.nativeEnum(RoomType)
roomType: z.nativeEnum(RoomType),
messages: MessageEntitySchema.array().optional()
})
export type RoomTable = z.infer<typeof RoomTableSchema>
export type DexieRoomsTable = EntityTable<RoomTable, 'id'>;
export const RoomTableColumn = 'id, createdBy, roomName, roomType, expirationDate, lastMessage'
export const RoomTableColumn = 'id, createdBy, roomName, roomType, expirationDate, lastMessage'
+3 -1
View File
@@ -37,6 +37,7 @@ import { DistributionService } from './domain/service/distribution.service'
import { BoldLocalRepository } from './data/repository/bold/bold-local-repository';
import { IBoldLocalRepository } from 'src/app/core/chat/repository/bold/bold-local-repository';
import { BoldService } from 'src/app/module/chat/domain/service/bold.service'
import { RoomLastMessageService } from 'src/app/module/chat/domain/service/room-last-message.service'
@NgModule({
imports: [HttpModule],
providers: [
@@ -118,7 +119,8 @@ export class ChatModule {
private UserTypingRemoteRepositoryService: UserTypingRemoteRepositoryService,
private RoomService: RoomService,
private DistributionService: DistributionService,
private BoldService: BoldService
private BoldService: BoldService,
private RoomLastMessageService: RoomLastMessageService
) {
this.RoomService.init()
@@ -14,7 +14,8 @@ export function roomListDetermineChanges(serverRooms: RoomListItemOutPutDTO[], l
room.chatRoom.roomName !== localRoom.roomName && room.chatRoom.roomType == RoomType.Group ||
room.chatRoom.createdBy.wxUserId !== localRoom.createdBy.wxUserId ||
room.chatRoom.createdAt !== localRoom.createdAt ||
room.chatRoom.expirationDate !== localRoom.expirationDate // ||
room.chatRoom.expirationDate !== localRoom.expirationDate ||
room.chatRoom.messages?.[0]?.id !== localRoom.messages?.[0]?.id
// room.chatRoom.roomType !== localRoom.roomType
);
});
@@ -19,7 +19,7 @@ import { DeleteRoomUseCaseService } from './use-case/room/room-delete-by-id-use-
import { CreateRoomInputDTO, CreateRoomUseCaseService } from './use-case/room/room-create-use-case.service';
import { RoomLeaveUseCase, UserRemoveListInputDTO } from './use-case/room/room-leave-by-id-use-case.service';
import { SyncAllRoomMessagesService } from './use-case/message/sync-all-room-messages.service';
import { ListenSendMessageUseCase } from './use-case/message/listen-send-message.service'
import { ListenSendMessageUseCase } from './use-case/message/listen-send-message.service';
import { SendLocalMessagesUseCaseService } from './use-case/message/messages-send-offline-use-case.service'
import { RemoveMemberUseCaseService } from './use-case/member/-use-case.service'
import { AddMemberUseCaseService } from './use-case/member/member-add-use-case.service'
@@ -27,13 +27,12 @@ import { RoomUpdateInputDTO, UpdateRoomByIdUseCaseService } from './use-case/roo
import { SocketConnectUseCaseService } from './use-case/socket-connect-use-case.service'
import { MessageMarkAsReadUseCaseService } from './use-case/message/message-mark-as-read-use-case.service'
import { MessageMarkAllMessageAsReadByRoomIdInputSchema, MessageMarkAllMessageAsReadByRoomIdService } from './use-case/message/message-mark-all-message-as-read-by-room-id.service'
import { GetMessageAttachmentLocallyByMessageId, GetMessageAttachmentLocallyUseCaseService } from 'src/app/module/chat/domain/use-case/message/message-get-attachment-localy-use-case.service';
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 { MessageAttachmentByMessageIdInput, MessageAttachmentByMessageIdUseCase } from './use-case/message/message-attachment-by-message-id.service';
import { AddMemberToRoomInputDTO, AddMemberToRoomInputDTOSchema } from '../domain/use-case/member/member-add-use-case.service';
import { 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'
import { HttpListenToMessageLoadHistoryUseCaseInput } from 'src/app/core/chat/usecase/message/http-listen-to-message-load-history-by-roomId-use-case';
@@ -65,7 +64,6 @@ export class ChatServiceService {
private MessageAttachmentByMessageIdService: MessageAttachmentByMessageIdUseCase,
private SyncAllRoomMessagesService: SyncAllRoomMessagesService,
private DownloadMessageAttachmentUserCaseService: DownloadMessageAttachmentUserCaseService,
private GetMessageAttachmentLocallyUseCaseService: GetMessageAttachmentLocallyUseCaseService,
private GetRoomListUseCaseService: GetRoomListUseCaseService,
private GetRoomByIdUseCaseService: GetRoomByIdUseCaseService,
private DeleteRoomUseCaseService: DeleteRoomUseCaseService,
@@ -23,9 +23,7 @@ export class DistributionService {
constructor(
private http: HttpAdapter,
private distributionLocalRepository: IDistributionLocalRepository
) {
// this.listenToLoadHistory()
}
) {}
listenToLoadHistory() {
return this.http.listen().pipe(
@@ -0,0 +1,16 @@
import { TestBed } from '@angular/core/testing';
import { RoomLastMessageService } from './room-last-message.service';
describe('RoomLastMessageService', () => {
let service: RoomLastMessageService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(RoomLastMessageService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});
@@ -0,0 +1,33 @@
import { Injectable } from '@angular/core';
import { filter, map } from 'rxjs/operators';
import { MessageEntity } from 'src/app/core/chat/entity/message';
import { IMessageSocketRepository } from 'src/app/core/chat/repository/message/message-socket-repository';
import { InstanceId } from '../chat-service.service';
import { IRoomLocalRepository } from 'src/app/core/chat/repository/room/room-local-repository';
@Injectable({
providedIn: 'root'
})
export class RoomLastMessageService {
constructor(
private MessageSocketRepositoryService: IMessageSocketRepository,
private roomLocalRepository: IRoomLocalRepository
) {
this.listenToIncomingMessage()
}
listenToIncomingMessage() {
return this.MessageSocketRepositoryService.listenToMessages().pipe(
filter((message) => !message?.requestId?.startsWith(InstanceId)),
map(message => Object.assign(new MessageEntity(), message))
).subscribe(async (message) => {
this.roomLocalRepository.update(message.roomId, {
messages: [message]
})
});
}
}
+16 -9
View File
@@ -68,16 +68,19 @@
</span>
</ion-label>
</div>
<!-- <div class="item-date font-13-em" [class.item-date-active]="room.id == idSelected">{{room.duration}}</div> -->
<div class="item-date font-13-em" [class.item-date-active]="room.id == idSelected">
{{ room.displayDate }}
</div>
</div>
<div class="item-date font-13-em" [class.item-date-active]="room.id == idSelected">
<!-- {{ expirationDate[room.id] !== null ? expirationDate[room.id] + ' seconds left' : 'No expiration' }} -->
{{ expirationDate[room.id] !== null ? expirationDate[room.id] + ' seconds left' : '' }}
</div>
<!-- <div *ngIf="room.lastMessage" class="item-description d-flex align-items-center" [class.item-description-active]="room.id ==idSelected">
<div class="item-message font-13-em add-ellipsis white-space-nowrap" *ngIf="room.otherUserType == false"> {{room.lastMessage.msg}} </div>
<div class="font-13-em" *ngIf="room.otherUserType == true">está escrever ...</div>
</div> -->
<div *ngIf="room?.messages?.[0]?.message" class="item-description d-flex align-items-center" [class.item-description-active]="room.id ==idSelected">
<div class="item-message font-13-em add-ellipsis white-space-nowrap"> {{room.messages[0].message}} </div>
<!-- <div class="item-message font-13-em add-ellipsis white-space-nowrap" *ngIf="room.otherUserType == false"> {{room.messages[0].message}} </div> -->
<!-- <div class="font-13-em" *ngIf="room.otherUserType == true">está escrever ...</div> -->
</div>
</div>
</div>
</ion-item-sliding>
@@ -106,16 +109,20 @@
</span>
</ion-label>
</div>
<div class="item-date font-13-em" [class.item-date-active]="room.id == idSelected">
{{ room.displayDate }}
</div>
<!-- <div class="item-date font-13-em" [class.item-date-active]="room.id == idSelected">{{room.duration}}</div> -->
</div>
<div class="item-date font-13-em" [class.item-date-active]="room.id == idSelected">
<!-- {{ expirationDate[room.id] !== null ? expirationDate[room.id] + ' seconds left' : 'No expiration' }} -->
{{ expirationDate[room.id] !== null ? expirationDate[room.id] + ' seconds left' : '' }}
</div>
<!-- <div *ngIf="room.lastMessage" class="item-description d-flex align-items-center" [class.item-description-active]="room.id ==idSelected">
<div class="item-message font-13-em add-ellipsis white-space-nowrap" *ngIf="room.otherUserType == false"> {{room.lastMessage.msg}} </div>
<div class="font-13-em" *ngIf="room.otherUserType == true">está escrever ...</div>
</div> -->
<div *ngIf="room?.messages?.[0]?.message" class="item-description d-flex align-items-center" [class.item-description-active]="room.id ==idSelected">
<div class="item-message font-13-em add-ellipsis white-space-nowrap"> {{room?.messages?.[0]?.message}} </div>
<!-- <div class="item-message font-13-em add-ellipsis white-space-nowrap" *ngIf="room.otherUserType == false"> {{room?.messages?.[0]?.message}} </div> -->
<!-- <div class="font-13-em" *ngIf="room.otherUserType == true">está escrever ...</div> -->
</div>
</div>
</div>
</ion-item-sliding>
+9 -7
View File
@@ -22,9 +22,10 @@ import { RoomLocalRepository } from 'src/app/module/chat/data/repository/room/ro
import { map, tap } from 'rxjs/operators';
import { interval, Subscription } from 'rxjs';
import { RoomTable } from 'src/app/infra/database/dexie/instance/chat/schema/room';
import { RoomType } from 'src/app/core/chat/entity/group';
import { RoomEntity, RoomType } from 'src/app/core/chat/entity/group';
import { BoldLocalRepository } from 'src/app/module/chat/data/repository/bold/bold-local-repository'
import { BoldTable } from 'src/app/infra/database/dexie/instance/chat/schema/bold';
import { RoomViewModel } from './store/model/room';
@Component({
selector: 'app-chat',
templateUrl: './chat.page.html',
@@ -104,12 +105,13 @@ export class ChatPage implements OnInit {
ngOnInit() {
this.items$ = this.roomLocalDataSourceService.getItemsLive().pipe(
map(rooms => rooms.map(room => ({
...room,
minutesLeft: this.getSecondsLeft(room.expirationDate)
}))),
map((roomList) => roomList.map((room)=> new RoomViewModel(room))),
tap((roomList) => {
this.rooms = roomList
this.rooms = roomList.sort((a, b) =>
new Date(b.messages?.[0]?.sentAt as unknown as string) as unknown as number -
(new Date(a.messages?.[0]?.sentAt as unknown as string) as any) as unknown as number
)
})
);
@@ -125,7 +127,7 @@ export class ChatPage implements OnInit {
// Subscribe to the interval observable
this.intervalSubscription = interval$.subscribe();
this.ChatServiceService.getRoomList()
// this.ChatServiceService.getRoomList()
this.hideRefreshButton();
+61
View File
@@ -0,0 +1,61 @@
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
createdAt: typeof RoomEntitySchema._input.createdAt
expirationDate: typeof RoomEntitySchema._input.expirationDate
roomType: typeof RoomEntitySchema._input.roomType
members: typeof RoomEntitySchema._input.members
messages: typeof RoomEntitySchema._input.messages
displayDate = ''
constructor(model: IRoom) {
Object.assign(this, model)
this.formatarData()
}
formatarData() {
if(this.messages?.[0]?.sentAt) {
const dataMensagem = new Date(this.messages[0].sentAt);
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) {
this.displayDate = dataMensagem.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit', hour12: false });
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
}
}
}