remove duplicate

This commit is contained in:
Peter Maquiran
2024-09-01 12:57:33 +01:00
parent 6193aac4a8
commit 41c63b6c56
33 changed files with 359 additions and 323 deletions
+1 -1
View File
@@ -21,7 +21,7 @@ export enum IMessageType {
export const MessageEntitySchema = z.object({
$id: z.any().optional(),
id: z.string().optional(),
id: z.string().uuid().optional(),
roomId: z.string().uuid().optional(),
receiverId: z.number().optional(),
message: z.string().nullable().optional(),
@@ -8,5 +8,5 @@ import { Observable } from "rxjs";
export abstract class IRoomLocalRepository extends DexieRepository<RoomTable, RoomTable> {
abstract getItemsLive(): Observable<RoomTable[]>
abstract getRoomByIdLive(id: any) : DexieObservable<RoomTable>
abstract getRoomByIdLive(id: any) : Observable<RoomTable>
}
@@ -4,7 +4,7 @@ import { z } from 'zod';
export const MessageTableSchema = z.object({
$id: z.number().optional(),
id: z.string().optional(),
id: z.string().uuid().optional(),
roomId: z.string().uuid().optional(),
message: z.string().nullable().optional(),
messageType: z.number(),
+9 -4
View File
@@ -21,7 +21,8 @@ export class HttpService {
data: response.body,
status: response.status,
headers: response.headers,
url: response.url || url
url: response.url || url,
method: '',
}
this.responseSubject.next(ok(data))
return ok(data);
@@ -36,6 +37,7 @@ export class HttpService {
const response = await this.http.get<T>(url, { ...options, observe: 'response' }).toPromise();
const data = {
method: 'GET',
data: response.body,
status: response.status,
headers: response.headers,
@@ -58,7 +60,8 @@ export class HttpService {
data: response.body,
status: response.status,
headers: response.headers,
url: response.url || url
url: response.url || url,
method: '',
}
this.responseSubject.next(ok(data))
@@ -77,7 +80,8 @@ export class HttpService {
data: response.body,
status: response.status,
headers: response.headers,
url: response.url || url
url: response.url || url,
method: '',
}
this.responseSubject.next(ok(data))
@@ -101,7 +105,8 @@ export class HttpService {
data: response?.body,
status: response?.status,
headers: response?.headers,
url: response?.url || url
url: response?.url || url,
method: '',
}
this.responseSubject.next(ok(data))
+1
View File
@@ -10,4 +10,5 @@ export interface HttpResult<T> {
status: number;
headers: HttpHeaders;
url: string;
method: string
}
+2 -3
View File
@@ -127,15 +127,14 @@ export class SignalRConnection {
this.sendDataSubject.pipe(
filter((message) => {
console.log(message)
return input.data.requestId == message?.data.requestId ||
input.data.roomName == message?.data.roomName
input?.data?.roomName == message?.data.roomName && typeof input?.data?.roomName == 'string'
}),
first()
).subscribe(value => {
resolve(ok(value.data as unknown as T))
// console.log('Received valid value:', value);
console.log('Received valid value:', value);
});
} catch(error) {
@@ -49,6 +49,10 @@ export class MessageSocketRepositoryService implements IMessageSocketRepository
data: data,
})
if(result.isOk()) {
console.log('recieve', result.value)
}
return result;
}
@@ -6,6 +6,8 @@ import { Observable as DexieObservable, PromiseExtended } from 'Dexie';
import { MessageTable, MessageTableSchema } from 'src/app/infra/database/dexie/instance/chat/schema/message';
import { chatDatabase } from 'src/app/infra/database/dexie/service';
import { IMessageLocalRepository } from 'src/app/core/chat/repository/message/message-local-repository';
import { combineLatest, from, Observable } from 'rxjs';
import { map } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
@@ -49,5 +51,25 @@ export class MessageLocalDataSourceService extends DexieRepository<MessageTable,
console.error('Error fetching messages:', error);
}
}
getLastMessageForRooms(roomIds: string[]): Observable<any[]> {
const observables = roomIds.map(roomId =>
from (liveQuery(async() =>{
const messages = await chatDatabase.message
.where('roomId')
.equals(roomId)
.reverse()
.sortBy('timestamp')
return messages[0] || null; // Return the first item (latest message) or null if no message
})).pipe(
map((message) => ({ roomId, message: message || null })) // Attach roomId to the result
)
);
return combineLatest(observables); // Combine all observables into one array of results
}
}
@@ -20,7 +20,7 @@ export class RoomLocalRepository extends DexieRepository<RoomTable, RoomTable> i
}
getRoomByIdLive(id: any) {
return liveQuery(() => chatDatabase.room.get(id));
return from(liveQuery(() => chatDatabase.room.get(id)));
}
}
@@ -12,6 +12,7 @@ import { RoomByIdOutputDTO } from 'src/app/module/chat/domain/use-case/room/room
import { RoomUpdateInputDTO, RoomUpdateOutputDTO } from 'src/app/module/chat/domain/use-case/room/room-update-by-id-use-case.service';
import { RoomListOutPutDTO } from '../../../domain/use-case/room/room-get-list-use-case.service';
import { z } from 'zod';
import { HttpAdapter } from 'src/app/infra/http/adapter';
const RoomByIdInputDTOSchema = z.string()
type RoomByIdInputDTO = z.infer<typeof RoomByIdInputDTOSchema>
@@ -27,6 +28,7 @@ export class RoomRemoteDataSourceService implements IRoomRemoteRepository {
constructor(
private httpService: HttpService,
private socket: SignalRService,
private Http: HttpAdapter
) {}
@@ -39,13 +41,17 @@ export class RoomRemoteDataSourceService implements IRoomRemoteRepository {
//@APIReturn(RoomListOutPutDTOSchema, 'get/Room')
async getRoomList(): Promise<DataSourceReturn<RoomListOutPutDTO>> {
return await this.httpService.get<RoomListOutPutDTO>(`${this.baseUrl}/Room?userId=${SessionStore.user.UserId}`);
const result = await this.Http.get<RoomListOutPutDTO>(`${this.baseUrl}/Room?userId=${SessionStore.user.UserId}`);
return result.map((e)=> e.data)
}
//@ValidateSchema(RoomByIdInputDTOSchema)
//@APIReturn(RoomByIdOutputDTOSchema,'get/Room/${id}')
async getRoom(id: RoomByIdInputDTO): DataSourceReturn<RoomByIdOutputDTO> {
return await this.httpService.get(`${this.baseUrl}/Room/${id}`);
const result = await this.Http.get(`${this.baseUrl}/Room/${id}`);
return result.map((e)=> e.data)
}
//@ValidateSchema(RoomUpdateInputDTOSchema)
@@ -5,6 +5,8 @@ import { filter, map } from 'rxjs/operators';
import { SocketMessage } from 'src/app/infra/socket/signalR/signalR';
import { ITypingRemoteRepository } from 'src/app/core/chat/repository/typing/typing-remote-repository';
import { z } from "zod"
import { InstanceId } from '../../../domain/chat-service.service';
import { v4 as uuidv4 } from 'uuid'
export const UserTypingDTOSchema = z.object({
requestId: z.string(),
@@ -32,7 +34,7 @@ export class UserTypingRemoteRepositoryService implements ITypingRemoteRepositor
roomId,
UserName:SessionStore.user.FullName,
userId:SessionStore.user.UserId,
requestId: '',
requestId: InstanceId +'@'+ uuidv4(),
},
})
}
@@ -38,7 +38,8 @@ import { HttpListenToMessageLoadHistoryAdapter } from './adapter'
import { HttpListenToMessageLoadHistoryUseCaseInput } from 'src/app/core/chat/usecase/message/http-listen-to-message-load-history-by-roomId-use-case';
import { MessageSocketRepositoryService } from 'src/app/module/chat/data/repository/message/message-live-signalr-data-source.service'
import { MessageMarkAsReadInput } from "src/app/module/chat/domain/use-case/message/message-mark-as-read-use-case.service";
import { BoldRemoveByRoomIdInput, BoldRemoveByRoomIdService } from 'src/app/module/chat/domain/use-case/bold/bold-remove-by-room-id.service'
import { BoldRemoveByRoomIdInput, BoldRemoveByRoomIdService } from 'src/app/module/chat/domain/use-case/bold/bold-remove-by-room-id.service';
import { MemberListHttpSyncUseCase } from 'src/app/module/chat/domain/use-case/member/member-list-http-sync-use-case.ts.service'
export const InstanceId = uuidv4();
@Injectable({
@@ -78,7 +79,8 @@ export class ChatServiceService {
private MessageMarkAllMessageAsReadByRoomIdService: MessageMarkAllMessageAsReadByRoomIdService,
private HttpListenToMessageLoadHistory: HttpListenToMessageLoadHistoryAdapter,
private MessageSocketRepositoryService: MessageSocketRepositoryService,
private BoldRemoveByRoomIdService: BoldRemoveByRoomIdService
private BoldRemoveByRoomIdService: BoldRemoveByRoomIdService,
private MemberListHttpSyncUseCase: MemberListHttpSyncUseCase
) {
this.MessageSocketRepositoryService.listenToDeleteMessages()
.pipe()
@@ -17,7 +17,6 @@ export class RoomLastMessageService {
this.listenToIncomingMessage()
}
listenToIncomingMessage() {
return this.MessageSocketRepositoryService.listenToMessages().pipe(
filter((message) => !message?.requestId?.startsWith(InstanceId)),
@@ -0,0 +1,61 @@
import { Injectable } from '@angular/core';
import { filter, map } from 'rxjs/operators';
import { HttpAdapter } from 'src/app/infra/http/adapter';
import { RoomByIdOutputDTO } from '../../../domain/use-case/room/room-get-by-id-use-case.service';
import { IMemberLocalRepository } from 'src/app/core/chat/repository/member/member-local-repository';
import { MemberListMapper } from '../../../domain/mapper/memberLIstMapper';
import { roomMemberListDetermineChanges } from '../../../data/async/list/rooms/roomMembersChangeDetector';
@Injectable({
providedIn: 'root'
})
export class MemberListHttpSyncUseCase {
constructor(
private http: HttpAdapter,
private memberLocalRepository: IMemberLocalRepository
) {
// this.http.listen().pipe(
// filter((response)=> {
// if(response?.isOk()) {
// return response.value.url.includes('/Room/') && typeof response.value?.data?.data?.roomName == 'string'
// }
// return false
// }),
// map((response: any) => response.value.data as RoomByIdOutputDTO)
// )
// .subscribe(async (data) => {
// this.syncMembers(data)
// })
}
private async syncMembers(roomData: RoomByIdOutputDTO): Promise<void> {
const roomId = roomData.data.id;
// Fetch local members and determine changes
const localList = await this.memberLocalRepository.getRoomMemberById(roomId);
const { membersToInsert, membersToUpdate, membersToDelete } = roomMemberListDetermineChanges(roomData.data.members, localList, roomId);
// Sync members
// for (const user of membersToInsert) {
// await this.memberLocalRepository.addMember(MemberListMapper(user, roomId));
// }
// for (const user of membersToUpdate) {
// await this.memberLocalRepository.updateMemberRole(MemberListMapper(user, roomId));
// }
// for (const user of membersToDelete) {
// await this.memberLocalRepository.removeMemberFromRoom(user.$roomIdUserId);
// }
// console.log({membersToInsert, membersToUpdate, membersToDelete})
await Promise.all([
...membersToInsert.map(user => this.memberLocalRepository.addMember(MemberListMapper(user, roomId))),
...membersToUpdate.map(user => this.memberLocalRepository.updateMemberRole(MemberListMapper(user, roomId))),
...membersToDelete.map(user => this.memberLocalRepository.removeMemberFromRoom(user.$roomIdUserId))
]);
}
}
@@ -161,6 +161,8 @@ export class MessageCreateUseCaseService {
if(sendMessageResult.isOk()) {
console.log('sendMessageResult', sendMessageResult.value.id)
if(sendMessageResult.value.sender == undefined || sendMessageResult.value.sender == null) {
delete sendMessageResult.value.sender
@@ -172,7 +174,15 @@ export class MessageCreateUseCaseService {
$id : message.$id
}
this.messageLocalDataSourceService.update(message.$id, {...clone, sending: false, roomId: message.roomId})
this.messageLocalDataSourceService.update(message.$id, {...clone, sending: false, roomId: message.roomId}).then((data)=> {
if(data.isOk()) {
} else {
tracing.hasError('failed to update send message')
console.log(sendMessageResult)
console.log(data.error)
}
})
return sendMessageResult
} else {
@@ -51,21 +51,7 @@ export class CreateRoomUseCaseService {
if(result.isOk()) {
console.log('create rooms',result.value)
if(!result?.value?.createdBy) {
let dataObject;
result.value.createdBy = {
wxeMail: SessionStore.user.Email,
wxFullName: SessionStore.user.FullName,
wxUserId: SessionStore.user.UserId,
}
dataObject = result.value
}
const localResult = await this.roomLocalDataSourceService.insert(result.value)
return localResult.map(e => result.value)
return result
} else {
tracing.hasError("socket close");
console.log(result.error)
@@ -1,9 +1,5 @@
import { Injectable } from '@angular/core';
import { id } from 'date-fns/locale';
import { isHttpResponse } from 'src/app/services/http.service';
import { roomListDetermineChanges } from '../../../data/async/list/rooms/roomListChangeDetector';
import { roomMemberListDetermineChanges } from '../../../data/async/list/rooms/roomMembersChangeDetector';
import { MemberListMapper } from '../../mapper/memberLIstMapper';
import { captureAndReraiseAsync } from 'src/app/services/decorators/captureAndReraiseAsync';
import { z } from 'zod';
import { IRoomRemoteRepository } from 'src/app/core/chat/repository/room/room-remote-repository';
@@ -11,8 +7,6 @@ import { IMemberLocalRepository } from 'src/app/core/chat/repository/member/memb
import { IRoomLocalRepository } from 'src/app/core/chat/repository/room/room-local-repository';
import { GetRoomByIdMapper } from 'src/app/core/chat/mapper/getRoomByIdMapper';
import { RoomEntity, RoomType } from 'src/app/core/chat/entity/group';
import { GetRoomListMapper } from 'src/app/core/chat/mapper/getRoomListMapper';
import { roomByIdDetermineChanges } from '../../../data/async/list/rooms/roomByIdChangeDetector';
import { diff, addedDiff, deletedDiff, updatedDiff, detailedDiff } from 'deep-object-diff';
import { zodSafeValidation } from 'src/app/utils/zodValidation';
@@ -101,23 +95,6 @@ export class GetRoomByIdUseCaseService {
this.roomLocalDataSourceService.insert(room)
}
// ============================
const localList = await this.MemberListLocalRepository.getRoomMemberById(id)
const { membersToInsert, membersToUpdate, membersToDelete } = roomMemberListDetermineChanges(validData.value.data.members, localList, id)
for (const user of membersToInsert) {
await this.MemberListLocalRepository.addMember(MemberListMapper(user, id))
}
for (const user of membersToUpdate) {
await this.MemberListLocalRepository.updateMemberRole(MemberListMapper(user, id))
}
for(const user of membersToDelete) {
await this.MemberListLocalRepository.removeMemberFromRoom(user.$roomIdUserId)
}
}
} else {
@@ -0,0 +1,16 @@
import { TestBed } from '@angular/core/testing';
import { RoomSetLastMessageService } from './room-set-last-message.service';
describe('RoomSetLastMessageService', () => {
let service: RoomSetLastMessageService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(RoomSetLastMessageService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});
@@ -0,0 +1,36 @@
import { Injectable } from '@angular/core';
import { IMessageSocketRepository } from 'src/app/core/chat/repository/message/message-socket-repository';
import { IRoomLocalRepository } from 'src/app/core/chat/repository/room/room-local-repository';
import { filter, map } from 'rxjs/operators';
import { InstanceId } from '../../chat-service.service';
import { MessageEntity } from 'src/app/core/chat/entity/message';
@Injectable({
providedIn: 'root'
})
export class RoomSetLastMessageService {
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]
})
});
}
listenToOnSendDataToSocket() {
}
}
-4
View File
@@ -36,10 +36,6 @@ const routes: Routes = [
path: 'chat-message-debugging',
loadChildren: () => import('./modal/chat-message-debugging/chat-message-debugging.module').then( m => m.ChatMessageDebuggingPageModule)
},
{
path: 'add-user',
loadChildren: () => import('./component/add-user/add-user.module').then( m => m.AddUserPageModule)
},
{
path: 'empty-chat',
loadChildren: () => import('./component/empty-chat/empty-chat.module').then( m => m.EmptyChatPageModule)
+22 -55
View File
@@ -39,19 +39,25 @@
</ion-segment>
</ion-toolbar>
<!-- <div *ngFor="let room of roomsWithLastMessages">
{{ room.name }} == {{ room.lastMessage.message }}
</div> -->
<div class=" aside overflow-y-auto d-flex flex-wrap flex-grow-1">
<div class="width-100" [ngSwitch]="segment">
<ion-list *ngSwitchCase="1">
<ion-item-sliding>
<div class="width-100">
<div class="item item-hover width-100 d-flex ion-no-padding ion-no-margin"
*ngFor="let room of (items$ | async)"
[class.item-active]="room.id == idSelected" [class.hide-room]="room.roomType != 1">
*ngFor="let room of rooms"
[class.item-active]="room.id == idSelected" [class.hide-room]="room.roomType != segment">
<div class="item-icon">
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " class="icon" slot="start" src="assets/images/icons-chat-group-chat-40.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' && room.id != idSelected " class="icon" slot="start" src="assets/images/theme/gov/icons-chat-group-chat-40.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' && room.id == idSelected " class="icon" slot="start" src="assets/images/theme/gov/icons-chat-group-chat-40-hover.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'doneIt' && room.id != idSelected " class="icon" slot="start" src="assets/images/theme/{{ThemeService.currentTheme}}/icons-chat-group-chat-40.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'doneIt' && room.id == idSelected " class="icon" slot="start" src="assets/images/theme/{{ThemeService.currentTheme}}/icons-chat-group-chat-40-hover.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' && room.id != idSelected && room.roomType == RoomType.Group " class="icon" slot="start" src="assets/images/theme/gov/icons-chat-chat-40.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' && room.id == idSelected && room.roomType == RoomType.Group" class="icon" slot="start" src="assets/images/theme/gov/icons-chat-chat-40-hover.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'default' && room.roomType == RoomType.Direct" class="icon" slot="start" src="assets/images/icons-chat-group-chat-40.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' && room.id != idSelected && room.roomType == RoomType.Direct" class="icon" slot="start" src="assets/images/theme/gov/icons-chat-group-chat-40.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' && room.id == idSelected && room.roomType == RoomType.Direct" class="icon" slot="start" src="assets/images/theme/gov/icons-chat-group-chat-40-hover.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'doneIt' && room.id != idSelected && room.roomType == RoomType.Direct" class="icon" slot="start" src="assets/images/theme/{{ThemeService.currentTheme}}/icons-chat-group-chat-40.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'doneIt' && room.id == idSelected && room.roomType == RoomType.Direct" class="icon" slot="start" src="assets/images/theme/{{ThemeService.currentTheme}}/icons-chat-group-chat-40-hover.svg"></ion-icon>
</div>
<div
(click)="openMessagesPage(room.id)"
@@ -83,50 +89,10 @@
</div>
</div>
</div>
</ion-item-sliding>
</ion-list>
<ion-list *ngSwitchCase="2">
<ion-item-sliding>
<div class="item item-hover width-100 d-flex ion-no-padding ion-no-margin"
*ngFor="let room of (items$ | async)"
[class.item-active]="room.id == idSelected" [class.hide-room]="room.roomType != 2">
<div class="item-icon">
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' && room.id != idSelected " class="icon" slot="start" src="assets/images/theme/gov/icons-chat-chat-40.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' && room.id == idSelected " class="icon" slot="start" src="assets/images/theme/gov/icons-chat-chat-40-hover.svg"></ion-icon>
</div>
<div
(click)="openMessagesPage(room.id)"
class="item-content flex-grow-1 cursor-pointer"><!-- (click)="openMessages(dm)" -->
<div class="item-title-time">
<div class="item-title" [class.item-title-active]="room.id == idSelected">
<ion-label >
<span >
<div >
<div class="font-15-em" [class.bold-message]="boldTable?.[room.id]?.bold">
{{room.roomName}}
</div>
</div>
</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?.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>
</ion-list>
<div class="width-100" [ngSwitch]="segment">
</div>
<!-- <button (click)="sendMsg()" style="height: 41px;">Send message</button> -->
@@ -142,6 +108,7 @@
</app-empty-chat>
<app-messages class=" height-100 flex-column"
[room]="RoomSelected"
*ngIf="showMessages"
[style.display]="showMessages ? 'flex' : 'none'"
(closeAllDesktopComponents)="closeAllDesktopComponents()"
@@ -184,14 +151,14 @@
<app-edit-group [roomId]="roomId"
(closeAllDesktopComponents)="closeAllDesktopComponents()"
(openGroupMessage)="openGroupMessagesPage($event)"
(openGroupMessage)="openMessagesPage($event)"
*ngIf="showEditGroup"
[style.display]="showEditGroup ? 'flex' : 'none'"
class="height-100 flex-column">
</app-edit-group>
<app-group-contacts
(openGroupMessage)="openGroupMessagesPage($event)"
(openGroupMessage)="openMessagesPage($event)"
*ngIf="showGroupContacts"
[style.display]="showGroupContacts ? 'flex' : 'none'"
[roomId]="groupRoomId" class=" height-100 flex-column"
+68 -35
View File
@@ -19,13 +19,14 @@ import { Observable as DexieObservable } from 'Dexie';
import { EditGroupPage } from './modal/edit-group/edit-group.page';
import { ChatServiceService } from 'src/app/module/chat/domain/chat-service.service'
import { RoomLocalRepository } from 'src/app/module/chat/data/repository/room/room-local-repository.service'
import { map, tap } from 'rxjs/operators';
import { interval, Subscription } from 'rxjs';
import { map, switchMap, tap } from 'rxjs/operators';
import { BehaviorSubject, interval, Subscription } from 'rxjs';
import { RoomTable } from 'src/app/infra/database/dexie/instance/chat/schema/room';
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';
import { MessageLocalDataSourceService } from 'src/app/module/chat/data/repository/message/message-local-data-source.service'
@Component({
selector: 'app-chat',
templateUrl: './chat.page.html',
@@ -34,7 +35,7 @@ import { RoomViewModel } from './store/model/room';
export class ChatPage implements OnInit {
showLoader: boolean;
segment: RoomType = RoomType.Group
segment: RoomType = RoomType.Direct
idSelected: string;
roomId: any;
@@ -59,7 +60,7 @@ export class ChatPage implements OnInit {
// count$: Observable<RoomRemoteDataSourceState>;
//items$!: DexieObservable<RoomTable[]>;
items$!: Observable<RoomTable[]>;
private rooms: RoomTable[] = [];
rooms: RoomViewModel[] = [];
private subscription: Subscription;
expirationDate = {}
private intervalSubscription: Subscription;
@@ -67,6 +68,11 @@ export class ChatPage implements OnInit {
RoomType = RoomType
boldTable: {[key: string]: BoldTable} = {}
private roomListSubject = new BehaviorSubject<{ id: string, name: string }[]>([]);
roomsWithLastMessages: { name: string, lastMessage: any }[] = [];
private subscription1: Subscription;
RoomSelected!: RoomViewModel;
constructor(
private modalController: ModalController,
@@ -77,7 +83,8 @@ export class ChatPage implements OnInit {
public RouteService: RouteService,
private ChatServiceService: ChatServiceService,
private roomLocalDataSourceService: RoomLocalRepository,
private boldLocalRepository: BoldLocalRepository
private boldLocalRepository: BoldLocalRepository,
private MessageLocalDataSourceService: MessageLocalDataSourceService
) {
window.onresize = (event) => {
@@ -100,21 +107,62 @@ export class ChatPage implements OnInit {
}
// Method to update the room list
// updateRoomList(newRoomList: { id: string, name: string }[]): void {
// this.roomListSubject.next(newRoomList);
// }
// Fetch all items using useLiveQuery
ngOnInit() {
this.items$ = this.roomLocalDataSourceService.getItemsLive().pipe(
updatemessage(sortedRooms) {
this.rooms = sortedRooms
this.rooms.sort((a, b) =>
new Date(b.messages?.[0]?.sentAt as string).getTime() -
new Date(a.messages?.[0]?.sentAt as string).getTime()
);
this.RoomSelected = this.rooms.filter(e => e.id == this.idSelected)[0]
}
ngOnInit() {
// this.subscription = this.roomListSubject.pipe(
// switchMap(roomList =>
// this.MessageLocalDataSourceService.getLastMessageForRooms(roomList.map(room => room.id))
// )
// ).subscribe(lastMessages => {
// this.roomsWithLastMessages = this.roomListSubject.value.map(room => ({
// name: room.name,
// lastMessage: lastMessages.find(msg => msg.roomId === room.id)?.message || null
// }));
// this.roomsWithLastMessages.sort((a, b) =>
// new Date(b.lastMessage.messages?.[0]?.sentAt as unknown as string) as unknown as number -
// (new Date(a.lastMessage.messages?.[0]?.sentAt as unknown as string) as any) as unknown as number
// )
// });
// // Initialize room list (can be loaded from a service, API, etc.)
// this.roomListSubject.next([
// { id: '1135e73c-af8e-416c-a51f-1602b4770cf7', name: 'Room 1' }
// // Add more rooms as needed
// ]);
this.roomLocalDataSourceService.getItemsLive().pipe(
map((roomList) => roomList.map((room)=> new RoomViewModel(room))),
tap((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
)
})
roomList.sort((a, b) =>
new Date(b.messages?.[0]?.sentAt as string).getTime() -
new Date(a.messages?.[0]?.sentAt as string).getTime()
);
console.log('update')
this.updatemessage(roomList)
})
).subscribe()
// Create the interval observable
const interval$ = interval(1000).pipe(
tap(() => {
@@ -286,9 +334,10 @@ export class ChatPage implements OnInit {
this.idSelected = '';
this.showEmptyComponent = true;
}
openGroupContactsPage(data) {
openGroupContactsPage(roomId) {
this.idSelected = '';
this.groupRoomId = data;
this.groupRoomId = roomId;
this.RoomSelected = this.rooms.filter(e => e.id == roomId)[0]
this.closeAllDesktopComponents();
if (window.innerWidth < 701) {
@@ -299,15 +348,16 @@ export class ChatPage implements OnInit {
}
openMessagesPage(rid) {
openMessagesPage(roomId) {
// this.chatService.refreshtoken();
this.roomId = rid;
this.roomId = roomId;
this.RoomSelected = this.rooms.filter(e => e.id == roomId)[0]
if (window.innerWidth < 701) {
this.openMessagesModal(rid);
this.openMessagesModal(roomId);
}
else {
this.idSelected = rid;
this.idSelected = roomId;
this.closeAllDesktopComponents();
this.showEmptyComponent = false;
this.showMessages = true;
@@ -351,23 +401,6 @@ export class ChatPage implements OnInit {
}
}
openGroupMessagesPage(rid) {
this.roomId = rid;
if (window.innerWidth < 701) {
this.openGroupMessagesModal(rid);
}
else {
this.idSelected = rid;
this.closeAllDesktopComponents();
this.showEmptyComponent = false;
this.showMessages = true;
}
}
doRefresh(event) {
setTimeout(() => {
try {
@@ -1,17 +0,0 @@
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { AddUserPage } from './add-user.page';
const routes: Routes = [
{
path: '',
component: AddUserPage
}
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class AddUserPageRoutingModule {}
@@ -1,20 +0,0 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { IonicModule } from '@ionic/angular';
import { AddUserPageRoutingModule } from './add-user-routing.module';
import { AddUserPage } from './add-user.page';
@NgModule({
imports: [
CommonModule,
FormsModule,
IonicModule,
AddUserPageRoutingModule
],
declarations: [AddUserPage]
})
export class AddUserPageModule {}
@@ -1,9 +0,0 @@
<ion-header>
<ion-toolbar>
<ion-title>addUser</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
</ion-content>
@@ -1,24 +0,0 @@
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { IonicModule } from '@ionic/angular';
import { AddUserPage } from './add-user.page';
describe('AddUserPage', () => {
let component: AddUserPage;
let fixture: ComponentFixture<AddUserPage>;
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [ AddUserPage ],
imports: [IonicModule.forRoot()]
}).compileComponents();
fixture = TestBed.createComponent(AddUserPage);
component = fixture.componentInstance;
fixture.detectChanges();
}));
it('should create', () => {
expect(component).toBeTruthy();
});
});
@@ -1,15 +0,0 @@
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-add-user',
templateUrl: './add-user.page.html',
styleUrls: ['./add-user.page.scss'],
})
export class AddUserPage implements OnInit {
constructor() { }
ngOnInit() {
}
}
@@ -3,12 +3,12 @@
<div class="main-header">
<div class="header-top">
<div class="middle" >
<ion-label class="title" *ngIf="roomData$ | async as roomData"> {{ roomData.roomName }}</ion-label>
<ion-label class="title" > {{ room.roomName }}</ion-label>
<!-- <button (click)="ChatMessageDebuggingPage()">Dev</button> -->
<span *ngIf="roomStatus$ | async as roomStatus"><ion-icon *ngIf="roomStatus" class="online" name="ellipse"></ion-icon></span>
</div>
<div class="right">
<button title="Menu" class="btn-no-color" (click)="_openMessagesOptions()" *ngIf="roomType == RoomTypeEnum.Group">
<button title="Menu" class="btn-no-color" (click)="_openMessagesOptions()" *ngIf="room.roomType == RoomTypeEnum.Group">
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " src="assets/images/theme/blue/icons-menu.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " src="assets/images/theme/gov/icons-menu.svg">
</ion-icon>
@@ -41,7 +41,7 @@ import { UserTypingRemoteRepositoryService } from 'src/app/module/chat/data/repo
import { MessageLocalDataSourceService } from 'src/app/module/chat/data/repository/message/message-local-data-source.service';
import { RoomType } from "src/app/core/chat/entity/group";
import { Logger } from 'src/app/services/logger/main/service';
import { tap } from 'rxjs/operators';
import { map, tap } from 'rxjs/operators';
import { AlertController } from '@ionic/angular';
import { ViewOncesImagePage, ViewOncesImagePageInput } from '../../modal/view-onces/view-onces.page';
import { MemberTable } from 'src/app/infra/database/dexie/instance/chat/schema/members';
@@ -50,6 +50,8 @@ import { RoomTable } from 'src/app/infra/database/dexie/instance/chat/schema/roo
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';
@Component({
selector: 'app-messages',
templateUrl: './messages.page.html',
@@ -112,7 +114,7 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
@ViewChild('array') myInputRef!: ElementRef;
userName = "";
room: any = new Array();
@Input() room!: RoomViewModel;
roomName: any;
isAdmin = true;
roomCountDownDate: string;
@@ -120,7 +122,7 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
textField = ''
roomData$: DexieObservable<RoomTable | undefined>
roomData$: Observable<RoomTable | undefined>
roomStatus$: DexieObservable<Boolean >
roomMessage$: DexieObservable<MessageTable[]>
roomMembers$: Observable<MemberTable[] | undefined>
@@ -135,6 +137,7 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
messages: MessageEntity[] = []
RoomDataSubject: Subscription
messageReceiveSubject: Subscription
messageDeleteSubject: Subscription
messageUpdateSubject: Subscription
@@ -179,7 +182,7 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
private UserTypingRemoteRepositoryService: UserTypingRemoteRepositoryService,
private messageLocalDataSourceService: MessageLocalDataSourceService,
private alertController: AlertController,
private http: HttpClient
private http: HttpClient,
) {
// update
this.checkAudioPermission()
@@ -226,17 +229,6 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
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();
this.listenToIncomingMessage();
this.listenToDeleteMessage();
@@ -276,6 +268,15 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
this.chatServiceService.removeBoldFromRoom({roomId: this.roomId})
// this.RoomDataSubject?.unsubscribe()
// this.RoomDataSubject = this.RoomLocalRepository.getRoomByIdLive(this.roomId).pipe(
// map((roomData) => new RoomViewModel(roomData)),
// tap((room: RoomViewModel) => {
// this.room = room
// })
// ).subscribe()
}
messageStatus(message: MessageEntity) {
@@ -469,7 +470,6 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
this.messageSendSubject = this.chatServiceService.listenToSendMessage(this.roomId).subscribe((updateMessage) => {
console.log({updateMessage},'=--=-=-=--=', this.messages1[this.roomId])
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
@@ -733,7 +733,7 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
safeFile: this.sanitiser.bypassSecurityTrustResourceUrl(this.audioRecordedDataUrl)
}]
this.chatServiceService.sendMessage(message, this.roomType)
this.chatServiceService.sendMessage(message, this.room.roomType)
this.messages1[this.roomId].push(message)
setTimeout(() => {
this.scrollToBottomClicked()
@@ -794,7 +794,7 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
setTimeout(() => {
this.scrollToBottomClicked()
}, 100)
const data = await this.chatServiceService.sendMessage(message, this.roomType)
const data = await this.chatServiceService.sendMessage(message, this.room.roomType)
}
@@ -898,7 +898,7 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
roomId: this.roomId,
members: [],
isAdmin: this.isAdmin,
roomType: this.roomType
roomType: this.room.roomType
}
});
await modal.present();
@@ -980,7 +980,7 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
setTimeout(() => {
this.scrollToBottomClicked()
}, 100)
this.chatServiceService.sendMessage(message, this.roomType)
this.chatServiceService.sendMessage(message, this.room.roomType)
}
@@ -1036,7 +1036,7 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
setTimeout(() => {
this.scrollToBottomClicked()
}, 100)
this.chatServiceService.sendMessage(message, this.roomType)
this.chatServiceService.sendMessage(message, this.room.roomType)
this.textField = ''
}
@@ -1126,7 +1126,7 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
setTimeout(() => {
this.scrollToBottomClicked()
}, 100)
this.chatServiceService.sendMessage(message, this.roomType)
this.chatServiceService.sendMessage(message, this.room.roomType)
}
}
@@ -1182,7 +1182,7 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
setTimeout(() => {
this.scrollToBottomClicked()
}, 100)
this.chatServiceService.sendMessage(message, this.roomType)
this.chatServiceService.sendMessage(message, this.room.roomType)
}
} else {
@@ -131,9 +131,8 @@ export class NewGroupPage implements OnInit{
members: []
})
console.log(result)
if(result.isOk()) {
await this.ChatServiceService.getRoomById(result.value.id)
this.addGroupMessage.emit(result.value.id);
} else if(result.error instanceof HttpErrorResponse) {
this.httpErrorHandle.httpStatusHandle(result.error)
@@ -20,7 +20,7 @@ import { ViewMediaPage } from 'src/app/modals/view-media/view-media.page';
//======
import { Observable as DexieObservable } from 'Dexie';
import { Subscription } from 'rxjs';
import { Observable, Subscription } from 'rxjs';
import { MessageTable } from 'src/app/infra/database/dexie/instance/chat/schema/message';
import { ChatServiceService } from 'src/app/module/chat/domain/chat-service.service';
import { EditMessagePage } from 'src/app/ui/chat/modal/edit-message/edit-message.page';
@@ -109,7 +109,7 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
audioPermissionStatus: 'granted' | 'denied' | 'prompt' | null = null
sessionStore = SessionStore
roomData$: DexieObservable<RoomTable | undefined>
roomData$: Observable<RoomTable | undefined>
roomStatus$: DexieObservable<Boolean >
roomMessage$: DexieObservable<MessageTable[]>
roomMembers$: DexieObservable<MemberTable[] | undefined>
@@ -17,7 +17,7 @@ export class RoomInfoPage implements OnInit {
roomId:string;
roomMembers$: Observable<MemberTable[] | undefined>
roomData$: DexieObservable<RoomTable | undefined>
roomData$: Observable<RoomTable | undefined>
constructor(
private navParams: NavParams,