diff --git a/src/app/pages/chat/chat.page.html b/src/app/pages/chat/chat.page.html index 58c9532ed..d3c56031e 100644 --- a/src/app/pages/chat/chat.page.html +++ b/src/app/pages/chat/chat.page.html @@ -123,6 +123,11 @@ (showEmptyContainer)="showEmptyContainer()" (showEmptyContainer)="showEmptyContainer()" (openNewEventPage)="openNewEventPage($event)" + + (openGroupContacts)="openGroupContactsPage($event)" + (openEditGroupPage)="openEditGroupPage($event)" + (getGroups)="getGroups($event)" + [style.display]="showMessages ? 'flex' : 'none'" [roomId]="roomId" [showMessages]="showMessages" #messagecontainer> diff --git a/src/app/pages/chat/chat.page.ts b/src/app/pages/chat/chat.page.ts index 3df2c296a..440f40b74 100644 --- a/src/app/pages/chat/chat.page.ts +++ b/src/app/pages/chat/chat.page.ts @@ -36,6 +36,8 @@ import { Store } from '@ngrx/store'; import { RoomRemoteDataSourceState } from 'src/app/services/Repositorys/chat/data-source/room/room-memory-data-source'; import { RoomRepositoryService } from 'src/app/services/Repositorys/chat/repository/room-repository.service' import { RoomListOutPutDTO } from 'src/app/services/Repositorys/chat/dto/room/roomListOutputDTO'; +import { Observable as DexieObservable } from 'Dexie'; + const { App } = Plugins; @@ -115,7 +117,7 @@ export class ChatPage implements OnInit { routerSubscription count$: Observable; - items$!: Observable; + items$!: DexieObservable; constructor( @@ -409,7 +411,7 @@ export class ChatPage implements OnInit { this.showEmptyComponent = false; - this.showGroupMessages = true; + this.showMessages = true; } } diff --git a/src/app/services/Repositorys/chat/data-source/message/message-local-data-source.service.ts b/src/app/services/Repositorys/chat/data-source/message/message-local-data-source.service.ts index c6eed105d..18c3317c6 100644 --- a/src/app/services/Repositorys/chat/data-source/message/message-local-data-source.service.ts +++ b/src/app/services/Repositorys/chat/data-source/message/message-local-data-source.service.ts @@ -7,6 +7,7 @@ import { Observable } from 'rxjs'; import { RoomOutPutDTO } from '../../dto/room/roomOutputDTO'; import { z } from 'zod'; import { MessageInputDTO } from '../../dto/message/messageInputDtO'; +import { SessionStore } from 'src/app/store/session.service'; const tableSchema = z.object({ @@ -51,7 +52,6 @@ export class MessageLocalDataSourceService { async createMessage(data: MessageInputDTO) { try { - console.log('add', data) const result = await messageDataSource.message.add(data) return ok(result as string) } catch (e) { @@ -65,7 +65,6 @@ export class MessageLocalDataSourceService { async update(data: TableMessage) { try { - console.log('update', data) const result = await messageDataSource.message.update(data.id, data) return ok(result) } catch (e) { @@ -78,8 +77,6 @@ export class MessageLocalDataSourceService { async findOrUpdate(data: TableMessage) { const findResult = await this.findMessageById(data.messageId) - console.log('findOrUpdate', findResult) - if(findResult.isOk()) { return this.update({...findResult.value, ...data}) } else { @@ -87,8 +84,8 @@ export class MessageLocalDataSourceService { } } - getItemsLive(roomId: string): Observable { - return liveQuery(() => messageDataSource.message.where('roomId').equals(roomId).toArray() as any) as any + getItemsLive(roomId: string) { + return liveQuery(() => messageDataSource.message.where('roomId').equals(roomId).toArray() ) } diff --git a/src/app/services/Repositorys/chat/data-source/message/message-remote-data-source.service.ts b/src/app/services/Repositorys/chat/data-source/message/message-remote-data-source.service.ts index e6e59195a..a9fc0f60a 100644 --- a/src/app/services/Repositorys/chat/data-source/message/message-remote-data-source.service.ts +++ b/src/app/services/Repositorys/chat/data-source/message/message-remote-data-source.service.ts @@ -1,10 +1,10 @@ import { Injectable } from '@angular/core'; import { HttpService } from 'src/app/services/http.service'; -import { MessageListInputDTO } from '../../dto/message/messageListInputDTO'; import { DataSourceReturn } from '../../../type'; import { MessageInputDTO, MessageInputDTOSchema } from '../../dto/message/messageInputDtO'; import { ValidateSchema } from 'src/app/services/decorators/validate-schema.decorator'; -import { MessageOutPutDTO } from '../../dto/message/messageOutputDTO'; +import { APIReturn } from 'src/app/services/decorators/api-validate-schema.decorator'; +import { MessageOutPutDTO, MessageOutPutDTOSchema } from '../../dto/message/messageOutputDTO'; import { MessageListOutput } from '../../dto/message/messageListOutputDTO'; @Injectable({ @@ -16,6 +16,7 @@ export class MessageRemoteDataSourceService { constructor(private httpService: HttpService) {} + @APIReturn(MessageOutPutDTOSchema) @ValidateSchema(MessageInputDTOSchema) async sendMessage(data: MessageInputDTO) { return await this.httpService.post(`${this.baseUrl}/Messages`, data); diff --git a/src/app/services/Repositorys/chat/data-source/room/room-remote-data-source.service.ts b/src/app/services/Repositorys/chat/data-source/room/room-remote-data-source.service.ts index f901ff252..7a2c4a54b 100644 --- a/src/app/services/Repositorys/chat/data-source/room/room-remote-data-source.service.ts +++ b/src/app/services/Repositorys/chat/data-source/room/room-remote-data-source.service.ts @@ -3,13 +3,14 @@ import { Result } from 'neverthrow'; import { HttpService } from 'src/app/services/http.service'; import { RoomListOutPutDTO, RoomListOutPutDTOSchema } from '../../dto/room/roomListOutputDTO'; import { RoomInputDTO, RoomInputDTOSchema } from '../../dto/room/roomInputDTO'; -import { RoomOutPutDTO } from '../../dto/room/roomOutputDTO'; +import { RoomOutPutDTO, RoomOutPutDTOSchema } from '../../dto/room/roomOutputDTO'; import { AddMemberToRoomInputDTO, AddMemberToRoomInputDTOSchema } from '../../dto/room/addMemberToRoomInputDto'; import { ValidateSchema } from 'src/app/services/decorators/validate-schema.decorator'; import { DataSourceReturn } from '../../../type'; import { RoomByIdInputDTO, RoomByIdInputDTOSchema } from '../../dto/room/roomByIdInputDTO'; import { RoomByIdOutputDTO, RoomByIdOutputDTOSchema } from '../../dto/room/roomByIdOutputDTO'; import { APIReturn } from 'src/app/services/decorators/api-validate-schema.decorator'; +import { UserRemoveListInputDTO, UserRemoveListInputDTOSchema } from '../../dto/room/userRemoveListInputDTO'; @Injectable({ providedIn: 'root' @@ -22,6 +23,7 @@ export class RoomRemoteDataSourceService { @ValidateSchema(RoomInputDTOSchema) + @APIReturn(RoomOutPutDTOSchema) async createRoom(data: RoomInputDTO): DataSourceReturn { return await this.httpService.post(`${this.baseUrl}/Room`, data); } @@ -43,16 +45,18 @@ export class RoomRemoteDataSourceService { } async deleteRoom(id: string): Promise> { - return await this.httpService.delete(`${this.baseUrl}/Room/${id}`); + return await this.httpService.delete(`${this.baseUrl}/Room/${id}`, {}); } @ValidateSchema(AddMemberToRoomInputDTOSchema) async addMemberToRoom(data: AddMemberToRoomInputDTO): DataSourceReturn { - return await this.httpService.post(`${this.baseUrl}/Room/${data.id}/Member`, data.member); + return await this.httpService.post(`${this.baseUrl}/Room/${data.id}/Member`, { members:data.members }); } - async removeMemberFromRoom(id: string, member: any): Promise> { - return await this.httpService.delete(`${this.baseUrl}/Room/${id}/Member`); + + @ValidateSchema(UserRemoveListInputDTOSchema) + async removeMemberFromRoom(data: UserRemoveListInputDTO): Promise> { + return await this.httpService.delete(`${this.baseUrl}/Room/${data.id}/Member`, {members:data.members}); } } diff --git a/src/app/services/Repositorys/chat/data-source/room/rooom-local-data-source.service.ts b/src/app/services/Repositorys/chat/data-source/room/rooom-local-data-source.service.ts index 9f97998c8..d33ac4cff 100644 --- a/src/app/services/Repositorys/chat/data-source/room/rooom-local-data-source.service.ts +++ b/src/app/services/Repositorys/chat/data-source/room/rooom-local-data-source.service.ts @@ -1,8 +1,7 @@ import { Injectable } from '@angular/core'; import { RoomListItemOutPutDTO, RoomListOutPutDTO } from '../../dto/room/roomListOutputDTO'; -import { Dexie, EntityTable, liveQuery } from 'Dexie'; +import { Dexie, EntityTable, liveQuery, Observable } from 'Dexie'; import { err, ok } from 'neverthrow'; -import { Observable } from 'rxjs'; import { z } from 'zod'; import { UserList } from '../../../contacts/data-source/contacts-data-source.service'; @@ -114,8 +113,11 @@ export class RoomLocalDataSourceService { return liveQuery(() => roomDataSource.room.get(id)) as any; } - getRoomMemberByIdLive(roomId: any): Observable { - return liveQuery(() => roomDataSource.memberList.where('roomId').equals(roomId).toArray()) as any; + async getRoomMemberById(roomId: any) { + return await roomDataSource.memberList.where('roomId').equals(roomId).toArray() + } + getRoomMemberByIdLive(roomId: any) { + return liveQuery(() => roomDataSource.memberList.where('roomId').equals(roomId).toArray()) } } diff --git a/src/app/services/Repositorys/chat/dto/message/messageOutputDTO.ts b/src/app/services/Repositorys/chat/dto/message/messageOutputDTO.ts index e33f0209b..d46a27dff 100644 --- a/src/app/services/Repositorys/chat/dto/message/messageOutputDTO.ts +++ b/src/app/services/Repositorys/chat/dto/message/messageOutputDTO.ts @@ -4,10 +4,15 @@ const DataSchema = z.object({ id: z.string(), chatRoomId: z.string(), wxUserId: z.number(), - sender: z.string().nullable(), + sender: z.object({ + wxUserId: z.number(), + wxFullName: z.string(), + wxeMail: z.string(), + userPhoto: z.string().optional() + }).nullable(), message: z.string(), messageType: z.number(), - sentAt: z.string().datetime(), + sentAt: z.string(), deliverAt: z.string().datetime().nullable(), canEdit: z.boolean(), oneShot: z.boolean(), @@ -15,10 +20,10 @@ const DataSchema = z.object({ }); -const ResponseSchema = z.object({ +export const MessageOutPutDTOSchema = z.object({ success: z.boolean(), message: z.string(), data: DataSchema }); -export type MessageOutPutDTO = z.infer +export type MessageOutPutDTO = z.infer diff --git a/src/app/services/Repositorys/chat/dto/room/addMemberToRoomInputDto.ts b/src/app/services/Repositorys/chat/dto/room/addMemberToRoomInputDto.ts index 40d6a00f4..2f92166ad 100644 --- a/src/app/services/Repositorys/chat/dto/room/addMemberToRoomInputDto.ts +++ b/src/app/services/Repositorys/chat/dto/room/addMemberToRoomInputDto.ts @@ -2,7 +2,7 @@ import { z } from "zod"; export const AddMemberToRoomInputDTOSchema = z.object({ id: z.string(), - member: z.string(), + members: z.array(z.number()), }); export type AddMemberToRoomInputDTO = z.infer diff --git a/src/app/services/Repositorys/chat/dto/room/roomOutputDTO.ts b/src/app/services/Repositorys/chat/dto/room/roomOutputDTO.ts index 044caa260..9aef66a25 100644 --- a/src/app/services/Repositorys/chat/dto/room/roomOutputDTO.ts +++ b/src/app/services/Repositorys/chat/dto/room/roomOutputDTO.ts @@ -1,6 +1,6 @@ import { z } from "zod"; -const RoomOutPutDTOSchema = z.object({ +export const RoomOutPutDTOSchema = z.object({ success: z.string(), message: z.string(), data: z.object({ diff --git a/src/app/services/Repositorys/chat/dto/room/userRemoveListInputDTO.ts b/src/app/services/Repositorys/chat/dto/room/userRemoveListInputDTO.ts new file mode 100644 index 000000000..9c3ce6ec5 --- /dev/null +++ b/src/app/services/Repositorys/chat/dto/room/userRemoveListInputDTO.ts @@ -0,0 +1,9 @@ +import { z } from "zod"; + +// Define the schema for the entire response +export const UserRemoveListInputDTOSchema = z.object({ + id: z.string(), + members: z.array(z.number()) +}); + +export type UserRemoveListInputDTO = z.infer diff --git a/src/app/services/Repositorys/chat/repository/message-respository.service.ts b/src/app/services/Repositorys/chat/repository/message-respository.service.ts index 3a61dde53..9547538ec 100644 --- a/src/app/services/Repositorys/chat/repository/message-respository.service.ts +++ b/src/app/services/Repositorys/chat/repository/message-respository.service.ts @@ -4,6 +4,7 @@ import { MessageLiveDataSourceService } from '../data-source/message/message-liv import { MessageListInputDTO } from '../dto/message/messageListInputDTO'; import { MessageInputDTO } from '../dto/message/messageInputDtO'; import { MessageLocalDataSourceService, TableMessage } from '../data-source/message/message-local-data-source.service'; +import { SessionStore } from 'src/app/store/session.service'; @Injectable({ providedIn: 'root' @@ -18,6 +19,13 @@ export class MessageRepositoryService { async sendMessage(data: MessageInputDTO) { + (data as TableMessage).sender = { + userPhoto: '', + wxeMail: SessionStore.user.Email, + wxFullName: SessionStore.user.FullName, + wxUserId: SessionStore.user.UserId + } + const localActionResult = await this.messageLocalDataSourceService.createMessage(data) if(localActionResult.isOk()) { @@ -25,14 +33,12 @@ export class MessageRepositoryService { if(sendMessageResult.isOk()) { + if(sendMessageResult.value.data.sender == null) { + delete sendMessageResult.value.data.sender + } + let clone: TableMessage = { ...sendMessageResult.value.data, - sender: { - userPhoto: '', - wxeMail: '', - wxFullName: '', - wxUserId: 0 - }, messageId: sendMessageResult.value.data.id, id : localActionResult.value } diff --git a/src/app/services/Repositorys/chat/repository/room-repository.service.ts b/src/app/services/Repositorys/chat/repository/room-repository.service.ts index 76faa2a7e..acd0da1fe 100644 --- a/src/app/services/Repositorys/chat/repository/room-repository.service.ts +++ b/src/app/services/Repositorys/chat/repository/room-repository.service.ts @@ -7,7 +7,7 @@ import { AddMemberToRoomInputDTO } from '../dto/room/addMemberToRoomInputDto'; import { RoomLocalDataSourceService } from '../data-source/room/rooom-local-data-source.service'; import { RoomByIdInputDTO } from '../dto/room/roomByIdInputDTO'; import { roomListDetermineChanges } from '../async/rooms/roomListChangeDetector'; -import { value } from '../../../../../plugin/src/sql/Operators/args-attributes'; +import { UserRemoveListInputDTO } from '../dto/room/userRemoveListInputDTO'; @Injectable({ providedIn: 'root' @@ -50,6 +50,8 @@ export class RoomRepositoryService { } } + + return result } async create(data: RoomInputDTO) { @@ -71,6 +73,13 @@ export class RoomRepositoryService { return result } + + async removeMemberToRoom(data: UserRemoveListInputDTO) { + const result = await this.roomRemoteDataSourceService.removeMemberFromRoom(data) + + return result + } + getItemsLive() { return this.roomLocalDataSourceService.getItemsLive() } @@ -83,4 +92,8 @@ export class RoomRepositoryService { getRoomMemberByIdLive(roomId: any) { return this.roomLocalDataSourceService.getRoomMemberByIdLive(roomId) } + + getRoomMemberById(roomId: any) { + return this.roomLocalDataSourceService.getRoomMemberById(roomId) + } } diff --git a/src/app/services/http-error-handle.service.ts b/src/app/services/http-error-handle.service.ts index 3d6b0e318..5aa527247 100644 --- a/src/app/services/http-error-handle.service.ts +++ b/src/app/services/http-error-handle.service.ts @@ -1,7 +1,7 @@ import { Injectable } from '@angular/core'; import { ToastService } from 'src/app/services/toast.service'; import { BackgroundService } from 'src/app/services/background.service'; - +import { HttpErrorResponse } from '@angular/common/http'; @Injectable({ providedIn: 'root' }) @@ -12,7 +12,7 @@ export class HttpErrorHandle { private backgroundService: BackgroundService ) { } - async httpStatusHandle(error) { + async httpStatusHandle(error: any) { switch (error.status ) { case 0: diff --git a/src/app/services/http.service.ts b/src/app/services/http.service.ts index fd5f35a4a..7bf4f030f 100644 --- a/src/app/services/http.service.ts +++ b/src/app/services/http.service.ts @@ -39,10 +39,14 @@ export class HttpService { } - async delete(url: string): Promise> { + async delete(url: string, body = {}): Promise> { + + const options = { + body: body // Pass payload as the body of the request + }; try { - const result = await this.http.delete(url).toPromise() + const result = await this.http.delete(url, options).toPromise() return ok (result as T) } catch (e) { return err(e as HttpErrorResponse) diff --git a/src/app/shared/chat/group-messages/group-contacts/group-contacts.page.html b/src/app/shared/chat/group-messages/group-contacts/group-contacts.page.html index e4fefa8e3..fafe6169d 100644 --- a/src/app/shared/chat/group-messages/group-contacts/group-contacts.page.html +++ b/src/app/shared/chat/group-messages/group-contacts/group-contacts.page.html @@ -35,13 +35,13 @@ - + Contactos selecção: - - + + - {{user.name }} - + {{user.wxFullName }} + @@ -55,10 +55,10 @@ {{ userContainer.key }} - - - {{user.name}} - + + + {{user.wxFullName}} + diff --git a/src/app/shared/chat/group-messages/group-contacts/group-contacts.page.ts b/src/app/shared/chat/group-messages/group-contacts/group-contacts.page.ts index c6e20fd9b..f41eb8ed8 100644 --- a/src/app/shared/chat/group-messages/group-contacts/group-contacts.page.ts +++ b/src/app/shared/chat/group-messages/group-contacts/group-contacts.page.ts @@ -1,13 +1,14 @@ -import { HttpHeaders } from '@angular/common/http'; import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; -import { ModalController } from '@ionic/angular'; -import * as _ from 'lodash'; -import { ChatService } from 'src/app/services/chat.service'; -import { NewGroupPage } from '../../new-group/new-group.page'; -import { GroupMessagesPage } from '../group-messages.page'; import { ThemeService } from 'src/app/services/theme.service' -import { SessionStore } from 'src/app/store/session.service'; import { ChatSystemService } from 'src/app/services/chat/chat-system.service'; +import { ContactRepositoryService } from 'src/app/services/Repositorys/contacts/repository/contacts-repository.service'; +import { UserContacts } from 'src/app/services/Repositorys/contacts/data-source/contacts-data-source.service'; +import { RoomRepositoryService } from 'src/app/services/Repositorys/chat/repository/room-repository.service' + +import { HttpErrorHandle } from 'src/app/services/http-error-handle.service'; +import { SessionStore } from 'src/app/store/session.service'; +import { HttpRequest } from '@angular/common/http'; +import { ZodError } from 'zod'; @Component({ selector: 'app-group-contacts', @@ -15,357 +16,192 @@ import { ChatSystemService } from 'src/app/services/chat/chat-system.service'; styleUrls: ['./group-contacts.page.scss'], }) export class GroupContactsPage implements OnInit { + showLoader: boolean; - loggedUser: any; - users = []; - - contact: string[] = [" Ana M.", "Andre F.", "Bruno G.", "Catarina T", "Tiago"]; - - options:any; - listContacts: any[]; - contacts: any; textSearch:string; - room:any; - members:any; - dm:any; - isGroupCreated:boolean; - groupName:string; - selectedUserList:any; - sessionStore = SessionStore @Input() roomId:string; @Output() openGroupMessage:EventEmitter = new EventEmitter(); + currentMembers:UserContacts[]; + allChatUsers: UserContacts[] = []; + userContainer: {[key: string]: ( UserContacts & {isChecked: boolean})[] } = {} + + selectedUsers: number[] =[] + SessionStore = SessionStore - objectUserSingleStone = [] - userContainer = {} - constructor( - private modalController: ModalController, - private chatService: ChatService, public ThemeService: ThemeService, - public ChatSystemService: ChatSystemService + public ChatSystemService: ChatSystemService, + private contactsRepositoryService: ContactRepositoryService, + private RoomRepositoryService: RoomRepositoryService, + private httpErrorHandle: HttpErrorHandle, ) - { - this.loggedUser = SessionStore.user.ChatData['data']; - this.textSearch=""; - this.dm=null; - this.room=null; + {} + ngOnInit(): void { + this.loadUsers() } - ngOnInit() { - // this.chatService.refreshtoken(); - //this.getRoomInfo(); - this.loadUsers(); - - this.getChatInfo(); - // + get hasMemberToUpload() { + return this.selectedUsers.length >= 1 } - getChatInfo(){ - - this.chatService.getRoomInfo(this.roomId).subscribe(room=>{ - - - this.getGroupContacts(room['room']); - }); - } - deleteMember(data:any){ - + async updateGroup() { - let body = { - "roomId": this.roomId, - "userId": data._id, + if(this.hasMemberToUpload) { + this.showLoader = true; + const addMembers = await this.RoomRepositoryService.addMemberToRoom({ + id: this.roomId, + members: this.selectedUsers + }) + if(addMembers.isOk()) { + // this.addContacts(this.roomId); + this.openGroupMessage.emit(this.roomId); + this.RoomRepositoryService.getRoomById(this.roomId) + } else if(addMembers.error instanceof HttpRequest) { + this.httpErrorHandle.httpStatusHandle(addMembers.error) + } + } else { + this.openGroupMessage.emit(this.roomId); } - - this.chatService.getRoomInfo(this.roomId).subscribe(room=>{ - if(room['room'].t == "p"){ - this.chatService.removeGroupMember(body).subscribe(res=>{ - - this.getMembers(); - this.getChatInfo(); - }); - } - else if(room['room'].t == "c"){ - this.chatService.removeChannelMember(body).subscribe(res=>{ - - this.getMembers(); - this.getChatInfo(); - }); - } - }); - } - getMembers(){ - this.chatService.getRoomInfo(this.roomId).subscribe(res=>{ - - let room = res['room']; - - if(room.t == "p"){ - this.chatService.getGroupMembers(this.roomId).subscribe(res=>{ - this.members = res['members']; - }); - } - else if(room.t == "c"){ - this.chatService.getChannelMembers(this.roomId).subscribe(res=>{ - this.members = res['members']; - }); - } - }); - } - - getGroupContacts(room:any){ - this.showLoader = true; - if(room.t === 'p'){ - this.chatService.getGroupMembers(this.roomId).subscribe(res=>{ - this.members = res['members']; - this.loadUsers1(this.members); - this.showLoader = false; - }); - } - else{ - this.chatService.getChannelMembers(this.roomId).subscribe(res=>{ - this.members = res['members']; - this.loadUsers1(this.members); - this.showLoader = false; - }); - } - } - - updateGroup(){ - this.showLoader = true; - this.addContacts(this.roomId); - this.openGroupMessage.emit(this.roomId); this.showLoader = false; } - openGroupMessagesPage(){ - this.showLoader = true; + + openGroupMessagesPage() { this.openGroupMessage.emit(this.roomId) + } + + async loadUsers() { + + const getallChatUsers = await this.contactsRepositoryService.getUsers() + const getRoomById = await this.RoomRepositoryService.getRoomById(this.roomId) + + if(getallChatUsers.isOk() && getRoomById.isOk()) { + + this.allChatUsers = getallChatUsers.value.data.result.sort((a,b) => { + if(a.wxFullName < b.wxFullName) { + return -1; + } + if(a.wxFullName > b.wxFullName) { + return 1; + } + return 0; + }); + + const currentMemberToMap = await this.RoomRepositoryService.getRoomMemberById(this.roomId) + + this.currentMembers = currentMemberToMap.map((e)=> ({ + userPhoto: e.user.userPhoto, + wxeMail: e.user.wxeMail, + wxFullName: e.user.wxFullName, + wxUserId: e.user.wxUserId + })) + + } + else if (getRoomById.isErr()) { + this.httpErrorHandle.httpStatusHandle(getRoomById.error) + } else if (getallChatUsers.isErr()) { + this.httpErrorHandle.httpStatusHandle(getallChatUsers.error) + } + + const currentMemberIds = this.currentMembers.map(e => e.wxUserId) + + const allSelectableUsers = this.allChatUsers.filter(e => !currentMemberIds.includes(e.wxUserId)) + + for(const user of allSelectableUsers) { + const firstLetter = user.wxFullName.charAt(0) + + if(!this.userContainer[firstLetter]) { + user['isChecked'] = false + this.userContainer[firstLetter] = [user as any] + } else { + const userIds = this.userContainer[firstLetter].map( e => e.wxUserId) + if(!userIds.includes(user.wxUserId)) { + user['isChecked'] = false + this.userContainer[firstLetter].push(user as any) + } + } + } this.showLoader = false; } - loadUsers1(members:any) { - - this.chatService.getAllUsers().subscribe((res:any)=>{ - - - - if(members){ - this.contacts = res.users.filter(f => !this.members.some(item => item._id === f._id)); - } - else{ - this.contacts = res.users.filter(data => data.username != this.sessionStore.user.UserName); - } - - this.users = this.contacts.sort((a,b) => { - if(a.name < b.name){ - return -1; - } - if(a.name > b.name){ - return 1; - } - return 0; - }); - - - this.showLoader = false; - }); - } - - loadUsers() { - - this.chatService.getAllUsers().subscribe((res:any)=>{ - - - - if(this.members){ - this.contacts = res.users.filter(f => !this.members.some(item => item._id === f._id)); - } - else{ - this.contacts = res.users.filter(data => data.username != this.sessionStore.user.UserName); - } - - this.users = this.contacts.sort((a,b) => { - if(a.name < b.name){ - return -1; - } - if(a.name > b.name){ - return 1; - } - return 0; - }); - - - for( const user of this.users) { - - const foundUser = this.objectUserSingleStone.find( e => e.name == user.name) - - if(!foundUser) { - this.objectUserSingleStone.push(user) - } else { - console.log('not found') - } - - } - - const userContainer = {} - - for(const user of this.objectUserSingleStone) { - const firstLetter = user.name.charAt(0) - - if(!userContainer[firstLetter]) { - userContainer[firstLetter] = [user] - } else { - userContainer[firstLetter].push(user) - } - } - - - this.userContainer = userContainer - - this.showLoader = false; - }); - } - - doRefresh(ev){ + doRefresh(ev) { ev.target.complete(); } - async close(){ - this.modalController.dismiss(); - if(this.isGroupCreated){ - - } - else{ - this.modalController.dismiss(); - - const modal = await this.modalController.create({ - component: NewGroupPage, - componentProps: { - name:this.groupName, - duration:'', - }, - cssClass: 'new-group modal-desktop', - backdropDismiss: false, - }); - await modal.present(); + FilterUserListedByTextSearch() { + return this.allChatUsers.filter( e => e.wxFullName.toLowerCase().includes(this.textSearch.toLowerCase())).sort((a,b) => { + if(a.wxFullName < b.wxFullName) { + return -1; + } + if(a.wxFullName > b.wxFullName) { + return 1; + } + return 0; + }); + } + + + onChangeCheckBox(user: UserContacts & {isChecked: boolean}) { + if(user.isChecked) { + this.selectedUsers.push(user.wxUserId) + } else { + this.selectedUsers = this.selectedUsers.filter(e => e!= user.wxUserId) } } onChange(event) { this.textSearch = event.detail.value; - const users: any[] = this.contacts.filter( e => e.name.toLowerCase().includes(this.textSearch.toLowerCase())).sort((a,b) => { - if(a.name < b.name) { - return -1; - } - if(a.name > b.name) { - return 1; - } - return 0; - }); + const filteredUserList: (UserContacts & {isChecked: boolean})[] = this.FilterUserListedByTextSearch() as any - const selectedUsers = this.users.filter( e => e?.isChecked == true) - - users.forEach( (user, index) => { - if(user[index]) { - console.log({user, index}) - const isCheck = selectedUsers.find( e => e._id == user._id)?.isChecked - if(isCheck) { - user[index].isChecked = isCheck - } + const userContainer = {} + for(const user of filteredUserList) { + const firstLetter = user.wxFullName.charAt(0) - // if(user[index].isChecked) { - // console.log('user[index].isChecked', user[index].isChecked) - // } + if(!userContainer[firstLetter]) { + user.isChecked = this.selectedUsers.includes(user.wxUserId) + userContainer[firstLetter] = [user] + } else { + user.isChecked = this.selectedUsers.includes(user.wxUserId) + userContainer[firstLetter].push(user) } + } + this.userContainer = userContainer + } + + + async deleteMember(user: UserContacts) { + this.showLoader = true; + + const result = await this.RoomRepositoryService.removeMemberToRoom({ + id: this.roomId, + members: [ user.wxUserId] }) - this.users = users + if(result.isOk()) { + this.currentMembers = this.currentMembers.filter( e => e.wxUserId != user.wxUserId) + const firstLetter = user.wxFullName.charAt(0) - let a = this.objectUserSingleStone.filter( e => e.name.toLowerCase().includes(this.textSearch.toLowerCase())) - - let b = {} - for(const user of a) { - const firstLetter = user.name.charAt(0) - - if(!b[firstLetter]) { - b[firstLetter] = [user] + if(!this.userContainer[firstLetter]) { + user['isChecked'] = false + this.userContainer[firstLetter] = [user as any] } else { - b[firstLetter].push(user) + user['isChecked'] = false + this.userContainer[firstLetter].push(user as any) } - + + } else if(result.error instanceof HttpRequest) { + this.httpErrorHandle.httpStatusHandle(result.error) + } else if(result.error instanceof ZodError) { + console.log(result.error.issues) } + this.showLoader = false; - this.userContainer = b - - // console.log('this.users', this.users) - } - - clicked(){ - - } - - selectedContact(user:any) { - /* this.groupName = this.room.name; */ - if(user.isChecked != true ) { - user.isChecked = false - } else { - user.isChecked = true - } - - const userIndex = this.objectUserSingleStone.findIndex((e) => e._id == user._id) - this.objectUserSingleStone[userIndex].isChecked = user.isChecked - - } - - addContacts(roomId:any) { - - this.selectedUserList = this.objectUserSingleStone.filter(function(contact) { - return contact.isChecked == true; - }); - - this.selectedUserList.forEach(user=>{ - let body ={ - "roomId":roomId, - "userId":user._id, - } - this.chatService.addUserToGroup(body).subscribe(res=>{ - this.ChatSystemService.getGroupRoom(roomId).updateContacts() - }); - }); - } - - - async newGroup(){ - this.close(); - const modal = await this.modalController.create({ - component: NewGroupPage, - cssClass: 'new-group modal-desktop', - backdropDismiss: false, - }); - - modal.onDidDismiss(); - await modal.present(); - } - - async openGroupMessages(room:any){ - this.close(); - const modal = await this.modalController.create({ - component: GroupMessagesPage, - componentProps: { - room: room, - }, - cssClass: 'group-messages', - backdropDismiss: false - }); - - - modal.onDidDismiss(); - await modal.present(); } } diff --git a/src/app/shared/chat/group-messages/group-messages.page.ts b/src/app/shared/chat/group-messages/group-messages.page.ts index 041ae5845..d84c01f6d 100644 --- a/src/app/shared/chat/group-messages/group-messages.page.ts +++ b/src/app/shared/chat/group-messages/group-messages.page.ts @@ -521,7 +521,6 @@ export class GroupMessagesPage implements OnInit, OnChanges, AfterViewInit, OnDe }); - } openSendGroupMessageOptions(ev?: any) { diff --git a/src/app/shared/chat/messages/contacts/contacts.page.ts b/src/app/shared/chat/messages/contacts/contacts.page.ts index 965520619..f955cd0c7 100644 --- a/src/app/shared/chat/messages/contacts/contacts.page.ts +++ b/src/app/shared/chat/messages/contacts/contacts.page.ts @@ -12,7 +12,6 @@ import { RoomRepositoryService } from 'src/app/services/Repositorys/chat/reposit import { HttpErrorResponse } from '@angular/common/http'; - class UserToSelect { } @@ -95,7 +94,7 @@ export class ContactsPage implements OnInit { }, () => { this.loading = false - }); + }); }*/ } @@ -170,7 +169,7 @@ export class ContactsPage implements OnInit { } /* this.chatService.createRoom(body).subscribe(res => { - + this.room = res['room']; this.openMessagesModal(this.room._id); this.ChatSystemService.getAllRooms() diff --git a/src/app/shared/chat/messages/messages.page.html b/src/app/shared/chat/messages/messages.page.html index 502db2cad..4f4b64ccb 100644 --- a/src/app/shared/chat/messages/messages.page.html +++ b/src/app/shared/chat/messages/messages.page.html @@ -7,7 +7,7 @@ - + @@ -41,9 +41,14 @@ Room ID: {{ roomData.id }} - {{ roomMessage$ | async | json }} + + + {{ message | json }} + + + members diff --git a/src/app/shared/chat/messages/messages.page.scss b/src/app/shared/chat/messages/messages.page.scss index d26566c29..8edacc9f9 100644 --- a/src/app/shared/chat/messages/messages.page.scss +++ b/src/app/shared/chat/messages/messages.page.scss @@ -143,41 +143,54 @@ ion-content { .messages { font-size: rem(13); font-family: Roboto; - overflow: auto; + // overflow: auto; - //set scroll do bottom - position: absolute; - top: 0; - left: 0; - overflow-x: hidden; - overflow-y: auto; - width: 100%; - height: 100%; - word-wrap: break-word; - -webkit-overflow-scrolling: touch; + // //set scroll do bottom + // position: absolute; + // top: 0; + // left: 0; + // overflow-x: hidden; + // overflow-y: auto; + // width: 100%; + // height: 100%; + // word-wrap: break-word; + // -webkit-overflow-scrolling: touch; - .container-width-100 { - width: 100%; - overflow: auto; - } - - .incoming-true, - .incoming-false { + .other-message, + .my-message { padding: 15px 20px; border-radius: 10px; + + // Common styles for incoming messages + display: flex; + justify-content: flex-start; + align-items: center; + //margin-bottom: 10px; // Adjust as needed + //padding: 5px; // Adjust as needed } - .incoming-true { + .other-message { margin: 10px 75px 10px 20px; - background: #ebebeb; - float: left; + // background: #ebebeb; + // float: left; + // Styles for incoming messages from other users + justify-content: flex-start; } } - .incoming-false { + .my-message { margin: 10px 20px 10px 75px; background: var(--chat-incoming-msg-color); - float: right; + //float: right; + // Styles for incoming messages from the current user + justify-content: flex-end; + } + + .message-bubble { + // Styles for the message bubble + background-color: #e2e2e2; // Example background color + padding: 10px; // Adjust as needed + border-radius: 10px; // Adjust as needed } .title { diff --git a/src/app/shared/chat/messages/messages.page.ts b/src/app/shared/chat/messages/messages.page.ts index 58a7a1b5f..b2177fe1a 100644 --- a/src/app/shared/chat/messages/messages.page.ts +++ b/src/app/shared/chat/messages/messages.page.ts @@ -40,7 +40,9 @@ import { MessageRepositoryService } from 'src/app/services/Repositorys/chat/repo import { MessageInputDTO } from 'src/app/services/Repositorys/chat/dto/message/messageInputDtO'; import { TableMemberList } from 'src/app/services/Repositorys/chat/data-source/room/rooom-local-data-source.service'; import { Observable } from 'rxjs'; - +import { TableMessage } from 'src/app/services/Repositorys/chat/data-source/message/message-local-data-source.service'; +import { ChatPopoverPage } from '../../popover/chat-popover/chat-popover.page'; +import { Observable as DexieObservable } from 'Dexie'; const IMAGE_DIR = 'stored-images'; @Component({ @@ -66,6 +68,12 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy @Output() openNewEventPage: EventEmitter = new EventEmitter(); @Output() getDirectMessages: EventEmitter = new EventEmitter(); + @Output() closeAllDesktopComponents: EventEmitter = new EventEmitter(); + @Output() showEmptyContainer: EventEmitter = new EventEmitter(); + @Output() openGroupContacts: EventEmitter = new EventEmitter(); + @Output() openEditGroupPage: EventEmitter = new EventEmitter(); + @Output() getGroups: EventEmitter = new EventEmitter(); + chatMessageStore = ChatMessageStore @@ -109,9 +117,9 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy textField = '' - roomData$: Observable - roomMessage$: Observable - roomMembers$: Observable + roomData$: DexieObservable + roomMessage$: DexieObservable + roomMembers$: DexieObservable constructor( public popoverController: PopoverController, @@ -144,7 +152,7 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy ngOnChanges(changes: SimpleChanges): void { this.roomData$ = this.roomRepositoryService.getItemByIdLive(this.roomId) this.roomMessage$ = this.messageRepositoryService.getItemsLive(this.roomId) - this.roomMembers$ = this.roomRepositoryService.getRoomMemberByIdLive(this.roomId) + this.roomMembers$ = this.roomRepositoryService.getRoomMemberByIdLive(this.roomId) as any this.roomRepositoryService.getRoomById(this.roomId) this.messageRepositoryService.listAllMessagesByRoomId(this.roomId) } @@ -583,7 +591,6 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy async _openMessagesOptions() { - const enterAnimation = (baseEl: any) => { const backdropAnimation = this.animationController.create() .addElement(baseEl.querySelector('ion-backdrop')!) @@ -607,17 +614,48 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy return enterAnimation(baseEl).direction('reverse'); } - const modal = await this.modalController.create({ enterAnimation, leaveAnimation, - component: MessagesOptionsPage, - cssClass: 'model profile-modal search-submodal', + component: ChatPopoverPage, + cssClass: 'model search-submodal chat-option-aside', componentProps: { roomId: this.roomId, + members: [], + isAdmin: this.isAdmin } }); - return await modal.present(); + await modal.present(); + modal.onDidDismiss().then(res => { + + if (res.data == 'leave') { + this.getRoomInfo(); + this.closeAllDesktopComponents.emit(); + this.showEmptyContainer.emit(); + this.ChatSystemService.hidingRoom(this.roomId).catch((error) => console.error(error)); + } + else if (res.data == 'delete') { + this.closeAllDesktopComponents.emit(); + this.showEmptyContainer.emit(); + } + else if (res.data == 'cancel') { + + } + else if (res.data == 'edit') { + + //this.closeAllDesktopComponents.emit(); + this.openEditGroupPage.emit(this.roomId); + } else if (res.data == 'addUser') { + + this.openGroupContactsPage(); + } + else {} + + }); + } + + openGroupContactsPage() { + this.openGroupContacts.emit(this.roomId); } diff --git a/src/app/shared/chat/new-group/new-group.page.ts b/src/app/shared/chat/new-group/new-group.page.ts index a5fe412d4..ce507f803 100644 --- a/src/app/shared/chat/new-group/new-group.page.ts +++ b/src/app/shared/chat/new-group/new-group.page.ts @@ -1,10 +1,9 @@ import { Component, EventEmitter, Input, OnInit, Output,ViewContainerRef } from '@angular/core'; -import { ModalController, PickerController, PopoverController } from '@ionic/angular'; +import { PickerController, PopoverController } from '@ionic/angular'; import { ChatSystemService } from 'src/app/services/chat/chat-system.service'; import { DataService } from 'src/app/services/data.service'; import { GroupDurationPage } from 'src/app/shared/popover/group-duration/group-duration.page'; import { SessionStore } from 'src/app/store/session.service'; -import { GroupContactsPage } from '../group-messages/group-contacts/group-contacts.page'; import { ToastService } from 'src/app/services/toast.service'; import { ThemeService } from 'src/app/services/theme.service'; import { RouteService } from 'src/app/services/route.service'; @@ -45,10 +44,8 @@ export class NewGroupPage implements OnInit{ constructor( private pickerController: PickerController, private popoverController: PopoverController, - private modalController: ModalController, private dataService:DataService, public ChatSystemService: ChatSystemService, - private toastService: ToastService, public ThemeService: ThemeService, private RouteService: RouteService, private viewContainerRef: ViewContainerRef, @@ -117,59 +114,8 @@ export class NewGroupPage implements OnInit{ async createGroup() { this.createGroup1() - - // let name = this.groupName.split(' ').join('-'); - // //Take out all special characters in string - // name = name.normalize("NFD").replace(/[\u0300-\u036f]/g, ""); - - // let customFields = {} - // let res:any; - - - // const loader = this.toastService.loading(); - - // if(this.expirationDate) { - // let customFields = { - // "countDownDate":this.expirationDate - // } - // res = await this.ChatSystemService.createPrivateRoom(name, SessionStore.user.UserName, customFields); - // } - // else { - // res = await this.ChatSystemService.createPrivateRoom(name, SessionStore.user.UserName, customFields); - // } - - - // loader.remove(); - - // // FsId - // // DocId - - // if(res?.result?.rid) { - // this.addGroupMessage.emit(res.result.rid); - - // this.ChatSystemService.getAllRooms(() => { - // if(!this.ChatSystemService.getGroupRoom(res.result.rid)) { - // this.createGroupWithAttachmentsCath(res) - // } else { - // setTimeout(()=> { - - // this.createGroupWithAttachments(res) - - // }, 500) - // } - // }, res.result.rid); - - - - // } else { - - // this.toastService._badRequest('Existe um grupo com este nome!'); - - // } - } - async createGroup1() { const result = await this.roomRepositoryService.create({ roomName: this.groupName, @@ -178,20 +124,14 @@ export class NewGroupPage implements OnInit{ expirationDate: null }) - - console.log(result) - if(result.isOk()) { - // this.addGroupMessage.emit(result); - } else if(result.error instanceof HttpErrorResponse) { } } - createGroupWithAttachmentsCath(res: any) { if(!this.ChatSystemService.getGroupRoom(res.result.rid)) { setTimeout(() => { @@ -243,27 +183,6 @@ export class NewGroupPage implements OnInit{ }, 150); } - async addContacts() { - this.close(); - - let name = this.groupName.split(' ').join('-'); - - - const modal = await this.modalController.create({ - component: GroupContactsPage, - componentProps: { - isCreated:this.isGroupCreated, - name: name, - duration:'', - }, - cssClass: 'contacts', - backdropDismiss: false - }); - - - modal.onDidDismiss(); - await modal.present(); - } async setDuration(ev: any) { const popover = await this.popoverController.create({ diff --git a/src/app/shared/popover/chat-popover/chat-popover.page.html b/src/app/shared/popover/chat-popover/chat-popover.page.html index 340f70792..848ff49a9 100644 --- a/src/app/shared/popover/chat-popover/chat-popover.page.html +++ b/src/app/shared/popover/chat-popover/chat-popover.page.html @@ -8,12 +8,22 @@ - Adicionar + + + + Adicionar + Sair do Grupo + Alterar + nome do grupo + + Cancelar + Apagar grupo - \ No newline at end of file +
{{user.name }}
{{user.wxFullName }}
Room ID: {{ roomData.id }}