create direct message

This commit is contained in:
Peter Maquiran
2024-08-19 16:01:58 +01:00
parent 29d0a9b55e
commit ae50d9b3bd
46 changed files with 500 additions and 297 deletions
+21 -11
View File
@@ -96,6 +96,7 @@ import { DiplomaOptionsPage } from './shared/popover/deploma-options/deploma-opt
import { ImageCropperModule } from 'ngx-image-cropper';
import { createAction, createReducer, on, StoreModule } from '@ngrx/store';
import { ChatModule } from './module/chat/chat.module';
import { openTelemetryLogging, OpenTelemetryLogging } from './services/monitoring/opentelemetry/logging';
// import { ServiceWorkerModule } from '@angular/service-worker';
// import { AngularFireModule } from '@angular/fire';
// import { AngularFireMessagingModule } from '@angular/fire/messaging';
@@ -106,15 +107,6 @@ import { FirebaseX } from '@ionic-native/firebase-x/ngx'; */
//import { FCM } from 'cordova-plugin-fcm-with-dependecy-updated/ionic/ngx';
// import { WebTracerProvider } from '@opentelemetry/web';
// import { SimpleSpanProcessor } from '@opentelemetry/tracing';
// import { ConsoleSpanExporter } from '@opentelemetry/tracing';
// const provider = new WebTracerProvider();
// provider.addSpanProcessor(new SimpleSpanProcessor(new ConsoleSpanExporter()));
// provider.register();
Sentry.init(
{
dsn: 'https://5b345a3ae70b4e4da463da65881b4aaa@o4504340905525248.ingest.sentry.io/4504345615794176',
@@ -128,10 +120,28 @@ import { FirebaseX } from '@ionic-native/firebase-x/ngx'; */
new BrowserTracing({
tracingOrigins: ['localhost', 'https://gd-api.oapr.gov.ao/api/'],
}) as Integration,
]
],
beforeSend(event) {
if (event.level === 'error') {
console.log(event.exception.values[0].value)
openTelemetryLogging.send({
type: 'graylog',
payload: {
message: event.exception.values[0].value,
object: {
sentry: true,
error: event
}
},
spanContext: null
})
}
// Return event to send it to Sentry
return event;
},
},
// Forward the init method to the sibling Framework.
SentrySibling.init
SentrySibling.init,
);
export const increment = createAction('[Counter Component] Increment');
@@ -3,7 +3,8 @@ import { MessageAttachmentFileType, MessageAttachmentSource } from "./messageOut
import { base64Schema } from "src/app/utils/zod";
export const MessageInputDTOSchema = z.object({
roomId: z.string().uuid(),
roomId: z.string().uuid().optional(),
receiverId: z.number().optional(),
senderId: z.number(),
message: z.string().nullable().optional(),
messageType: z.number(),
@@ -27,7 +27,7 @@ export const MessageOutPutDataDTOSchema = z.object({
canEdit: z.boolean(),
oneShot: z.boolean(),
requireUnlock: z.boolean(),
requestId: z.string().optional(),
requestId: z.string().optional().nullable(),
reactions: z.object({
id: z.string(),
reactedAt: z.string(),
@@ -1,51 +0,0 @@
import { Injectable } from '@angular/core';
import { err, ok } from 'neverthrow';
import { SignalRService } from '../../infra/socket/signal-r.service';
interface msgObj {
roomId: string;
senderId: string;
message:string;
messageType:1;
canEdit:Boolean;
oneShot:Boolean;
requestId: string;
}
@Injectable({
providedIn: 'root'
})
export class MessageLiveDataSourceService {
constructor(
private messageLiveSignalRDataSourceService: SignalRService
) {}
async sendMessage(data: msgObj) {
try {
const result = await this.messageLiveSignalRDataSourceService.sendMessage(data)
return ok(result)
} catch (e) {
return err(e)
}
}
listenToMessages() {
return this.messageLiveSignalRDataSourceService.getMessage()
}
listenToDeleteMessages() {
return this.messageLiveSignalRDataSourceService.getMessageDelete()
}
listenToUpdateMessages() {
return this.messageLiveSignalRDataSourceService.getMessageUpdate()
}
}
@@ -0,0 +1,99 @@
import { Injectable } from '@angular/core';
import { err, ok } from 'neverthrow';
import { SignalRService } from '../../../infra/socket/signal-r.service';
import { SessionStore } from 'src/app/store/session.service';
import { MessageDeleteInputDTO } from '../../dto/message/messageDeleteInputDTO';
import { v4 as uuidv4 } from 'uuid'
import { InstanceId } from '../../../domain/chat-service.service';
import { MessageUpdateInput } from '../../../domain/use-case/message-update-by-id-use-case.service';
import { MessageOutPutDataDTO } from '../../dto/message/messageOutputDTO';
import { MessageInputDTO } from '../../dto/message/messageInputDtO';
interface msgObj {
roomId: string;
senderId: string;
message:string;
messageType:1;
canEdit:Boolean;
oneShot:Boolean;
requestId: string;
}
@Injectable({
providedIn: 'root'
})
export class MessageSocketRepositoryService {
constructor(
private socket: SignalRService
) {}
async sendMessage(data: msgObj) {
try {
const result = await this.socket.sendMessage(data)
return ok(result)
} catch (e) {
return err(e)
}
}
async sendDirectMessage(data: MessageInputDTO) {
const result = await this.socket.sendData<MessageOutPutDataDTO>({
method: 'SendDirectMessage',
data: data as any,
})
return result;
}
listenToMessages() {
return this.socket.getMessage()
}
listenToDeleteMessages() {
return this.socket.getMessageDelete()
}
listenToUpdateMessages() {
return this.socket.getMessageUpdate()
}
reactToMessageSocket(data) {
this.socket.sendData({
method: 'ReactMessage',
data
})
}
updateMessage(input: MessageUpdateInput) {
this.socket.sendData({
method: 'EditMessage',
data: input,
})
}
sendTyping(roomId) {
return this.socket.sendTyping({
roomId,
UserName:SessionStore.user.FullName,
userId: SessionStore.user.UserId
})
}
sendMessageDelete(data: MessageDeleteInputDTO) {
data['requestId'] = InstanceId +'@'+ uuidv4();
return this.socket.sendMessageDelete(data)
}
}
@@ -3,10 +3,10 @@ import { liveQuery } from 'Dexie';
import { err, ok, Result } from 'neverthrow';
import { Observable, Subject } from 'rxjs';
import { filter } from 'rxjs/operators';
import { MessageEntity } from '../../domain/entity/message';
import { MessageEntity } from '../../../domain/entity/message';
import { DexieRepository } from 'src/app/infra/repository/dexie/dexie-repository.service';
import { MessageTable, MessageTableSchema } from 'src/app/module/chat/infra/database/dexie/schema/message';
import { chatDatabase } from '../../infra/database/dexie/service';
import { chatDatabase } from '../../../infra/database/dexie/service';
import { Observable as DexieObservable, PromiseExtended } from 'Dexie';
@Injectable({
@@ -1,15 +1,15 @@
import { Injectable } from '@angular/core';
import { HttpService } from 'src/app/services/http.service';
import { MessageInputDTO, MessageInputDTOSchema } from '../dto/message/messageInputDtO';
import { MessageInputDTO, MessageInputDTOSchema } from '../../dto/message/messageInputDtO';
import { ValidateSchema } from 'src/app/services/decorators/validate-schema.decorator';
import { APIReturn } from 'src/app/services/decorators/api-validate-schema.decorator';
import { MessageOutPutDataDTOSchema, MessageOutPutDTO, MessageOutPutDTOSchema } from '../dto/message/messageOutputDTO';
import { MessageOutPutDataDTOSchema, MessageOutPutDTO, MessageOutPutDTOSchema } from '../../dto/message/messageOutputDTO';
import { DataSourceReturn } from 'src/app/services/Repositorys/type';
import { SignalRService } from '../../infra/socket/signal-r.service';
import { MessageUpdateInput } from '../../domain/use-case/message-update-by-id-use-case.service';
import { SignalRService } from '../../../infra/socket/signal-r.service';
import { MessageUpdateInput } from '../../../domain/use-case/message-update-by-id-use-case.service';
import { SessionStore } from 'src/app/store/session.service';
import { MessageDeleteInputDTO } from '../dto/message/messageDeleteInputDTO';
import { InstanceId } from '../../domain/chat-service.service';
import { MessageDeleteInputDTO } from '../../dto/message/messageDeleteInputDTO';
import { InstanceId } from '../../../domain/chat-service.service';
import { v4 as uuidv4 } from 'uuid'
@Injectable({
@@ -46,35 +46,5 @@ export class MessageRemoteDataSourceService {
return await this.httpService.get(`${this.baseUrl}/attachment/${id}`);
}
reactToMessageSocket(data) {
this.socket.sendData({
method: 'ReactMessage',
data
})
}
updateMessage(input: MessageUpdateInput) {
this.socket.sendData({
method: 'EditMessage',
data: input,
})
}
sendTyping(roomId) {
return this.socket.sendTyping({
roomId,
UserName:SessionStore.user.FullName,
userId: SessionStore.user.UserId
})
}
sendMessageDelete(data: MessageDeleteInputDTO) {
data['requestId'] = InstanceId +'@'+ uuidv4();
return this.socket.sendMessageDelete(data)
}
}
@@ -4,7 +4,7 @@ import { SessionStore } from 'src/app/store/session.service';
import { MessageReactionInput, MessageReactionUseCaseService } from 'src/app/module/chat/domain/use-case/message-reaction-by-id-use-case.service';
import { MessageUpdateInput, MessageUpdateUseCaseService } from 'src/app/module/chat/domain/use-case/message-update-by-id-use-case.service';
import { MemberAdminUseCaseService, MemberSetAdminDTO } from 'src/app/module/chat/domain/use-case/member-admin-use-case.service';
import { MessageCreateUseCaseService } from 'src/app/module/chat/domain/use-case/message-create-use-case.service';
import { MessageCreateUseCaseService, MessageEnum } from 'src/app/module/chat/domain/use-case/message-create-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';
@@ -151,8 +151,8 @@ export class ChatServiceService {
return this.MemberAdminUseCaseService.execute(input)
}
sendMessage(input: MessageEntity) {
return this.MessageCreateUseCaseService.execute(input);
sendMessage(input: MessageEntity, messageEnum: MessageEnum) {
return this.MessageCreateUseCaseService.execute(input, messageEnum);
}
asyncAllRoomMessage() {
@@ -0,0 +1,4 @@
export enum RoomType {
Group = 1,
Direct = 2
}
+4 -2
View File
@@ -6,7 +6,8 @@ import { base64Schema } from "src/app/utils/zod";
export const MessageEntitySchema = z.object({
$id: z.any().optional(),
id: z.string().optional(),
roomId: z.string(),
roomId: z.string().uuid().optional(),
receiverId: z.number().optional(),
message: z.string().optional(),
messageType: z.number(),
canEdit: z.boolean(),
@@ -38,7 +39,8 @@ export class MessageEntity implements Message {
$id: number
id: string
roomId: string
roomId?: string
receiverId?: number
message: string
messageType: number = 0
canEdit: boolean = false
@@ -1,7 +1,6 @@
import { MessageInputDTO } from "../../data/dto/message/messageInputDtO";
import { MessageOutPutDataDTO } from "../../data/dto/message/messageOutputDTO";
import { MessageEntity } from "../entity/message";
import { attachments } from '../../../../../../../../../Downloads/equilibriumito-gabinete-digital-fo-23cf0fc4cbaa/equilibriumito-gabinete-digital-fo-23cf0fc4cbaa/src/app/models/beast-orm';
export class MessageMapper {
static toDomain(DTO: MessageOutPutDataDTO) : MessageEntity {
@@ -10,6 +9,7 @@ export class MessageMapper {
static fromDomain(entity:MessageEntity, requestId): MessageInputDTO {
return {
receiverId: entity.receiverId,
canEdit: entity.canEdit,
message: entity.message,
messageType: entity.messageType,
@@ -26,7 +26,7 @@ export class MessageMapper {
applicationId: e.applicationId || 0,
docId: Number(e.docId) || 0,
mimeType: e.mimeType
}))[0]
}))[0] || {}
}
}
@@ -1,7 +1,7 @@
import { Injectable } from '@angular/core';
import { filter, map } from 'rxjs/operators';
import { InstanceId } from '../chat-service.service';
import { MessageLiveDataSourceService } from 'src/app/module/chat/data/repository/message-live-signalr-data-source.service'
import { MessageSocketRepositoryService } from 'src/app/module/chat/data/repository/message/message-live-signalr-data-source.service'
import { MessageEntity } from '../entity/message';
@Injectable({
@@ -10,12 +10,12 @@ import { MessageEntity } from '../entity/message';
export class ListenMessageByRoomIdNewUseCase {
constructor(
private MessageLiveDataSourceService: MessageLiveDataSourceService
private MessageSocketRepositoryService: MessageSocketRepositoryService
) { }
execute({roomId}: {roomId: string}) {
return this.MessageLiveDataSourceService.listenToMessages().pipe(
return this.MessageSocketRepositoryService.listenToMessages().pipe(
filter((message) => !message?.requestId?.startsWith(InstanceId) && message?.roomId == roomId),
map(message => Object.assign(new MessageEntity(), message))
)
@@ -1,6 +1,6 @@
import { Injectable } from '@angular/core';
import { filter } from 'rxjs/operators';
import { MessageLiveDataSourceService } from '../../data/repository/message-live-signalr-data-source.service';
import { MessageSocketRepositoryService } from '../../data/repository/message/message-live-signalr-data-source.service';
@Injectable({
providedIn: 'root'
@@ -8,7 +8,7 @@ import { MessageLiveDataSourceService } from '../../data/repository/message-live
export class ListenMessageUpdateByRoomIdUseCase {
constructor(
private messageLiveSignalRDataSourceService: MessageLiveDataSourceService,
private messageLiveSignalRDataSourceService: MessageSocketRepositoryService,
) { }
execute({roomId}) {
@@ -1,5 +1,5 @@
import { Injectable } from '@angular/core';
import { MessageLiveDataSourceService } from 'src/app/module/chat/data/repository/message-live-signalr-data-source.service'
import { MessageSocketRepositoryService } from 'src/app/module/chat/data/repository/message/message-live-signalr-data-source.service'
import { InstanceId } from '../chat-service.service';
import { filter, map } from 'rxjs/operators';
@@ -9,12 +9,12 @@ import { filter, map } from 'rxjs/operators';
export class ListenSendMessageUseCase {
constructor(
private MessageLiveDataSourceService: MessageLiveDataSourceService
private MessageSocketRepositoryService: MessageSocketRepositoryService
) { }
execute({roomId}: {roomId: string}) {
return this.MessageLiveDataSourceService.listenToMessages().pipe(
return this.MessageSocketRepositoryService.listenToMessages().pipe(
filter((message) => message?.requestId?.startsWith(InstanceId) && message?.roomId == roomId),
map(message => message)
)
@@ -8,8 +8,9 @@ import { createDataURL } from 'src/app/utils/ToBase64';
import { zodSafeValidation } from 'src/app/utils/zodValidation';
import { Logger } from 'src/app/services/logger/main/service';
import { MessageAttachmentSource, MessageOutPutDataDTO } from '../../data/dto/message/messageOutputDTO';
import { MessageLocalDataSourceService } from '../../data/repository/message-local-data-source.service';
import { err } from 'neverthrow';
import { MessageLocalDataSourceService } from '../../data/repository/message/message-local-data-source.service';
import { MessageSocketRepositoryService } from '../../data/repository/message/message-live-signalr-data-source.service';
import { err, Result } from 'neverthrow';
import { MessageTable } from '../../infra/database/dexie/schema/message';
import { MessageMapper } from '../mapper/messageMapper';
import { SignalRService } from '../../infra/socket/signal-r.service';
@@ -20,6 +21,11 @@ const MessageInputUseCaseSchema = z.object({
message: z.string()
})
export enum MessageEnum {
Direct = 1,
group = 2
}
export type MessageInputUseCase = z.infer< typeof MessageInputUseCaseSchema>
@Injectable({
@@ -31,10 +37,11 @@ export class MessageCreateUseCaseService {
private AttachmentLocalRepositoryService: AttachmentLocalDataSource,
private messageLocalDataSourceService: MessageLocalDataSourceService,
private messageLiveSignalRDataSourceService: SignalRService,
private messageSocketRepositoryService: MessageSocketRepositoryService
) { }
async execute(message: MessageEntity) {
async execute(message: MessageEntity, messageEnum: MessageEnum) {
const validation = zodSafeValidation<MessageEntity>(MessageEntitySchema, message)
@@ -85,7 +92,14 @@ export class MessageCreateUseCaseService {
message.sending = true
const DTO = MessageMapper.fromDomain(message, message.requestId)
const sendMessageResult = await this.messageLiveSignalRDataSourceService.sendMessage<MessageOutPutDataDTO>(DTO)
let sendMessageResult: Result<MessageOutPutDataDTO, any>
if(messageEnum == MessageEnum.group) {
sendMessageResult = await this.messageLiveSignalRDataSourceService.sendMessage<MessageOutPutDataDTO>(DTO)
} else {
sendMessageResult = await this.messageSocketRepositoryService.sendDirectMessage(DTO)
}
// return this sendMessageResult
if(sendMessageResult.isOk()) {
@@ -101,7 +115,9 @@ export class MessageCreateUseCaseService {
$id : message.$id
}
return this.messageLocalDataSourceService.update(message.$id, {...clone, sending: false, roomId: message.roomId})
this.messageLocalDataSourceService.update(message.$id, {...clone, sending: false, roomId: message.roomId})
return sendMessageResult
} else {
Logger.error('failed to send message to the server', {
error: sendMessageResult.error
@@ -1,7 +1,9 @@
import { Injectable } from '@angular/core';
import { z } from 'zod';
import { SafeValidateSchema, ValidateSchema } from 'src/app/services/decorators/validate-schema.decorator';
import { MessageRemoteDataSourceService } from '../../data/repository/message-remote-data-source.service';
import { MessageRemoteDataSourceService } from '../../data/repository/message/message-remote-data-source.service';
import { MessageSocketRepositoryService } from '../../data/repository/message/message-live-signalr-data-source.service';
export const MessageDeleteInputDTOSchema = z.object({
requestId: z.string().optional(),
@@ -17,7 +19,7 @@ export type MessageDeleteInputDTO = z.infer<typeof MessageDeleteInputDTOSchema>
})
export class MessageDeleteLiveUseCaseService {
constructor(
public repository: MessageRemoteDataSourceService
public repository: MessageSocketRepositoryService
) { }
@SafeValidateSchema(MessageDeleteInputDTOSchema, 'MessageDeleteUseCaseService')
@@ -1,7 +1,8 @@
import { Injectable } from '@angular/core';
import { object, z } from 'zod';
import { ValidateSchema } from 'src/app/services/decorators/validate-schema.decorator';
import { MessageRemoteDataSourceService } from '../../data/repository/message-remote-data-source.service';
import { MessageRemoteDataSourceService } from '../../data/repository/message/message-remote-data-source.service';
import { MessageSocketRepositoryService } from '../../data/repository/message/message-live-signalr-data-source.service';
const MessageReactionInputDTOSchema = z.object({
@@ -20,7 +21,7 @@ export type MessageReactionInput = z.infer< typeof MessageReactionInputDTOSchema
export class MessageReactionUseCaseService {
constructor(
public repository: MessageRemoteDataSourceService
public repository: MessageSocketRepositoryService
) { }
@ValidateSchema(MessageReactionInputDTOSchema)
@@ -1,8 +1,8 @@
import { Injectable } from '@angular/core';
import { err, ok } from 'neverthrow';
import { SessionStore } from 'src/app/store/session.service';
import { MessageLocalDataSourceService } from '../../data/repository/message-local-data-source.service';
import { MessageRemoteDataSourceService } from '../../data/repository/message-remote-data-source.service';
import { MessageLocalDataSourceService } from '../../data/repository/message/message-local-data-source.service';
import { MessageRemoteDataSourceService } from '../../data/repository/message/message-remote-data-source.service';
import { SignalRService } from '../../infra/socket/signal-r.service';
@Injectable({
@@ -1,7 +1,9 @@
import { Injectable } from '@angular/core';
import { z } from 'zod';
import { ValidateSchema } from 'src/app/services/decorators/validate-schema.decorator';
import { MessageRemoteDataSourceService } from '../../data/repository/message-remote-data-source.service';
import { MessageRemoteDataSourceService } from '../../data/repository/message/message-remote-data-source.service';
import { MessageSocketRepositoryService } from '../../data/repository/message/message-live-signalr-data-source.service';
const MessageUpdateInputDTOSchema = z.object({
memberId: z.number(),
@@ -20,7 +22,7 @@ export type MessageUpdateInput = z.infer< typeof MessageUpdateInputDTOSchema>
export class MessageUpdateUseCaseService {
constructor(
public repository: MessageRemoteDataSourceService
public repository: MessageSocketRepositoryService
) { }
@ValidateSchema(MessageUpdateInputDTOSchema)
@@ -1,5 +1,5 @@
import { Injectable } from '@angular/core';
import { MessageLocalDataSourceService } from '../../data/repository/message-local-data-source.service';
import { MessageLocalDataSourceService } from '../../data/repository/message/message-local-data-source.service';
import { MessageOutPutDataDTO } from '../../data/dto/message/messageOutputDTO';
import { MessageTable } from '../../infra/database/dexie/schema/message';
import { SignalRService } from '../../infra/socket/signal-r.service';
@@ -1,5 +1,5 @@
import { Injectable, Input } from '@angular/core';
import { MessageLocalDataSourceService } from '../../../data/repository/message-local-data-source.service';
import { MessageLocalDataSourceService } from '../../../data/repository/message/message-local-data-source.service';
import { TracingType, XTracerAsync } from 'src/app/services/monitoring/opentelemetry/tracer';
import { ParamsValidation } from 'src/app/services/decorators/validate-schema.decorator';
import { MessageOutPutDataDTOSchema } from '../../../data/dto/message/messageOutputDTO';
@@ -1,5 +1,5 @@
import { Injectable } from '@angular/core';
import { MessageLocalDataSourceService } from '../../../data/repository/message-local-data-source.service';
import { MessageLocalDataSourceService } from '../../../data/repository/message/message-local-data-source.service';
import { MessageOutPutDataDTO } from '../../../data/dto/message/messageOutputDTO';
@Injectable({
@@ -1,5 +1,5 @@
import { Injectable } from '@angular/core';
import { MessageLocalDataSourceService } from '../../../data/repository/message-local-data-source.service';
import { MessageLocalDataSourceService } from '../../../data/repository/message/message-local-data-source.service';
import { MessageOutPutDataDTO, MessageOutPutDataDTOSchema } from '../../../data/dto/message/messageOutputDTO';
import { ParamsValidation, SafeValidateSchema, ValidateSchema } from 'src/app/services/decorators/validate-schema.decorator';
import { MessageInputDTOSchema } from '../../../data/dto/message/messageInputDtO';
@@ -1,8 +1,8 @@
import { Injectable } from '@angular/core';
import { MessageLocalDataSourceService } from '../../data/repository/message-local-data-source.service';
import { MessageLocalDataSourceService } from '../../data/repository/message/message-local-data-source.service';
import { messageListDetermineChanges } from '../../data/async/list/rooms/messageListChangedetector';
import { MessageTable } from '../../infra/database/dexie/schema/message';
import { MessageRemoteDataSourceService } from '../../data/repository/message-remote-data-source.service';
import { MessageRemoteDataSourceService } from '../../data/repository/message/message-remote-data-source.service';
import { ok } from 'neverthrow';
import { RoomLocalRepository } from '../../data/repository/room-local-repository.service';
@@ -5,7 +5,7 @@ import { z } from 'zod';
export const MessageTableSchema = z.object({
$id: z.number().optional(),
id: z.string().optional(),
roomId: z.string().uuid(),
roomId: z.string().uuid().optional(),
message: z.string().nullable().optional(),
messageType: z.number(),
canEdit: z.boolean(),
@@ -18,6 +18,7 @@ export const MessageTableSchema = z.object({
wxeMail: z.string(),
userPhoto: z.string(),
}),
receiverId: z.number().optional(),
sending: z.boolean().optional(),
reactions: z.object({
id: z.string(),
@@ -134,8 +134,8 @@ export class SignalRService {
return this.messageUpdateSubject.asObservable()
}
sendData(input: ISignalRInput) {
return this.connection.sendData(input)
sendData<T>(input: ISignalRInput) {
return this.connection.sendData<T>(input)
}
getData() {
+3 -3
View File
@@ -241,7 +241,7 @@ export class SignalRConnection {
}
sendData(input: ISignalRInput): Promise<Result<any, any>> {
sendData<T>(input: ISignalRInput): Promise<Result<T, any>> {
return new Promise((resolve, reject) => {
if(this.connectionStateSubject.value == true) {
@@ -249,10 +249,10 @@ export class SignalRConnection {
this.hubConnection.invoke(input.method, input.data)
this.sendDataSubject.pipe(
filter((message: any) => input.data.requestId == message?.requestId),
filter((message) => input.data.requestId == message?.data.requestId),
first()
).subscribe(value => {
resolve(ok(value))
resolve(ok(value.data as unknown as T))
console.log('Received valid value:', value);
});
+2 -4
View File
@@ -43,14 +43,12 @@ export class WebSocketGraylogService {
payload: data.payload,
requestId: data.requestId,
parentSpan: {
traceId: data.spanContext.spanContext().traceId,
spanId: data.spanContext.spanContext().spanId,
traceId: data?.spanContext?.spanContext().traceId,
spanId: data?.spanContext?.spanContext().spanId,
}
}));
// data.spanContext.end()
} else {
console.warn('WebSocket is not open. Message not sent.');
}
}
+4 -1
View File
@@ -52,7 +52,10 @@ const routes: Routes = [
path: 'set-room-owner',
loadChildren: () => import('./modal/set-room-owner/set-room-owner.module').then( m => m.SetRoomOwnerPageModule)
},
{
path: 'contacts',
loadChildren: () => import('./component/contacts/contacts.module').then( m => m.ContactsPageModule)
},
];
@NgModule({
+1 -1
View File
@@ -18,7 +18,7 @@ import { EditGroupPageModule } from './component/edit-group/edit-group.module';
import { GroupContactsPageModule } from './component/group-messages/group-contacts/group-contacts.module';
import { GroupMessagesPageModule } from './component/group-messages/group-messages.module';
import { MessagesPageModule } from './component/messages/messages.module';
import { ContactsPageModule } from './component/new-group/contacts/contacts.module';
import { ContactsPageModule } from './component/contacts/contacts.module';
import { NewGroupPageModule } from './component/new-group/new-group.module';
@NgModule({
@@ -18,6 +18,7 @@ import { BtnSeguintePageModule } from 'src/app/shared/btn-seguinte/btn-seguinte.
ContactsPageRoutingModule,
BtnSeguintePageModule,
],
declarations: [ContactsPage]
declarations: [ContactsPage],
exports: [ContactsPage]
})
export class ContactsPageModule {}
@@ -9,9 +9,9 @@
</button>
</div>
<div class="div-title">
<!-- Create direct message -->
<ion-label class="title">Contactos</ion-label>
</div>
<app-btn-seguinte (click)="groupMessages()" class="cursor-pointer"></app-btn-seguinte>
</div>
</div>
</ion-toolbar>
@@ -23,34 +23,27 @@
</ion-header>
<ion-content>
<ion-refresher name="refresher" slot="fixed" (ionRefresh)="doRefresh($event)">
<!-- <ion-progress-bar type="indeterminate" *ngIf="showLoader"></ion-progress-bar> -->
<ion-progress-bar type="indeterminate" *ngIf="loading"></ion-progress-bar>
<ion-refresher-content>
</ion-refresher-content>
</ion-refresher>
<div class="main-content">
<ion-progress-bar class="position-absolute" type="indeterminate" *ngIf="loading"></ion-progress-bar>
<div *ngFor="let userContainer of userContainer | keyvalue;" >
<!-- <ion-list>
<ion-item *ngFor="let user of searchedItem">
{{user.name}}
</ion-item>
</ion-list> -->
<!-- <ion-virtual-scroll [items]="ChatSystemService.users" approxItemHeight="70px" [headerFn]="separateLetter">
<div class="item-divider" *virtualHeader="let header">
<ion-label>{{header}}</ion-label>
<div class="item-divider">
<ion-label>{{ userContainer.key }}</ion-label>
</div>
<div *virtualItem="let user" class="item-checkbox">
<ion-checkbox color="primary"></ion-checkbox>
<p>{{user.first}} {{user.last}}</p>
<ion-icon name="ellipse"></ion-icon>
<div *ngFor="let user of userContainer.value; let i = index" class="d-flex px-20 align-center" (click)="select(user)">
<ion-checkbox [(ngModel)]="user.isChecked" color="primary"></ion-checkbox>
<ion-label class="flex-grow-1 px-10">{{user.wxFullName}}</ion-label>
<div class="icon"><ion-icon name="ellipse"></ion-icon></div>
</div>
</ion-virtual-scroll> -->
</div>
</div>
</ion-content>
@@ -76,52 +76,108 @@
}
ion-content{
--background:transparent;
}
}
.main-content{
width: 100%;
//width: 100%;
height: 100%;
font-family: Roboto;
margin: 0 auto;
background-color: #fff;
overflow:auto;
padding: 0 0 0 0;
overflow:auto;
.item-divider{
background: #ebebeb;
font-size: rem(15);
margin: 10px 0 10px 0;
padding:5px 0 5px 20px;
.members{
padding: 15px 20px 0 20px !important;
.members-list{
margin: 0 !important;
padding: 0 !important;
}
}
.members-label{
//margin: 10px 20px 10px 20px !important;
/* font-size: rem(15); */
font-weight: bold;
}
.members-checkbox{
display: flex;
//margin: 0px 20px 0px 20px !important;
overflow: auto;
align-items: center;
.detele-item-icon{
display: none;
width: rem(30);
margin-left: 15px;
}
.detele-item-icon ion-icon{
font-size: rem(20) !important;
}
}
.members-checkbox:hover{
.detele-item-icon{
display: flex;
justify-content: flex-end;
}
}
.item-divider{
background: #ebebeb;
font-size: rem(15);
margin: 10px 0 10px 0;
padding:5px 0 5px 20px;
}
.item-checkbox{
display: flex;
margin: 10px 20px 10px 20px !important;
overflow: auto;
align-items: center;
}
.item-checkbox ion-checkbox{
--border-color: #0d89d1;
--background-checked:#0d89d1;
.item-checkbox ion-checkbox, .members-checkbox ion-checkbox{
--border-color: var(--title-text-color);
--background-checked:var(--title-text-color);
float: left;
}
.item-checkbox p{
display: block;
margin: 0 !important;
width: 330px;
.item-checkbox ion-label, .members-checkbox p{
padding-left: 10px;
font-size: rem(15);
color: #0d89d1;
color: var(--title-text-color);
float: left;
flex-grow: 1;
}
.item-checkbox ion-icon{
.icon, .members-checkbox ion-icon{
font-size: rem(10);
float: left;
color:#99e47b;
margin-left: 10px;
}
.online{
color:#99e47b !important;
}
.offline{
color:#cbced1 !important;
}
.away{
color:#ffd21f !important;
}
.invisible{
color:#cbced1 !important;
}
.busy{
color:#f5455c !important;
}
}
.inactive {
opacity: 0.7;
button {
display: none !important;
}
}
@@ -0,0 +1,153 @@
import { Component, EventEmitter, OnInit, Output } from '@angular/core';
import { ModalController } from '@ionic/angular';
import { GroupMessagesPage } from '../group-messages/group-messages.page';
import { ThemeService } from 'src/app/services/theme.service'
import { UserContacts } from 'src/app/services/Repositorys/contacts/data-source/contacts-data-source.service';
import { ContactRepositoryService } from 'src/app/services/Repositorys/contacts/repository/contacts-repository.service';
import { ChatServiceService } from 'src/app/module/chat/domain/chat-service.service';
import { HttpErrorHandle } from 'src/app/services/http-error-handle.service';
import { ToastService } from 'src/app/services/toast.service';
import { SessionStore } from 'src/app/store/session.service';
import { MessageEnum } from 'src/app/module/chat/domain/use-case/message-create-use-case.service';
import { MessageEntity } from 'src/app/module/chat/domain/entity/message';
// import { ChatSystemService } from 'src/app/services/chat/chat-system.service'
@Component({
selector: 'app-contacts',
templateUrl: './contacts.page.html',
styleUrls: ['./contacts.page.scss'],
})
export class ContactsPage implements OnInit {
options:any;
loading = false
userList: UserContacts[] = []
currentMembers:UserContacts[];
allChatUsers: UserContacts[] = [];
userContainer: {[key: string]: ( UserContacts & {isChecked: boolean})[] } = {}
@Output() openMessage: EventEmitter<any> = new EventEmitter<any>();
@Output() emptyTextDescriptionOpen: EventEmitter<any> = new EventEmitter<any>();
@Output() backToChat: EventEmitter<any> = new EventEmitter<any>();
@Output() closeAllDesktopComponents: EventEmitter<any> = new EventEmitter<any>();
roomId= ''
constructor(
private modalController: ModalController,
public ThemeService: ThemeService,
private contactsRepositoryService: ContactRepositoryService,
private httpErrorHandle: HttpErrorHandle,
private toastService: ToastService,
private chatServiceService: ChatServiceService
)
{}
ngOnInit() {
this.loadUsers();
}
async loadUsers() {
this.loading = true
const getallChatUsers = await this.contactsRepositoryService.getUsers()
if(getallChatUsers.isOk()) {
this.allChatUsers = getallChatUsers.value.data.result.sort((a,b) => {
if(a.wxFullName < b.wxFullName) {
return -1;
}
if(a.wxFullName > b.wxFullName) {
return 1;
}
return 0;
});
for(const user of this.allChatUsers) {
const firstLetter = user.wxFullName.charAt(0)
if(!this.userContainer[firstLetter]) {
user['isChecked'] = false
this.userContainer[firstLetter] = [user as any]
} else {
const userIds = this.userContainer[firstLetter].map( e => e.wxUserId)
if(!userIds.includes(user.wxUserId)) {
user['isChecked'] = false
this.userContainer[firstLetter].push(user as any)
}
}
}
}
else if (getallChatUsers.isErr() ) {
console.log(getallChatUsers.error)
} else {
this.toastService._badRequest("Pedimos desculpa mas não foi possível executar a acção. Por favor, contacte o apoio técnico.")
}
this.loading = false;
}
separateLetter(record, recordIndex, records){
if(recordIndex == 0){
return record.first[0];
}
let first_prev = records[recordIndex - 1].first[0];
let first_current = record.first[0];
if(first_prev != first_current){
return first_current;
}
return null;
}
doRefresh(event){
}
close(roomId) {
if (roomId) {
this.backToChat.emit({ roomId: roomId });
} else {
this.closeAllDesktopComponents.emit();
}
}
onChange(event) {
}
clicked() {}
selectOnce = true
async select(user: UserContacts) {
const message = new MessageEntity();
message.sender = {
userPhoto: '',
wxeMail: SessionStore.user.Email,
wxFullName: SessionStore.user.FullName,
wxUserId: SessionStore.user.UserId
}
message.receiverId = user.wxUserId
message.message = 'hello'
const result = await this.chatServiceService.sendMessage(message, MessageEnum.Direct)
if(result.isOk()) {
this.close(result.value.roomId)
} else {
console.log(result.error)
}
}
}
@@ -48,7 +48,7 @@
</div>
</ion-list>
</div>
pppp
<div *ngFor="let userContainer of userContainer | keyvalue;" >
<div class="item-divider">
@@ -1,7 +1,7 @@
import { AfterViewInit, Component, ElementRef, EventEmitter, Input, OnChanges, OnDestroy, OnInit, Output, SimpleChanges, ViewChild } from '@angular/core';
import { AnimationController, GestureController, IonRange, ModalController, PopoverController } from '@ionic/angular';
import { ToastService } from 'src/app/services/toast.service';
import { ContactsPage } from '../new-group/contacts/contacts.page';
import { ContactsPage } from '../contacts/contacts.page';
import { ChatOptionsFeaturesPage } from 'src/app/modals/chat-options-features/chat-options-features.page';
import { TimeService } from 'src/app/services/functions/time.service';
import { FileService } from 'src/app/services/functions/file.service';
@@ -43,8 +43,9 @@ import { ChatPopoverPage } from '../../modal/chat-popover/chat-popover.page';
import { LastMessage } from '../../utils/lastMessage';
import { UserTypingLocalRepository } from 'src/app/module/chat/data/repository/user-typing-local-data-source.service';
import { UserTypingRemoteRepositoryService } from 'src/app/module/chat/data/repository/user-typing-live-data-source.service';
import { MessageLocalDataSourceService } from 'src/app/module/chat/data/repository/message-local-data-source.service';
import { MessageRemoteDataSourceService } from 'src/app/module/chat/data/repository/message-remote-data-source.service';
import { MessageLocalDataSourceService } from 'src/app/module/chat/data/repository/message/message-local-data-source.service';
import { MessageRemoteDataSourceService } from 'src/app/module/chat/data/repository/message/message-remote-data-source.service';
import { MessageEnum } from 'src/app/module/chat/domain/use-case/message-create-use-case.service';
@Component({
@@ -567,7 +568,7 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
safeFile: this.sanitiser.bypassSecurityTrustResourceUrl(this.audioRecordedDataUrl)
}]
this.chatServiceService.sendMessage(message)
this.chatServiceService.sendMessage(message, MessageEnum.group)
this.messages1[this.roomId].push(message)
setTimeout(() => {
this.scrollToBottomClicked()
@@ -628,7 +629,7 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
setTimeout(() => {
this.scrollToBottomClicked()
}, 100)
const data = await this.chatServiceService.sendMessage(message)
const data = await this.chatServiceService.sendMessage(message, MessageEnum.group)
}
@@ -810,7 +811,7 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
setTimeout(() => {
this.scrollToBottomClicked()
}, 100)
this.chatServiceService.sendMessage(message)
this.chatServiceService.sendMessage(message, MessageEnum.group)
}
@@ -866,7 +867,7 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
setTimeout(() => {
this.scrollToBottomClicked()
}, 100)
this.chatServiceService.sendMessage(message)
this.chatServiceService.sendMessage(message, MessageEnum.group)
this.textField = ''
}
@@ -920,7 +921,7 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
setTimeout(() => {
this.scrollToBottomClicked()
}, 100)
this.chatServiceService.sendMessage(message)
this.chatServiceService.sendMessage(message, MessageEnum.group)
}
}
@@ -976,7 +977,7 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
setTimeout(() => {
this.scrollToBottomClicked()
}, 100)
this.chatServiceService.sendMessage(message)
this.chatServiceService.sendMessage(message, MessageEnum.group)
}
} else {
@@ -1,73 +0,0 @@
import { Component, OnInit } from '@angular/core';
import { ModalController } from '@ionic/angular';
import { GroupMessagesPage } from '../../group-messages/group-messages.page';
import { ThemeService } from 'src/app/services/theme.service'
// import { ChatSystemService } from 'src/app/services/chat/chat-system.service'
@Component({
selector: 'app-contacts',
templateUrl: './contacts.page.html',
styleUrls: ['./contacts.page.scss'],
})
export class ContactsPage implements OnInit {
options:any;
constructor(
private modalController: ModalController,
public ThemeService: ThemeService,
// public ChatSystemService: ChatSystemService
)
{
}
ngOnInit() {
this.loadUsers();
}
loadUsers(){
// sthis.ChatSystemService.getUser()
}
separateLetter(record, recordIndex, records){
if(recordIndex == 0){
return record.first[0];
}
let first_prev = records[recordIndex - 1].first[0];
let first_current = record.first[0];
if(first_prev != first_current){
return first_current;
}
return null;
}
doRefresh(event){
}
close(){
this.modalController.dismiss();
}
onChange(event){
}
clicked(){
}
async groupMessages(){
const modal = await this.modalController.create({
component: GroupMessagesPage,
componentProps: {},
cssClass: 'contacts',
backdropDismiss: false
});
modal.onDidDismiss();
await modal.present();
}
}
@@ -7,10 +7,6 @@ const routes: Routes = [
{
path: '',
component: NewGroupPage
},
{
path: 'contacts',
loadChildren: () => import('./contacts/contacts.module').then( m => m.ContactsPageModule)
}
];
@@ -11,7 +11,7 @@
</div>
<div class="div-title">
<!-- MOBILE -->
<ion-label class="title">Nova Conversa</ion-label>
<ion-label class="title">Nova Conversa ..</ion-label>
</div>
</div>
</div>
@@ -38,8 +38,8 @@
<ion-label>{{ userContainer.key }}</ion-label>
</div>
<div *ngFor="let user of userContainer.value; let i = index" class="d-flex px-20 align-center">
<ion-label class="flex-grow-1 px-10">{{user.wxFullName}}</ion-label>
<div *ngFor="let user of userContainer.value; let i = index" class="d-flex px-20 align-center" (click)="select(user)">
<ion-label class="flex-grow-1 px-10 cursor-pointer">{{user.wxFullName}}</ion-label>
<div class="icon"><ion-icon name="ellipse"></ion-icon></div>
</div>
</div>
@@ -6,6 +6,9 @@ import { ContactRepositoryService } from 'src/app/services/Repositorys/contacts/
import { UserContacts } from 'src/app/services/Repositorys/contacts/data-source/contacts-data-source.service';
import { HttpErrorHandle } from 'src/app/services/http-error-handle.service';
import { ToastService } from 'src/app/services/toast.service';
import { ChatServiceService } from 'src/app/module/chat/domain/chat-service.service'
import { MessageEntity } from 'src/app/module/chat/domain/entity/message';
import { MessageEnum } from 'src/app/module/chat/domain/use-case/message-create-use-case.service';
@Component({
@@ -38,6 +41,7 @@ export class ContactsPage implements OnInit {
private contactsRepositoryService: ContactRepositoryService,
private httpErrorHandle: HttpErrorHandle,
private toastService: ToastService,
private chatServiceService: ChatServiceService
)
{
this.loggedUser = SessionStore.user.ChatData['data'];
@@ -159,4 +163,23 @@ export class ContactsPage implements OnInit {
close() {
this.modalController.dismiss({});
}
select(user: UserContacts) {
const message = new MessageEntity();
message.sender = {
userPhoto: '',
wxeMail: SessionStore.user.Email,
wxFullName: SessionStore.user.FullName,
wxUserId: SessionStore.user.UserId
}
message.receiverId = user.wxUserId
message.message = 'hello'
this.chatServiceService.sendMessage(message, MessageEnum.Direct)
}
}
@@ -44,7 +44,8 @@ import { RoomLocalRepository } from 'src/app/module/chat/data/repository/room-lo
import { MemberListLocalRepository } from 'src/app/module/chat/data/repository/member-list-local-repository.service'
import { UserTypingLocalRepository } from 'src/app/module/chat/data/repository/user-typing-local-data-source.service';
import { UserTypingRemoteRepositoryService } from 'src/app/module/chat/data/repository/user-typing-live-data-source.service';
import { MessageLocalDataSourceService } from 'src/app/module/chat/data/repository/message-local-data-source.service';
import { MessageLocalDataSourceService } from 'src/app/module/chat/data/repository/message/message-local-data-source.service';
import { MessageEnum } from 'src/app/module/chat/domain/use-case/message-create-use-case.service';
const IMAGE_DIR = 'stored-images';
@@ -525,7 +526,7 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
wxUserId: SessionStore.user.UserId
}
this.chatServiceService.sendMessage(message)
this.chatServiceService.sendMessage(message, MessageEnum.group)
this.messages1[this.roomId].push(message)
this.textField = ''
@@ -568,7 +569,7 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
}]
this.messages1[this.roomId].push(message)
this.chatServiceService.sendMessage(message)
this.chatServiceService.sendMessage(message, MessageEnum.group)
setTimeout(() => {
this.scrollToBottomClicked()
}, 100)
@@ -749,7 +750,7 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
}]
this.messages1[this.roomId].push(message)
this.chatServiceService.sendMessage(message)
this.chatServiceService.sendMessage(message, MessageEnum.group)
}
@@ -799,7 +800,7 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
}]
this.messages1[this.roomId].push(message)
this.chatServiceService.sendMessage(message)
this.chatServiceService.sendMessage(message, MessageEnum.group)
this.textField = ''
}
@@ -845,7 +846,7 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
}]
this.messages1[this.roomId].push(message)
this.chatServiceService.sendMessage(message)
this.chatServiceService.sendMessage(message, MessageEnum.group)
}
}
@@ -896,7 +897,7 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
}]
this.messages1[this.roomId].push(message)
this.chatServiceService.sendMessage(message)
this.chatServiceService.sendMessage(message, MessageEnum.group)
return
}
@@ -940,7 +941,7 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
}]
this.messages1[this.roomId].push(message)
this.chatServiceService.sendMessage(message)
this.chatServiceService.sendMessage(message, MessageEnum.group)
}
+1
View File
@@ -0,0 +1 @@
import { Event } from '@sentry/types/types/event';
+1 -1
View File
@@ -48,4 +48,4 @@ platformBrowserDynamic().bootstrapModule(AppModule)
// Call the element loader after the platform has been bootstrapped
defineCustomElements(window);
defineCustomElements(window);