mirror of
https://code.equilibrium.co.ao/ITO/doneit-web.git
synced 2026-04-19 21:06:06 +00:00
set member to admin
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
import { Result, ok, err, ResultAsync } from 'neverthrow';
|
||||
import { Dexie, EntityTable, liveQuery, Observable } from 'Dexie';
|
||||
|
||||
// Define a type for the Result of repository operations
|
||||
type RepositoryResult<T> = Result<T, Error>;
|
||||
|
||||
export class DexieRepository<ISchema, T> {
|
||||
private table: EntityTable<ISchema, any>;
|
||||
|
||||
constructor(table: EntityTable<any, any>) {
|
||||
this.table = table as any
|
||||
}
|
||||
|
||||
async insert(document: T): Promise<RepositoryResult<number>> {
|
||||
try {
|
||||
const id = await this.table.add(document as any);
|
||||
return ok(id);
|
||||
} catch (error) {
|
||||
return err(new Error('Failed to insert document: ' + error.message));
|
||||
}
|
||||
}
|
||||
|
||||
async insertMany(documents: T[]): Promise<RepositoryResult<number[]>> {
|
||||
try {
|
||||
const ids = await this.table.bulkAdd(documents as any);
|
||||
return ok(ids);
|
||||
} catch (error) {
|
||||
return err(new Error('Failed to insert multiple documents: ' + error.message));
|
||||
}
|
||||
}
|
||||
|
||||
async update(id: any, updatedDocument: Partial<T>) {
|
||||
try {
|
||||
const updatedCount = await this.table.update(id, updatedDocument as any);
|
||||
return ok(updatedCount);
|
||||
} catch (error) {
|
||||
return err(new Error('Failed to update document: ' + error.message));
|
||||
}
|
||||
}
|
||||
|
||||
async delete(id: any): Promise<RepositoryResult<void>> {
|
||||
try {
|
||||
await this.table.delete(id);
|
||||
return ok(undefined);
|
||||
} catch (error) {
|
||||
return err(new Error('Failed to delete document: ' + error.message));
|
||||
}
|
||||
}
|
||||
|
||||
async findById(id: any) {
|
||||
try {
|
||||
const document = await this.table.get(id);
|
||||
return ok(document);
|
||||
} catch (error) {
|
||||
return err(new Error('Failed to find document by ID: ' + error.message));
|
||||
}
|
||||
}
|
||||
|
||||
// async find(filter: any) {
|
||||
// try {
|
||||
// const documents = await this.table.where(filter).toArray();
|
||||
// return ok(documents);
|
||||
// } catch (error) {
|
||||
// return err(new Error('Failed to find documents: ' + error.message));
|
||||
// }
|
||||
// }
|
||||
|
||||
// async findOne(filter: any): Promise<RepositoryResult<T | undefined>> {
|
||||
// try {
|
||||
// const document = await this.table.where(filter).first();
|
||||
// return ok(document);
|
||||
// } catch (error) {
|
||||
// return err(new Error('Failed to find document: ' + error.message));
|
||||
// }
|
||||
// }
|
||||
|
||||
// async findAll(): Promise<RepositoryResult<T[]>> {
|
||||
// try {
|
||||
// const documents = await this.table.toArray();
|
||||
// return ok(documents);
|
||||
// } catch (error) {
|
||||
// return err(new Error('Failed to retrieve all documents: ' + error.message));
|
||||
// }
|
||||
// }
|
||||
|
||||
// async count(filter?: any): Promise<RepositoryResult<number>> {
|
||||
// try {
|
||||
// const count = filter ? await this.table.where(filter).count() : await this.table.count();
|
||||
// return ok(count);
|
||||
// } catch (error) {
|
||||
// return err(new Error('Failed to count documents: ' + error.message));
|
||||
// }
|
||||
// }
|
||||
}
|
||||
@@ -24,9 +24,8 @@
|
||||
</ion-header>
|
||||
|
||||
<ion-content>
|
||||
<div class="main-content">
|
||||
|
||||
<ion-virtual-scroll [items]="members | filter:textSearch: 'name'" approxItemHeight="70px" [headerFn]="separateLetter">
|
||||
<div class="main-content" *ngIf="roomMembers$ | async as memberList">
|
||||
<ion-virtual-scroll [items]="memberList | filter:textSearch: 'wxFullName'" approxItemHeight="70px" [headerFn]="separateLetter">
|
||||
|
||||
<div class="item-divider" *virtualHeader="let header">
|
||||
<ion-label>{{header}}</ion-label>
|
||||
@@ -34,7 +33,7 @@
|
||||
|
||||
<div *virtualItem="let user" class="item-checkbox">
|
||||
<div class="cursor-pointer d-flex width-100" (click)="setRoomOwner(user)" (ionChange)="setRoomOwner(user)">
|
||||
<p class="flex-1">{{user.name}}</p>
|
||||
<p class="flex-1">{{user.wxFullName}}</p>
|
||||
<ion-icon slot="end" class="{{user.status}}" name="ellipse"></ion-icon>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { ModalController, NavParams } from '@ionic/angular';
|
||||
import { ChatSystemService } from 'src/app/services/chat/chat-system.service';
|
||||
import { TableMemberList } from 'src/app/module/chat/data/data-source/room/rooom-local-data-source.service';
|
||||
import { RoomRepositoryService } from 'src/app/module/chat/data/repository/room-repository.service';
|
||||
import { ThemeService } from 'src/app/services/theme.service'
|
||||
import { ToastService } from 'src/app/services/toast.service';
|
||||
import { Observable as DexieObservable } from 'Dexie';
|
||||
import { ChatServiceService } from 'src/app/module/chat/domain/chat-service.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-set-room-owner',
|
||||
@@ -15,13 +18,15 @@ export class SetRoomOwnerPage implements OnInit {
|
||||
textSearch:string = "";
|
||||
roomId:any;
|
||||
members:any;
|
||||
roomMembers$: DexieObservable<TableMemberList[] | undefined>
|
||||
|
||||
constructor(
|
||||
private modalController: ModalController,
|
||||
private navParams: NavParams,
|
||||
public ThemeService: ThemeService,
|
||||
private toastService: ToastService,
|
||||
public ChatSystemService: ChatSystemService,
|
||||
private roomRepositoryService: RoomRepositoryService,
|
||||
private chatServiceService: ChatServiceService
|
||||
) {
|
||||
this.roomId = this.navParams.get('roomId');
|
||||
this.members = this.navParams.get('members');
|
||||
@@ -29,23 +34,24 @@ export class SetRoomOwnerPage implements OnInit {
|
||||
|
||||
ngOnInit() {
|
||||
// this.chatService.refreshtoken();
|
||||
this.roomMembers$ = this.roomRepositoryService.getRoomMemberNoneAdminByIdLive(this.roomId) as any
|
||||
}
|
||||
|
||||
async close(){
|
||||
async close() {
|
||||
this.modalController.dismiss();
|
||||
}
|
||||
|
||||
onChange(event){
|
||||
onChange(event) {
|
||||
this.textSearch = event.detail.value;
|
||||
}
|
||||
|
||||
separateLetter(record, recordIndex, records){
|
||||
separateLetter(record:TableMemberList, recordIndex, records:TableMemberList[]) {
|
||||
if(recordIndex == 0){
|
||||
return record.name[0];
|
||||
return record.wxFullName[0];
|
||||
}
|
||||
|
||||
let first_prev = records[recordIndex - 1].name[0];
|
||||
let first_current = record.name[0];
|
||||
let first_prev = records[recordIndex - 1].wxFullName[0];
|
||||
let first_current = record.wxFullName[0];
|
||||
|
||||
if(first_prev != first_current){
|
||||
return first_current;
|
||||
@@ -53,46 +59,20 @@ export class SetRoomOwnerPage implements OnInit {
|
||||
return null;
|
||||
}
|
||||
|
||||
async setRoomOwner(user:any){
|
||||
async setRoomOwner(user:TableMemberList) {
|
||||
|
||||
let res:any;
|
||||
try {
|
||||
res = await this.ChatSystemService.addRoomOwner(this.roomId, user._id)
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
}
|
||||
|
||||
|
||||
if(res.error){
|
||||
if(res.error.error == 'error-user-already-owner'){
|
||||
this.toastService._badRequest('Este utilizador já é administrador');
|
||||
}
|
||||
else{
|
||||
this.toastService._badRequest('Não foi possível completar a ação, por favor tente novamente.');
|
||||
}
|
||||
}
|
||||
else{
|
||||
this.modalController.dismiss('success');
|
||||
}
|
||||
|
||||
/*
|
||||
let body = {
|
||||
"roomId": this.roomId,
|
||||
"userId": user._id
|
||||
}
|
||||
|
||||
this.chatService.addGroupOwner(body).subscribe((res)=>{
|
||||
this.close();
|
||||
this.toastService._successMessage('Operação realizada com sucesso');
|
||||
}, (e) => {
|
||||
if(e.error.errorType == 'error-user-already-owner'){
|
||||
this.toastService._badRequest('Este utilizador já é administrador');
|
||||
}
|
||||
else{
|
||||
this.toastService._badRequest('Não foi possível completar a ação, por favor tente novamente.');
|
||||
}
|
||||
}); */
|
||||
const result = await this.chatServiceService.setAdmin({
|
||||
roomId: user.roomId,
|
||||
memberId: user.wxUserId.toString()
|
||||
});
|
||||
|
||||
if(result.isOk()) {
|
||||
this.roomRepositoryService.getRoomById(this.roomId)
|
||||
// this.modalController.dismiss('success');
|
||||
} else {
|
||||
this.toastService._badRequest('Não foi possível completar a ação, por favor tente novamente.');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -12,8 +12,8 @@ export function roomListDetermineChanges(serverRooms: RoomListItemOutPutDTO[], l
|
||||
room.chatRoom.roomName !== localRoom.roomName ||
|
||||
room.chatRoom.createdBy.wxUserId !== localRoom.createdBy.wxUserId ||
|
||||
room.chatRoom.createdAt !== localRoom.createdAt ||
|
||||
room.chatRoom.expirationDate !== localRoom.expirationDate ||
|
||||
room.chatRoom.roomType !== localRoom.roomType
|
||||
room.chatRoom.expirationDate !== localRoom.expirationDate // ||
|
||||
// room.chatRoom.roomType !== localRoom.roomType
|
||||
);
|
||||
});
|
||||
const roomsToDelete = localRooms.filter(room => !serverRoomMap.has(room.id));
|
||||
|
||||
@@ -18,9 +18,10 @@ export function roomMemberListDetermineChanges(____serverRooms: RoomByIdMemberIt
|
||||
const membersToUpdate = PServerRooms.filter(room => {
|
||||
const localRoom = localRoomMap.get(room.$roomIdUserId);
|
||||
return localRoom && (
|
||||
room.user.wxUserId !== localRoom.user.wxUserId ||
|
||||
room.user.userPhoto !== localRoom.user.userPhoto ||
|
||||
room.joinAt !== localRoom.joinAt
|
||||
room.user.wxUserId !== localRoom.wxUserId ||
|
||||
room.user.userPhoto !== localRoom.userPhoto ||
|
||||
room.joinAt !== localRoom.joinAt,
|
||||
room.isAdmin !== localRoom.isAdmin
|
||||
)
|
||||
});
|
||||
|
||||
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { RoomListItemOutPutDTO, RoomListOutPutDTO } from '../../dto/room/roomListOutputDTO';
|
||||
import { Dexie, EntityTable, liveQuery, Observable } from 'Dexie';
|
||||
import { z } from 'zod';
|
||||
import { DexieRepository } from 'src/app/infra/repository/dexie/dexie-repository.service';
|
||||
|
||||
|
||||
const TableMemberListSchema = z.object({
|
||||
$roomIdUserId: z.string().optional(),
|
||||
id: z.string(),
|
||||
roomId: z.string(),
|
||||
user: z.object({
|
||||
wxUserId: z.number(),
|
||||
wxFullName: z.string(),
|
||||
wxeMail: z.string(),
|
||||
userPhoto: z.string().nullable(),
|
||||
}),
|
||||
joinAt: z.string(),
|
||||
status: z.string()
|
||||
})
|
||||
|
||||
export type ITableMemberList = z.infer<typeof TableMemberListSchema>
|
||||
|
||||
type ITableMemberListSchema = EntityTable<ITableMemberList, '$roomIdUserId'>
|
||||
// Database declaration (move this to its own module also)
|
||||
export const roomMemberList = new Dexie('roomMemberList') as Dexie & {
|
||||
memberList: EntityTable<ITableMemberList, '$roomIdUserId'>;
|
||||
};
|
||||
|
||||
roomMemberList.version(1).stores({
|
||||
memberList: '$roomIdUserId, id, user, joinAt, roomId, status',
|
||||
});
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class MemberListLocalDataSourceService extends DexieRepository<ITableMemberListSchema, ITableMemberList> {
|
||||
|
||||
constructor() {
|
||||
super(roomMemberList.memberList);
|
||||
|
||||
// messageDataSource.message.hook('creating', (primKey, obj, trans) => {
|
||||
// // const newMessage = await trans.table('message').get(primKey);
|
||||
// this.messageSubject.next(obj);
|
||||
// // return newMessage
|
||||
// })
|
||||
|
||||
}
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Result } from 'neverthrow';
|
||||
import { ValidateSchema } from 'src/app/services/decorators/validate-schema.decorator';
|
||||
import { HttpService } from 'src/app/services/http.service';
|
||||
import { DataSourceReturn } from 'src/app/services/Repositorys/type';
|
||||
import { AddMemberToRoomInputDTOSchema, AddMemberToRoomInputDTO } from '../../dto/room/addMemberToRoomInputDto';
|
||||
import { UserRemoveListInputDTOSchema, UserRemoveListInputDTO } from '../../dto/room/userRemoveListInputDTO';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class MemberListRemoteDataSourceService {
|
||||
|
||||
private baseUrl = 'https://gdapi-dev.dyndns.info/stage/api/v2/Chat'; // Your base URL
|
||||
|
||||
constructor(private httpService: HttpService) { }
|
||||
|
||||
|
||||
@ValidateSchema(AddMemberToRoomInputDTOSchema)
|
||||
async addMemberToRoom(data: AddMemberToRoomInputDTO): DataSourceReturn<AddMemberToRoomInputDTO> {
|
||||
return await this.httpService.post<any>(`${this.baseUrl}/Room/${data.id}/Member`, { members:data.members });
|
||||
}
|
||||
|
||||
|
||||
@ValidateSchema(UserRemoveListInputDTOSchema)
|
||||
async removeMemberFromRoom(data: UserRemoveListInputDTO): Promise<Result<any ,any>> {
|
||||
return await this.httpService.delete<any>(`${this.baseUrl}/Room/${data.id}/Member`, {members:data.members});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -8,8 +8,8 @@ import { MessageInputDTO } from '../../dto/message/messageInputDtO';
|
||||
|
||||
|
||||
const tableSchema = z.object({
|
||||
id: z.any().optional(),
|
||||
messageId: z.string().optional(),
|
||||
$id: z.any().optional(),
|
||||
id: z.string().optional(),
|
||||
roomId: z.string().uuid(),
|
||||
message: z.string(),
|
||||
messageType: z.number(),
|
||||
@@ -49,11 +49,11 @@ export type TableMessage = z.infer<typeof tableSchema>
|
||||
|
||||
// Database declaration (move this to its own module also)
|
||||
export const messageDataSource = new Dexie('chat-message') as Dexie & {
|
||||
message: EntityTable<TableMessage, 'id'>;
|
||||
message: EntityTable<TableMessage, '$id'>;
|
||||
};
|
||||
|
||||
messageDataSource.version(1).stores({
|
||||
message: '++id, roomId, message, messageType, canEdit, oneShot, requireUnlock, messageId, info'
|
||||
message: '++$id, id, roomId, message, messageType, canEdit, oneShot, requireUnlock, messageId, info'
|
||||
});
|
||||
|
||||
@Injectable({
|
||||
@@ -88,12 +88,12 @@ export class MessageLocalDataSourceService {
|
||||
}
|
||||
}
|
||||
|
||||
async deleteByMessageId(messageId: string): Promise<Result<undefined|TableMessage, any>> {
|
||||
async deleteByMessageId(id: string): Promise<Result<undefined|TableMessage, any>> {
|
||||
try {
|
||||
console.log(messageId)
|
||||
console.log(id)
|
||||
const lastMessage = await messageDataSource.message
|
||||
.where('messageId')
|
||||
.equals(messageId).delete()
|
||||
.where('id')
|
||||
.equals(id).delete()
|
||||
|
||||
return ok(lastMessage[0]); // Get the last message
|
||||
} catch (error) {
|
||||
@@ -134,14 +134,14 @@ export class MessageLocalDataSourceService {
|
||||
}
|
||||
|
||||
|
||||
async messageExist({messageId}) {
|
||||
async messageExist({id}) {
|
||||
try {
|
||||
|
||||
console.log({messageId});
|
||||
console.log({id});
|
||||
|
||||
const existingMessage = await messageDataSource.message
|
||||
.where('messageId')
|
||||
.equals(messageId)
|
||||
.where('id')
|
||||
.equals(id)
|
||||
.first();
|
||||
|
||||
if (existingMessage) {
|
||||
@@ -159,7 +159,7 @@ export class MessageLocalDataSourceService {
|
||||
async update(data: TableMessage ) {
|
||||
|
||||
try {
|
||||
const result = await messageDataSource.message.update(data.id, data)
|
||||
const result = await messageDataSource.message.update(data.$id, data)
|
||||
return ok(result)
|
||||
} catch (e) {
|
||||
return err(false)
|
||||
@@ -181,7 +181,7 @@ export class MessageLocalDataSourceService {
|
||||
|
||||
|
||||
async findOrUpdate(data: TableMessage) {
|
||||
const findResult = await this.findMessageById(data.messageId)
|
||||
const findResult = await this.findMessageById(data.id)
|
||||
|
||||
if(findResult.isOk()) {
|
||||
return this.update({...findResult.value, ...data})
|
||||
@@ -192,14 +192,14 @@ export class MessageLocalDataSourceService {
|
||||
|
||||
getItemsLive(roomId: string) {
|
||||
return liveQuery(() =>
|
||||
messageDataSource.message.where('roomId').equals(roomId).sortBy('id')
|
||||
messageDataSource.message.where('roomId').equals(roomId).sortBy('$id')
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
async findMessageById(messageId: string) {
|
||||
async findMessageById(id: string) {
|
||||
try {
|
||||
const a = await messageDataSource.message.where('messageId').equals(messageId).first()
|
||||
const a = await messageDataSource.message.where('id').equals(id).first()
|
||||
|
||||
if(a) {
|
||||
return ok(a)
|
||||
|
||||
@@ -14,6 +14,7 @@ import { RoomUpdateInputDTO, RoomUpdateInputDTOSchema } from '../../dto/room/roo
|
||||
import { RoomUpdateOutputDTO } from '../../dto/room/roomUpdateOutputDTO';
|
||||
import { DataSourceReturn } from 'src/app/services/Repositorys/type';
|
||||
import { SessionStore } from 'src/app/store/session.service';
|
||||
import { MemberSetAdminDTO } from '../../../domain/use-case/member-admin-use-case.service';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
@@ -66,4 +67,8 @@ export class RoomRemoteDataSourceService {
|
||||
return await this.httpService.delete<any>(`${this.baseUrl}/Room/${data.id}/Member`, {members:data.members});
|
||||
}
|
||||
|
||||
async setAmin(data: MemberSetAdminDTO): Promise<Result<any ,any>> {
|
||||
return await this.httpService.patch<any>(`${this.baseUrl}/Room/${data.roomId}/Member/${data.memberId}/admin`);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import { Dexie, EntityTable, liveQuery, Observable } from 'Dexie';
|
||||
import { err, ok, Result } from 'neverthrow';
|
||||
import { z } from 'zod';
|
||||
import { ValidateSchema } from 'src/app/services/decorators/validate-schema.decorator';
|
||||
import { MemberListUPdateStatusInputDTO } from '../../../domain/use-case/socket/member-list-update-status-use-case.service';
|
||||
|
||||
const tableSchema = z.object({
|
||||
id: z.string(),
|
||||
@@ -15,29 +16,20 @@ const tableSchema = z.object({
|
||||
userPhoto: z.string().nullable().optional()// api check
|
||||
}),
|
||||
createdAt: z.any(),
|
||||
expirationDate: z.any(),
|
||||
roomType: z.any(),
|
||||
// lastMessage: z.object({
|
||||
// sentAt: z.string(),
|
||||
// message: z.string(),
|
||||
// sender: z.object({
|
||||
// wxUserId: z.any(),
|
||||
// wxFullName: z.any(),
|
||||
// }).optional(),s
|
||||
// })
|
||||
expirationDate: z.any().nullable(),
|
||||
})
|
||||
|
||||
const TableMemberListSchema = z.object({
|
||||
$roomIdUserId: z.string().optional(),
|
||||
id: z.string(),
|
||||
roomId: z.string(),
|
||||
user: z.object({
|
||||
wxUserId: z.number(),
|
||||
wxFullName: z.string(),
|
||||
wxeMail: z.string(),
|
||||
userPhoto: z.string().nullable(),
|
||||
}),
|
||||
joinAt: z.string()
|
||||
wxUserId: z.number(),
|
||||
wxFullName: z.string(),
|
||||
wxeMail: z.string(),
|
||||
userPhoto: z.string().nullable(),
|
||||
joinAt: z.string(),
|
||||
status: z.string(),
|
||||
isAdmin: z.boolean()
|
||||
})
|
||||
|
||||
|
||||
@@ -62,8 +54,8 @@ export const roomDataSource = new Dexie('FriendDatabase') as Dexie & {
|
||||
|
||||
roomDataSource.version(1).stores({
|
||||
room: 'id, createdBy, roomName, roomType, expirationDate, lastMessage',
|
||||
memberList: '$roomIdUserId, id, user, joinAt, roomId',
|
||||
TypingList: '++id, userId, roomId, entryDate'
|
||||
memberList: '$roomIdUserId, userId, id, user, joinAt, roomId, status, wxUserId, isAdmin',
|
||||
TypingList: '++id, userId, roomId, entryDate',
|
||||
});
|
||||
|
||||
@Injectable({
|
||||
@@ -137,7 +129,7 @@ export class RoomLocalDataSourceService {
|
||||
|
||||
async addMember(data: TableMemberList) {
|
||||
try {
|
||||
data.$roomIdUserId = data.roomId + data.user.wxUserId
|
||||
data.$roomIdUserId = data.roomId + data.wxUserId
|
||||
const result = await roomDataSource.memberList.add(data)
|
||||
return ok(result)
|
||||
} catch (e) {
|
||||
@@ -145,6 +137,44 @@ export class RoomLocalDataSourceService {
|
||||
}
|
||||
}
|
||||
|
||||
async updateMemberRole(data: TableMemberList) {
|
||||
try {
|
||||
const result = await roomDataSource.memberList.where({
|
||||
wxUserId:data.wxUserId,
|
||||
roomId: data.roomId,
|
||||
}).modify(data);
|
||||
|
||||
return ok(result)
|
||||
} catch (e) {
|
||||
return err(false)
|
||||
}
|
||||
}
|
||||
|
||||
async updateMembersStatus(data: MemberListUPdateStatusInputDTO) {
|
||||
try {
|
||||
await roomDataSource.memberList.toCollection().modify({ status: 'offline' });
|
||||
for (const item of data) {
|
||||
const wxUserId = item.value.userId; // Extract wxUserId
|
||||
await roomDataSource.memberList.where('wxUserId').equals(wxUserId).modify({ status: 'online' });
|
||||
}
|
||||
return ok(true)
|
||||
} catch (error) {
|
||||
console.error("Error updating user statuses:", error);
|
||||
return err(error)
|
||||
}
|
||||
}
|
||||
|
||||
allMemberOnline(roomId:string) {
|
||||
return liveQuery(async () => {
|
||||
|
||||
const allMessages = await roomDataSource.memberList
|
||||
.where('roomId')
|
||||
.equals(roomId)
|
||||
.toArray();
|
||||
|
||||
return allMessages.every(message => message?.status === "online");
|
||||
});
|
||||
}
|
||||
|
||||
async removeMemberFromRoom($roomIdUserId): Promise<Result<any ,any>> {
|
||||
try {
|
||||
@@ -193,10 +223,17 @@ export class RoomLocalDataSourceService {
|
||||
}
|
||||
|
||||
async getRoomMemberById(roomId: any) {
|
||||
return await roomDataSource.memberList.where('roomId').equals(roomId).toArray()
|
||||
return await roomDataSource.memberList.where({roomId}).toArray()
|
||||
}
|
||||
getRoomMemberByIdLive(roomId: any) {
|
||||
return liveQuery(() => roomDataSource.memberList.where('roomId').equals(roomId).toArray())
|
||||
return liveQuery(() => roomDataSource.memberList.where({roomId}).toArray())
|
||||
}
|
||||
|
||||
getRoomMemberNoneAdminByIdLive(roomId: any) {
|
||||
return liveQuery(async() => {
|
||||
const members = await roomDataSource.memberList.where({roomId}).toArray()
|
||||
return members.filter(e => e.isAdmin != true)
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ export const RoomInputDTOSchema = z.object({
|
||||
roomName: z.string(),
|
||||
createdBy: z.number(),
|
||||
roomType: z.number(),
|
||||
expirationDate: z.string().datetime().nullable(),
|
||||
expirationDate: z.string().nullable().optional(),
|
||||
members: z.array(z.number())
|
||||
});
|
||||
|
||||
|
||||
@@ -59,8 +59,8 @@ export class MessageRepositoryService {
|
||||
|
||||
let clone: TableMessage = {
|
||||
...sendMessageResult.value,
|
||||
messageId: sendMessageResult.value.id,
|
||||
id : localActionResult.value
|
||||
id: sendMessageResult.value.id,
|
||||
$id : localActionResult.value
|
||||
}
|
||||
|
||||
// console.log({clone})
|
||||
@@ -89,7 +89,7 @@ export class MessageRepositoryService {
|
||||
if(result.isOk()) {
|
||||
if(result.value) {
|
||||
|
||||
return await this.messageLiveSignalRDataSourceService.sendReadAt({roomId, memberId: SessionStore.user.UserId, chatMessageId: result.value.messageId})
|
||||
return await this.messageLiveSignalRDataSourceService.sendReadAt({roomId, memberId: SessionStore.user.UserId, chatMessageId: result.value.id})
|
||||
}
|
||||
return ok(true)
|
||||
}
|
||||
@@ -117,10 +117,7 @@ export class MessageRepositoryService {
|
||||
|
||||
for(const message of result.value.data) {
|
||||
let clone: TableMessage = message
|
||||
clone.messageId = message.id
|
||||
clone.roomId = id
|
||||
delete clone.id
|
||||
|
||||
await this.messageLocalDataSourceService.findOrUpdate(clone)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,9 @@ import { SessionStore } from 'src/app/store/session.service';
|
||||
import { RoomLiveDataSourceService } from '../data-source/room/room-live-data-source.service';
|
||||
import { isHttpResponse } from 'src/app/services/http.service';
|
||||
import { MessageLiveDataSourceService } from '../data-source/message/message-live-data-source.service';
|
||||
import { MemberListUPdateStatusInputDTO } from '../../domain/use-case/socket/member-list-update-status-use-case.service';
|
||||
import { MemberSetAdminDTO } from '../../domain/use-case/member-admin-use-case.service';
|
||||
import { MemberListMapper } from '../../domain/mapper/memberLIstMapper';
|
||||
|
||||
|
||||
function date(isoDateString) {
|
||||
@@ -54,46 +57,36 @@ export class RoomRepositoryService {
|
||||
const { roomsToDelete, roomsToInsert, roomsToUpdate } = roomListDetermineChanges(result.value.data, localList)
|
||||
|
||||
for( const roomData of roomsToInsert) {
|
||||
|
||||
// roomData["lastMessage"] = {
|
||||
// sentAt: date(roomData.createdAt),
|
||||
// message: "",
|
||||
// sender: {
|
||||
// wxUserId: "",
|
||||
// wxFullName: "",
|
||||
// },
|
||||
// }
|
||||
|
||||
this.roomLocalDataSourceService.createRoom(roomData.chatRoom)
|
||||
}
|
||||
|
||||
for( const roomData of roomsToUpdate) {
|
||||
|
||||
// roomData["lastMessage"] = {
|
||||
// sentAt: date(roomData.createdAt),
|
||||
// message: "",
|
||||
// sender: {
|
||||
// wxUserId: "",
|
||||
// wxFullName: "",
|
||||
// },
|
||||
// }
|
||||
|
||||
this.roomLocalDataSourceService.updateRoom(roomData.chatRoom)
|
||||
}
|
||||
|
||||
for( const roomData of roomsToDelete) {
|
||||
|
||||
// roomData["lastMessage"] = {
|
||||
// sentAt: date(roomData.createdAt),
|
||||
// message: "",
|
||||
// sender: {
|
||||
// wxUserId: 0,
|
||||
// wxFullName: "",
|
||||
// },
|
||||
// }
|
||||
|
||||
this.roomLocalDataSourceService.deleteRoomById(roomData.id)
|
||||
}
|
||||
|
||||
try {
|
||||
const rooms = roomsToInsert.concat(roomsToUpdate)
|
||||
|
||||
for(const room of rooms) {
|
||||
const expirationDate = new Date(room.chatRoom.expirationDate);
|
||||
const now = new Date();
|
||||
if (room.chatRoom.expirationDate != null && expirationDate.getTime() >= now.getTime()) {
|
||||
const timeRemaining = expirationDate.getTime() - now.getTime();
|
||||
setTimeout(() => {
|
||||
this.list()
|
||||
}, timeRemaining)
|
||||
}
|
||||
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
return result
|
||||
}
|
||||
@@ -142,20 +135,17 @@ export class RoomRepositoryService {
|
||||
const { membersToInsert, membersToUpdate, membersToDelete } = roomMemberListDetermineChanges(result.value.data.members, localList, id)
|
||||
|
||||
for (const user of membersToInsert) {
|
||||
await this.roomLocalDataSourceService.addMember({...user, roomId:id})
|
||||
await this.roomLocalDataSourceService.addMember(MemberListMapper(user, id))
|
||||
}
|
||||
|
||||
for (const user of membersToUpdate) {
|
||||
await this.roomLocalDataSourceService.updateMemberRole(MemberListMapper(user, id))
|
||||
}
|
||||
|
||||
for(const user of membersToDelete) {
|
||||
await this.roomLocalDataSourceService.removeMemberFromRoom(user.$roomIdUserId)
|
||||
}
|
||||
|
||||
const __localListRoom = await this.roomLocalDataSourceService.getRoomList()
|
||||
|
||||
// this.roomLiveDataSourceService.getRoomById({
|
||||
// type:'memberList',
|
||||
// payload: __localListRoom
|
||||
// })
|
||||
|
||||
} else if (isHttpResponse(result.error) ) {
|
||||
if(result.error.status == 404) {
|
||||
await this.roomLocalDataSourceService.deleteRoomById(id)
|
||||
@@ -238,6 +228,12 @@ export class RoomRepositoryService {
|
||||
return result
|
||||
}
|
||||
|
||||
async updateMemberStatus(data: MemberListUPdateStatusInputDTO) {
|
||||
const result = await this.roomLocalDataSourceService.updateMembersStatus(data)
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
|
||||
@captureAndReraiseAsync('RoomRepositoryService/removeMemberToRoom')
|
||||
async removeMemberToRoom(data: UserRemoveListInputDTO) {
|
||||
@@ -246,6 +242,11 @@ export class RoomRepositoryService {
|
||||
return result
|
||||
}
|
||||
|
||||
setAdmin(input: MemberSetAdminDTO) {
|
||||
return this.roomRemoteDataSourceService.setAmin(input);
|
||||
}
|
||||
|
||||
|
||||
|
||||
async leaveRoom(data: UserRemoveListInputDTO) {
|
||||
const result = await this.roomRemoteDataSourceService.removeMemberFromRoom(data)
|
||||
@@ -280,4 +281,13 @@ export class RoomRepositoryService {
|
||||
return this.roomLocalDataSourceService.getRoomMemberById(roomId)
|
||||
}
|
||||
|
||||
|
||||
getRoomStatus(roomId:string) {
|
||||
return this.roomLocalDataSourceService.allMemberOnline(roomId);
|
||||
}
|
||||
|
||||
|
||||
getRoomMemberNoneAdminByIdLive(roomId) {
|
||||
return this.roomLocalDataSourceService.getRoomMemberNoneAdminByIdLive(roomId)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,10 +3,12 @@ import { MessageDeleteLiveUseCaseService, MessageDeleteInputDTO } from 'src/app/
|
||||
import { SessionStore } from 'src/app/store/session.service';
|
||||
import { MessageReactionInput, MessageReactionUseCaseService } from 'src/app/module/chat/domain/use-case/message-reaction-use-case.service';
|
||||
import { MessageUpdateInput, MessageUpdateUseCaseService } from 'src/app/module/chat/domain/use-case/message-update-use-case.service';
|
||||
import { MemberAdminUseCaseService, MemberSetAdminDTO } from 'src/app/module/chat/domain/use-case/member-admin-use-case.service';
|
||||
import { SignalRService } from '../infra/socket/signal-r.service';
|
||||
import { SocketMessageDeleteUseCaseService } from 'src/app/module/chat/domain/use-case/socket/socket-message-delete-use-case.service';
|
||||
import { SocketMessageUpdateUseCaseService } from 'src/app/module/chat/domain/use-case/socket/socket-message-update-use-case.service';
|
||||
import { SocketMessageCreateUseCaseService } from 'src/app/module/chat/domain/use-case/socket/socket-message-create-use-case.service';
|
||||
import { MemberListUpdateStatusUseCaseService } from 'src/app/module/chat/domain/use-case/socket/member-list-update-status-use-case.service';
|
||||
import { filter } from 'rxjs/operators';
|
||||
import { InstanceId } from '../data/repository/message-respository.service';
|
||||
|
||||
@@ -22,7 +24,9 @@ export class ChatServiceService {
|
||||
private SocketMessageDeleteUseCaseService: SocketMessageDeleteUseCaseService,
|
||||
private messageLiveSignalRDataSourceService: SignalRService,
|
||||
private SocketMessageUpdateUseCaseService: SocketMessageUpdateUseCaseService,
|
||||
private SocketMessageCreateUseCaseService: SocketMessageCreateUseCaseService
|
||||
private SocketMessageCreateUseCaseService: SocketMessageCreateUseCaseService,
|
||||
private MemberListUpdateStatusUseCaseService: MemberListUpdateStatusUseCaseService,
|
||||
private MemberAdminUseCaseService: MemberAdminUseCaseService
|
||||
) {
|
||||
this.messageLiveSignalRDataSourceService.getMessageDelete()
|
||||
.pipe()
|
||||
@@ -30,7 +34,6 @@ export class ChatServiceService {
|
||||
if(message?.id) {
|
||||
this.SocketMessageDeleteUseCaseService.execute(message)
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
this.messageLiveSignalRDataSourceService.getMessageUpdate().pipe(
|
||||
@@ -38,7 +41,6 @@ export class ChatServiceService {
|
||||
return !message?.requestId?.startsWith(InstanceId)
|
||||
})
|
||||
).subscribe(async (message) => {
|
||||
|
||||
if(message?.id) {
|
||||
this.SocketMessageUpdateUseCaseService.execute(message)
|
||||
}
|
||||
@@ -61,6 +63,18 @@ export class ChatServiceService {
|
||||
|
||||
})
|
||||
|
||||
this.messageLiveSignalRDataSourceService.getData().pipe(
|
||||
filter((message) => {
|
||||
if(message?.method == 'AvailableUsers') {
|
||||
// console.log('exclude my message---')
|
||||
return true
|
||||
}
|
||||
})
|
||||
).subscribe(async (message) => {
|
||||
console.log('123', message)
|
||||
this.MemberListUpdateStatusUseCaseService.execute(message.data as any)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
messageDelete(data: {roomId, messageId}) {
|
||||
@@ -80,5 +94,9 @@ export class ChatServiceService {
|
||||
updateMessage(input: MessageUpdateInput) {
|
||||
return this.MessageUpdateUseCaseService.execute(input);
|
||||
}
|
||||
|
||||
setAdmin(input: MemberSetAdminDTO) {
|
||||
return this.MemberAdminUseCaseService.execute(input)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
import { TableMemberList } from "../../data/data-source/room/rooom-local-data-source.service";
|
||||
import { RoomByIdMemberItemOutputDTO } from "../../data/dto/room/roomByIdOutputDTO";
|
||||
|
||||
export function MemberListMapper(outputDto: RoomByIdMemberItemOutputDTO, roomId: string): TableMemberList {
|
||||
return {
|
||||
roomId: roomId,
|
||||
wxUserId: outputDto.user.wxUserId,
|
||||
wxFullName: outputDto.user.wxFullName,
|
||||
wxeMail: outputDto.user.wxFullName,
|
||||
userPhoto: outputDto.user.userPhoto,
|
||||
joinAt: outputDto.joinAt,
|
||||
isAdmin: outputDto.isAdmin
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { z } from "zod";
|
||||
import { RoomRepositoryService } from '../../data/repository/room-repository.service';
|
||||
import { ValidateSchema } from 'src/app/services/decorators/validate-schema.decorator';
|
||||
|
||||
// Define the schema for the entire response
|
||||
const MemberSetAdminDTOSchema = z.object({
|
||||
roomId: z.string(),
|
||||
memberId: z.string()
|
||||
});
|
||||
|
||||
export type MemberSetAdminDTO = z.infer<typeof MemberSetAdminDTOSchema>
|
||||
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class MemberAdminUseCaseService {
|
||||
|
||||
constructor(
|
||||
public repository: RoomRepositoryService
|
||||
) { }
|
||||
|
||||
@ValidateSchema(MemberSetAdminDTOSchema)
|
||||
execute(input: MemberSetAdminDTO) {
|
||||
|
||||
return this.repository.setAdmin(input)
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,10 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { z } from 'zod';
|
||||
import { MessageRepositoryService } from '../../data/repository/message-respository.service';
|
||||
import { ValidateSchema } from 'src/app/services/decorators/validate-schema.decorator';
|
||||
|
||||
export const MessageDeleteInputDTOSchema = z.object({
|
||||
requestId: z.string(),
|
||||
requestId: z.string().optional(),
|
||||
roomId: z.string(),
|
||||
messageId: z.string(),
|
||||
senderId: z.number(),
|
||||
@@ -19,6 +20,7 @@ export class MessageDeleteLiveUseCaseService {
|
||||
public repository: MessageRepositoryService
|
||||
) { }
|
||||
|
||||
@ValidateSchema(MessageDeleteInputDTOSchema)
|
||||
async execute(data: MessageDeleteInputDTO) {
|
||||
return this.repository.sendMessageDelete(data)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { MessageRepositoryService } from '../../data/repository/message-respository.service';
|
||||
import { object, z } from 'zod';
|
||||
import { ValidateSchema } from 'src/app/services/decorators/validate-schema.decorator';
|
||||
|
||||
|
||||
const MessageReactionInputDTOSchema = z.object({
|
||||
@@ -8,7 +9,7 @@ const MessageReactionInputDTOSchema = z.object({
|
||||
messageId: z.string(),
|
||||
roomId: z.string(),
|
||||
reaction: z.string(),
|
||||
requestId: z.string()
|
||||
requestId: z.string().optional()
|
||||
})
|
||||
|
||||
export type MessageReactionInput = z.infer< typeof MessageReactionInputDTOSchema>
|
||||
@@ -22,6 +23,7 @@ export class MessageReactionUseCaseService {
|
||||
public repository: MessageRepositoryService
|
||||
) { }
|
||||
|
||||
@ValidateSchema(MessageReactionInputDTOSchema)
|
||||
execute(input: MessageReactionInput) {
|
||||
return this.repository.reactToMessage(input)
|
||||
}
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { z } from 'zod';
|
||||
import { MessageRepositoryService } from '../../data/repository/message-respository.service';
|
||||
import { ValidateSchema } from 'src/app/services/decorators/validate-schema.decorator';
|
||||
|
||||
const MessageUpdateInputDTOSchema = z.object({
|
||||
memberId: z.number(),
|
||||
messageId: z.string(),
|
||||
roomId: z.string(),
|
||||
message: z.string(),
|
||||
requestId: z.string()
|
||||
requestId: z.string().optional()
|
||||
})
|
||||
|
||||
export type MessageUpdateInput = z.infer< typeof MessageUpdateInputDTOSchema>
|
||||
@@ -22,8 +23,9 @@ export class MessageUpdateUseCaseService {
|
||||
public repository: MessageRepositoryService
|
||||
) { }
|
||||
|
||||
@ValidateSchema(MessageUpdateInputDTOSchema)
|
||||
execute(input: MessageUpdateInput) {
|
||||
this.repository.updateMessage(input);
|
||||
return this.repository.updateMessage(input);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { z } from 'zod';
|
||||
import { RoomRepositoryService } from 'src/app/module/chat/data/repository/room-repository.service'
|
||||
import { ValidateSchema } from 'src/app/services/decorators/validate-schema.decorator';
|
||||
|
||||
export const MemberListUPdateStatus = z.object({
|
||||
key: z.string(),
|
||||
value: z.object({
|
||||
userId: z.number(),
|
||||
userName: z.string()
|
||||
})
|
||||
}).array();
|
||||
export type MemberListUPdateStatusInputDTO = z.infer<typeof MemberListUPdateStatus>
|
||||
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class MemberListUpdateStatusUseCaseService {
|
||||
|
||||
constructor(
|
||||
private RoomRepositoryService: RoomRepositoryService
|
||||
) { }
|
||||
|
||||
|
||||
@ValidateSchema(MemberListUPdateStatus)
|
||||
execute(input: MemberListUPdateStatusInputDTO) {
|
||||
console.log
|
||||
return this.RoomRepositoryService.updateMemberStatus(input)
|
||||
}
|
||||
}
|
||||
+2
-4
@@ -12,16 +12,14 @@ export class SocketMessageCreateUseCaseService {
|
||||
|
||||
async execute(input: any) {
|
||||
|
||||
const id = input.id + ''
|
||||
delete input.id;
|
||||
|
||||
const incomingMessage = {
|
||||
...input,
|
||||
messageId: id,
|
||||
sending: false,
|
||||
roomId:input.chatRoomId
|
||||
}
|
||||
|
||||
delete input.chatRoomId
|
||||
|
||||
const result = await this.messageLocalDataSourceService.sendMessage(incomingMessage)
|
||||
|
||||
if(result.isOk()) {
|
||||
|
||||
+3
-6
@@ -13,19 +13,16 @@ export class SocketMessageUpdateUseCaseService {
|
||||
|
||||
|
||||
async execute(data: MessageOutPutDataDTO) {
|
||||
const result = await this.messageLocalDataSourceService.messageExist({messageId: data.id})
|
||||
|
||||
|
||||
const id = data.id + ''
|
||||
delete data.id;
|
||||
const result = await this.messageLocalDataSourceService.messageExist({id: data.id})
|
||||
|
||||
const incomingMessage = {
|
||||
...data,
|
||||
messageId: id,
|
||||
sending: false,
|
||||
roomId:data.chatRoomId
|
||||
}
|
||||
|
||||
// delete data.chatRoomId
|
||||
|
||||
if(result.isOk()) {
|
||||
console.log('message exist')
|
||||
return this.messageLocalDataSourceService.update({...result.value, ...incomingMessage})
|
||||
|
||||
@@ -31,7 +31,7 @@ export class SignalRService {
|
||||
private connectingSubject: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(null);
|
||||
private messageDelete: BehaviorSubject<MessageOutPutDataDTO> = new BehaviorSubject<MessageOutPutDataDTO>(null);
|
||||
private messageUpdateSubject: BehaviorSubject<MessageOutPutDataDTO> = new BehaviorSubject<MessageOutPutDataDTO>(null);
|
||||
private sendDataSubject: BehaviorSubject<Object> = new BehaviorSubject<Object>(false);
|
||||
private sendDataSubject: BehaviorSubject<{method: string, data: any}> = new BehaviorSubject<{method: string, data: any}>(null);
|
||||
|
||||
private deadConnectionBackGround: Subject<any>;
|
||||
|
||||
@@ -129,7 +129,7 @@ export class SignalRService {
|
||||
}
|
||||
|
||||
getData() {
|
||||
return this.getData()
|
||||
return this.sendDataSubject.asObservable()
|
||||
}
|
||||
|
||||
async sendMessage(data: Object) {
|
||||
|
||||
@@ -24,7 +24,7 @@ export class SignalRConnection {
|
||||
private sendLaterSubject: BehaviorSubject<Object> = new BehaviorSubject<Object>(false);
|
||||
private reconnect = true
|
||||
|
||||
private sendDataSubject: BehaviorSubject<Object> = new BehaviorSubject<Object>(false);
|
||||
private sendDataSubject: BehaviorSubject<{method: string, data: any}> = new BehaviorSubject<{method: string, data: any}>(null);
|
||||
|
||||
url: string
|
||||
|
||||
@@ -264,6 +264,15 @@ export class SignalRConnection {
|
||||
})
|
||||
});
|
||||
|
||||
this.hubConnection.on('AvailableUsers', (data: any) => {
|
||||
console.log('AvailableUsers', data)
|
||||
this.typingSubject.next(data);
|
||||
this.sendDataSubject.next({
|
||||
method: 'AvailableUsers',
|
||||
data: data
|
||||
})
|
||||
});
|
||||
|
||||
this.hubConnection.on('ReadAt', (_message) => {
|
||||
console.log('ReadAt', _message)
|
||||
this.readAtSubject.next(_message);
|
||||
|
||||
@@ -19,7 +19,7 @@ export function ValidateSchema(schema: Schema) {
|
||||
if (e instanceof ZodError) {
|
||||
// If validation fails, throw an error with the details
|
||||
//
|
||||
ColoredLoggerService.error(e.errors, 'socket unexpected data structure '+ schema._def.description)
|
||||
ColoredLoggerService.error(e.errors, 'unexpected data structure '+ schema._def.description)
|
||||
|
||||
}
|
||||
return err(e)
|
||||
|
||||
@@ -39,6 +39,17 @@ export class HttpService {
|
||||
|
||||
}
|
||||
|
||||
async patch<T>(url: string, body: any = {}): Promise<Result<T, HttpErrorResponse>> {
|
||||
|
||||
try {
|
||||
const result = await this.http.patch<T>(url, body).toPromise()
|
||||
return ok (result as T)
|
||||
} catch (e) {
|
||||
return err(e as HttpErrorResponse)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
async delete<T>(url: string, body = {}): Promise<Result<T, HttpErrorResponse>> {
|
||||
|
||||
const options = {
|
||||
|
||||
@@ -19,7 +19,7 @@ class SocketLog {
|
||||
this.messageSubject$ = new Subject<WebSocketMessage>();
|
||||
this.connectionStatus$ = new BehaviorSubject<boolean>(false);
|
||||
this.setupVisibilityChangeHandler();
|
||||
// this.connect('https://5-180-182-151.cloud-xip.com:85/ws/')
|
||||
// this.connect('https://185-229-224-75.cloud-xip.com:85/ws/')
|
||||
//console.log('connect1')
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ export class OpenTelemetryLogging {
|
||||
socket = new WebSocketGraylogService()
|
||||
|
||||
constructor() {
|
||||
|
||||
if(environment.apiURL != 'https://gdqas-api.oapr.gov.ao/api/') {
|
||||
this.socket.start()
|
||||
}
|
||||
|
||||
@@ -12,7 +12,10 @@ metrics.setGlobalMeterProvider(meterProvider);
|
||||
if (window.location.protocol !== 'https:' && environment.apiURL != 'https://gdqas-api.oapr.gov.ao/api/') {
|
||||
const metricReader = new PeriodicExportingMetricReader({
|
||||
exporter: new OTLPMetricExporter({
|
||||
url: 'https://5-180-182-151.cloud-xip.com:85/collector2/v1/metrics',
|
||||
//url: 'https://5-180-182-151.cloud-xip.com:85/collector2/v1/metrics',
|
||||
url: 'https://185-229-224-75.cloud-xip.com:85/collector2/v1/metrics',
|
||||
//url: 'http://5-180-182-151.cloud-xip.com:4318/v1/metrics',
|
||||
//url: 'http://185-229-224-75.cloud-xip.com:4318/v1/metrics'
|
||||
// headers: {
|
||||
// 'Authorization': 'Basic ' + btoa('tabteste@006:tabteste@006'),
|
||||
// }
|
||||
|
||||
@@ -3,8 +3,11 @@ import { WebTracerProvider } from '@opentelemetry/sdk-trace-web';
|
||||
import { ZipkinExporter } from '@opentelemetry/exporter-zipkin';
|
||||
import { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions'
|
||||
import { Resource } from '@opentelemetry/resources';
|
||||
import { OTLPTraceExporter } from '@opentelemetry/exporter-otlp-http';
|
||||
//import { OTLPTraceExporter } from '@opentelemetry/exporter-otlp-http';
|
||||
import { context, trace, propagation } from '@opentelemetry/api';
|
||||
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
|
||||
// const { OTLPTraceExporter: OTLPTraceExporterProto } = require("@opentelemetry/exporter-trace-otlp-proto");
|
||||
|
||||
|
||||
function createProvider(serviceName) {
|
||||
const provider = new WebTracerProvider({
|
||||
@@ -14,14 +17,19 @@ function createProvider(serviceName) {
|
||||
});
|
||||
|
||||
// provider.addSpanProcessor(new SimpleSpanProcessor(new ConsoleSpanExporter()));
|
||||
provider.addSpanProcessor(new SimpleSpanProcessor(new ZipkinExporter({
|
||||
url: 'https://5-180-182-151.cloud-xip.com:85/zipkin-endpoint/api/v2/spans',
|
||||
serviceName: serviceName,
|
||||
getExportRequestHeaders: () => {
|
||||
return {
|
||||
'Authorization': 'Basic ' + btoa('tabteste@006:tabteste@006'),
|
||||
};
|
||||
}
|
||||
// provider.addSpanProcessor(new SimpleSpanProcessor(new ZipkinExporter({
|
||||
// //url: 'https://5-180-182-151.cloud-xip.com:85/zipkin-endpoint/api/v2/spans',
|
||||
// url: 'https://185-229-224-75.cloud-xip.com:85/zipkin-endpoint/api/v2/spans',
|
||||
// serviceName: serviceName,
|
||||
// getExportRequestHeaders: () => {
|
||||
// return {
|
||||
// 'Authorization': 'Basic ' + btoa('tabteste@006:tabteste@006'),
|
||||
// };
|
||||
// }
|
||||
// })));
|
||||
|
||||
provider.addSpanProcessor(new SimpleSpanProcessor(new OTLPTraceExporter({
|
||||
url: 'https://185-229-224-75.cloud-xip.com:85/collector2/v1/traces',
|
||||
})));
|
||||
|
||||
provider.register();
|
||||
@@ -34,6 +42,8 @@ export const OpentelemetryAgendaProvider = createProvider('FO-agenda-service');
|
||||
export const OpentelemetryNotificationProvider = createProvider('FO-notification');
|
||||
export const OpentelemetryInterceptorProvider = createProvider('FO-interceptor');
|
||||
export const OpentelemetryPublicationProvider = createProvider('FO-publication-service');
|
||||
export const OpentelemetryOtherProvider = createProvider('FO-other-service');
|
||||
|
||||
export const OpentelemetryLogging = createProvider('logging');
|
||||
|
||||
const tracerInstance = OpentelemetryAgendaProvider.getTracer('example-tracer-hole', '111', {})
|
||||
|
||||
@@ -31,7 +31,7 @@ function convertAttributesToString(obj) {
|
||||
result[key] = JSON.stringify(obj[key], null, 2);
|
||||
} else {
|
||||
// Convert primitive values to string
|
||||
result[key] = String(obj[key]);
|
||||
result[key] = obj[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -52,11 +52,13 @@ const createTracingInstance = ({bugPrint, name, module, autoFinish}): TracingTyp
|
||||
}
|
||||
|
||||
const span = _tracerInstance.startSpan(name);
|
||||
let finish = false
|
||||
|
||||
const data = {
|
||||
event: {},
|
||||
tags: {},
|
||||
status: {} as any,
|
||||
logs:[]
|
||||
}
|
||||
|
||||
const returnObject = {
|
||||
@@ -83,14 +85,23 @@ const createTracingInstance = ({bugPrint, name, module, autoFinish}): TracingTyp
|
||||
|
||||
if(key =='outcome' && value == 'failed') {
|
||||
returnObject.hasError('error')
|
||||
if(!autoFinish) {
|
||||
returnObject.finish()
|
||||
}
|
||||
} else if (key =='outcome' && value == 'success') {
|
||||
span.setStatus({code: SpanStatusCode.OK, message:name})
|
||||
if(!autoFinish) {
|
||||
returnObject.finish()
|
||||
}
|
||||
}
|
||||
},
|
||||
log(message: string, data: Object) {
|
||||
log(message: string, dataObject: Object) {
|
||||
const spanId = span.spanContext().spanId;
|
||||
const _tracer = OpentelemetryLogging.getTracer('logging')
|
||||
const spanContext = _tracer.startSpan(name)
|
||||
|
||||
data = convertAttributesToString(data)
|
||||
dataObject = convertAttributesToString(dataObject)
|
||||
|
||||
if(environment.apiURL != 'https://gdqas-api.oapr.gov.ao/api/') {
|
||||
openTelemetryLogging.send({
|
||||
type: 'graylog',
|
||||
@@ -98,7 +109,7 @@ const createTracingInstance = ({bugPrint, name, module, autoFinish}): TracingTyp
|
||||
payload: {
|
||||
message: message,
|
||||
object: {
|
||||
...data,
|
||||
...dataObject,
|
||||
spanId,
|
||||
name,
|
||||
user: SessionStore?.user?.FullName,
|
||||
@@ -107,14 +118,17 @@ const createTracingInstance = ({bugPrint, name, module, autoFinish}): TracingTyp
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
data.logs.push(dataObject)
|
||||
|
||||
},
|
||||
getAttribute: (key: string) => {
|
||||
return data.tags[key]
|
||||
},
|
||||
finish: () => {
|
||||
if(finish) return
|
||||
|
||||
if(environment.apiURL != 'https://gdqas-api.oapr.gov.ao/api/') {
|
||||
span.end();
|
||||
UseCaseCounter.add(1, {user: SessionStore?.user?.FullName, outcome:data.tags['outcome'] || data.status?.code , usecase: name})
|
||||
@@ -123,6 +137,8 @@ const createTracingInstance = ({bugPrint, name, module, autoFinish}): TracingTyp
|
||||
if(bugPrint && (data.tags['outcome'] == 'failed' || data.status?.code == SpanStatusCode.ERROR)) {
|
||||
console.error(name, data)
|
||||
}
|
||||
|
||||
finish = true
|
||||
},
|
||||
hasError:(message: string) => {
|
||||
if(data.status?.code != SpanStatusCode.ERROR) {
|
||||
|
||||
@@ -12,7 +12,8 @@ export class WebSocketGraylogService {
|
||||
constructor() { }
|
||||
|
||||
connect(): void {
|
||||
this.adminSocketGlobal = new WebSocket('wss://5-180-182-151.cloud-xip.com:85/ws/');
|
||||
// this.adminSocketGlobal = new WebSocket('wss://5-180-182-151.cloud-xip.com:85/ws/');
|
||||
this.adminSocketGlobal = new WebSocket('wss://185-229-224-75.cloud-xip.com:85/ws/');
|
||||
|
||||
this.adminSocketGlobal.onopen = () => {
|
||||
console.log('Admin WebSocket is open now.');
|
||||
|
||||
@@ -101,10 +101,10 @@ export class GroupContactsPage implements OnInit {
|
||||
console.log({currentMemberToMap})
|
||||
|
||||
this.currentMembers = currentMemberToMap.map((e)=> ({
|
||||
userPhoto: e.user.userPhoto,
|
||||
wxeMail: e.user.wxeMail,
|
||||
wxFullName: e.user.wxFullName,
|
||||
wxUserId: e.user.wxUserId
|
||||
userPhoto: e.userPhoto,
|
||||
wxeMail: e.wxeMail,
|
||||
wxFullName: e.wxFullName,
|
||||
wxUserId: e.wxUserId
|
||||
}))
|
||||
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<div class="middle" >
|
||||
<ion-label class="title"> {{ roomData.roomName }}</ion-label>
|
||||
<!-- <button (click)="ChatMessageDebuggingPage()">Dev</button> -->
|
||||
<span><ion-icon *ngIf="RochetChatConnectorService.isLogin" class="online" name="ellipse"></ion-icon></span>
|
||||
<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()">
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
<ion-list class="header-bottom-contacts" *ngIf="roomMembers$ | async as memberList">
|
||||
<ng-container *ngFor="let user of memberList; let i = index">
|
||||
{{ user.user.wxFullName }}<ng-container *ngIf="i < memberList.length - 1">, </ng-container>
|
||||
{{ user.wxFullName }}<ng-container *ngIf="i < memberList.length - 1">, </ng-container>
|
||||
</ng-container>
|
||||
</ion-list>
|
||||
|
||||
@@ -47,12 +47,12 @@
|
||||
*ngFor="let message of roomMessage$ | async" class="messages-list-item-wrapper"
|
||||
[ngClass]="{'my-message': message.sender.wxUserId === sessionStore.user.UserId, 'other-message': message.sender.wxUserId !== sessionStore.user.UserId}">
|
||||
<div class="message-container">
|
||||
{{ message.message }} .== {{ message.id }}
|
||||
{{ message.message }} .== {{ message.$id }}
|
||||
|
||||
<div class="message-item-options d-flex justify-content-end">
|
||||
<fa-icon [matMenuTriggerFor]="beforeMenu" icon="chevron-down" class="message-options-icon cursor-pointer"></fa-icon>
|
||||
<mat-menu #beforeMenu="matMenu" xPosition="before">
|
||||
<button (click)="messageDelete({messageId: message.messageId })" class="menuButton">Apagar mensagem</button>
|
||||
<button (click)="messageDelete({messageId: message.id })" class="menuButton">Apagar mensagem</button>
|
||||
<button (click)="editMessage(message)" class="menuButton">Editar mensagem</button>
|
||||
<button (click)="toggleEmojiPicker(message)" class="menuButton">Reagir mensagem</button>
|
||||
</mat-menu>
|
||||
|
||||
@@ -122,6 +122,7 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
|
||||
textField = ''
|
||||
|
||||
roomData$: DexieObservable<RoomListItemOutPutDTO | undefined>
|
||||
roomStatus$: DexieObservable<Boolean >
|
||||
roomMessage$: DexieObservable<TableMessage[]>
|
||||
roomMembers$: DexieObservable<TableMemberList[] | undefined>
|
||||
//userTyping$: DexieObservable<UserTypingList[] | undefined>
|
||||
@@ -160,10 +161,10 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges): void {
|
||||
console.log('change ¬!!')
|
||||
this.roomData$ = this.roomRepositoryService.getItemByIdLive(this.roomId)
|
||||
this.roomMessage$ = this.messageRepositoryService.getItemsLive(this.roomId)
|
||||
this.roomMembers$ = this.roomRepositoryService.getRoomMemberByIdLive(this.roomId) as any
|
||||
this.roomStatus$ = this.roomRepositoryService.getRoomStatus(this.roomId)
|
||||
this.roomRepositoryService.getRoomById(this.roomId)
|
||||
this.messageRepositoryService.listAllMessagesByRoomId(this.roomId)
|
||||
|
||||
@@ -214,7 +215,7 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
|
||||
|
||||
this.chatServiceService.reactToMessage({
|
||||
memberId: SessionStore.user.UserId,
|
||||
messageId: message.messageId,
|
||||
messageId: message.id,
|
||||
roomId: this.roomId,
|
||||
reaction: emoji,
|
||||
requestId: ''
|
||||
@@ -251,7 +252,7 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
|
||||
this.chatServiceService.updateMessage({
|
||||
memberId: SessionStore.user.UserId,
|
||||
message: res.data.message,
|
||||
messageId: message.messageId,
|
||||
messageId: message.id,
|
||||
requestId: '',
|
||||
roomId: this.roomId
|
||||
})
|
||||
|
||||
@@ -20,7 +20,7 @@ export class NewGroupPage implements OnInit{
|
||||
showLoader: boolean;
|
||||
displayDuration: any;
|
||||
showDuration: boolean;
|
||||
expirationDate:any;
|
||||
expirationDate:Date = null;
|
||||
_day:any;
|
||||
selectedDuration = ['','',''];
|
||||
countDownTime:any;
|
||||
@@ -93,7 +93,7 @@ export class NewGroupPage implements OnInit{
|
||||
this.expirationDate = new Date();
|
||||
}
|
||||
else {
|
||||
this.expirationDate = '';
|
||||
this.expirationDate = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,9 +123,8 @@ export class NewGroupPage implements OnInit{
|
||||
roomName: this.groupName,
|
||||
createdBy: SessionStore.user.UserId,
|
||||
roomType: 0,
|
||||
expirationDate: null,
|
||||
expirationDate: this.expirationDate?.toISOString(),
|
||||
members: []
|
||||
|
||||
})
|
||||
|
||||
if(result.isOk()) {
|
||||
@@ -147,44 +146,44 @@ export class NewGroupPage implements OnInit{
|
||||
}
|
||||
|
||||
createGroupWithAttachments(res: any) {
|
||||
this.ChatSystemService.getGroupRoom(res.result.rid).hasLoadHistory = true;
|
||||
// this.ChatSystemService.getGroupRoom(res.result.rid).hasLoadHistory = true;
|
||||
|
||||
if(this.documents) {
|
||||
this.documents.forEach(element => {
|
||||
this.ChatSystemService.getGroupRoom(res.result.rid).send({
|
||||
file: {
|
||||
"name": element.Assunto,
|
||||
"type": "application/webtrix",
|
||||
"ApplicationId": element.ApplicationId,
|
||||
"DocId": element.DocId,
|
||||
"Assunto": element.Assunto,
|
||||
},
|
||||
temporaryData: {
|
||||
data: {
|
||||
selected: {
|
||||
Id: element.DocId,
|
||||
ApplicationType: element.ApplicationId
|
||||
}
|
||||
}
|
||||
},
|
||||
attachments: [{
|
||||
"title": element.Assunto,
|
||||
"description": element.Assunto,
|
||||
"title_link_download": true,
|
||||
"type": "webtrix",
|
||||
"text": element.Assunto,
|
||||
"thumb_url": "https://static.ichimura.ed.jp/uploads/2017/10/pdf-icon.png",
|
||||
}],
|
||||
})
|
||||
});
|
||||
}
|
||||
// if(this.documents) {
|
||||
// this.documents.forEach(element => {
|
||||
// this.ChatSystemService.getGroupRoom(res.result.rid).send({
|
||||
// file: {
|
||||
// "name": element.Assunto,
|
||||
// "type": "application/webtrix",
|
||||
// "ApplicationId": element.ApplicationId,
|
||||
// "DocId": element.DocId,
|
||||
// "Assunto": element.Assunto,
|
||||
// },
|
||||
// temporaryData: {
|
||||
// data: {
|
||||
// selected: {
|
||||
// Id: element.DocId,
|
||||
// ApplicationType: element.ApplicationId
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
// attachments: [{
|
||||
// "title": element.Assunto,
|
||||
// "description": element.Assunto,
|
||||
// "title_link_download": true,
|
||||
// "type": "webtrix",
|
||||
// "text": element.Assunto,
|
||||
// "thumb_url": "https://static.ichimura.ed.jp/uploads/2017/10/pdf-icon.png",
|
||||
// }],
|
||||
// })
|
||||
// });
|
||||
// }
|
||||
|
||||
|
||||
this.ChatSystemService.getAllRooms();
|
||||
// this.ChatSystemService.getAllRooms();
|
||||
|
||||
setTimeout(() => {
|
||||
this.groupName = ""
|
||||
}, 150);
|
||||
// setTimeout(() => {
|
||||
// this.groupName = ""
|
||||
// }, 150);
|
||||
}
|
||||
|
||||
|
||||
@@ -211,7 +210,7 @@ export class NewGroupPage implements OnInit{
|
||||
handler:(value:any)=>{
|
||||
|
||||
let now = new Date();
|
||||
this.expirationDate = new Date(now.getFullYear(), now.getMonth(), now.getDate() + value.days.value, now.getHours() + value.hours.value, now.getMinutes() + value.minutes.value, now.getSeconds(), now.getMilliseconds());
|
||||
this.expirationDate = new Date(now.getFullYear(), now.getMonth(), now.getDate() + value.days.value, now.getHours() + value.hours.value, now.getMinutes() + value.minutes.value, now.getSeconds(), now.getMilliseconds())
|
||||
|
||||
this.selectedDuration = [
|
||||
value.days.value,
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
<button (click)="leaveGroup()" class="btn-cancel" shape="round">Sair do Grupo</button>
|
||||
<button (click)="openChangeGroupName()" class="btn-cancel btn-cancel mt-10" shape="round" style="min-width: 192px;">Alterar
|
||||
nome do grupo</button>
|
||||
<button (click)="setRoomOwner()" class="btn-cancel" shape="round">Adicionar admin</button>
|
||||
<div class="solid"></div>
|
||||
<button (click)="close('cancel')" full class="btn-cancel mobile-only" shape="round">Cancelar</button>
|
||||
<button (click)="deleteGroup()" class="btn-delete" shape="round">Apagar grupo</button>
|
||||
|
||||
@@ -18,7 +18,6 @@ import { RoomRepositoryService } from 'src/app/module/chat/data/repository/room-
|
||||
export class ChatPopoverPage implements OnInit {
|
||||
roomId:string;
|
||||
room: any;
|
||||
members:any;
|
||||
isAdmin = false;
|
||||
isGroupCreated: boolean;
|
||||
showLoader = false
|
||||
@@ -27,13 +26,11 @@ export class ChatPopoverPage implements OnInit {
|
||||
private popoverController: PopoverController,
|
||||
private modalController: ModalController,
|
||||
private navParams: NavParams,
|
||||
private chatService: ChatService,
|
||||
private toastService: ToastService,
|
||||
public ThemeService: ThemeService,
|
||||
private RoomRepositoryService: RoomRepositoryService
|
||||
) {
|
||||
this.roomId = this.navParams.get('roomId');
|
||||
this.members = this.navParams.get('members');
|
||||
this.isAdmin = this.navParams.get('isAdmin');
|
||||
|
||||
}
|
||||
@@ -54,7 +51,7 @@ export class ChatPopoverPage implements OnInit {
|
||||
//Top menu options
|
||||
//Close
|
||||
|
||||
async setRoomOwner(){
|
||||
async setRoomOwner() {
|
||||
let classs;
|
||||
if (window.innerWidth < 701) {
|
||||
classs = 'modal modal-desktop'
|
||||
@@ -67,7 +64,6 @@ export class ChatPopoverPage implements OnInit {
|
||||
backdropDismiss: true,
|
||||
componentProps: {
|
||||
roomId: this.roomId,
|
||||
members: this.members,
|
||||
isAdmin: this.isAdmin
|
||||
}
|
||||
});
|
||||
@@ -80,8 +76,14 @@ export class ChatPopoverPage implements OnInit {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
setAdmin() {
|
||||
this.setRoomOwner();
|
||||
}
|
||||
|
||||
async leaveGroup() {
|
||||
|
||||
//this.setRoomOwner();
|
||||
this.showLoader = true
|
||||
const result = await this.RoomRepositoryService.leaveRoom({
|
||||
id: this.roomId,
|
||||
|
||||
Reference in New Issue
Block a user