mirror of
https://code.equilibrium.co.ao/ITO/doneit-web.git
synced 2026-04-18 20:47:54 +00:00
receive message live
This commit is contained in:
@@ -16,7 +16,7 @@
|
||||
"path": "../grayLog"
|
||||
},
|
||||
{
|
||||
"path": "../../../Downloads/equilibriumito-gabinete-digital-fo-4f51cb55504b"
|
||||
"path": "../../../Downloads/equilibriumito-gabinete-digital-fo-23cf0fc4cbaa/equilibriumito-gabinete-digital-fo-23cf0fc4cbaa"
|
||||
}
|
||||
],
|
||||
"settings": {
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { MessageLiveDataSourceService } from '../../data-source/message/message-live-data-source.service';
|
||||
import { MessageLocalDataSourceService } from '../../data-source/message/message-local-data-source.service';
|
||||
import { IncomingMessageSchema, MessageLocalDataSourceService } from '../../data-source/message/message-local-data-source.service';
|
||||
import { MessageRemoteDataSourceService } from '../../data-source/message/message-remote-data-source.service';
|
||||
import { SignalRService } from '../../../infra/socket/signal-r.service';
|
||||
import { filter } from 'rxjs/operators';
|
||||
import { InstanceId } from '../../repository/message-respository.service';
|
||||
import { SocketStreamReturn } from 'src/app/services/decorators/socket-validate-schema.decorator';
|
||||
import { SafeValidateSchema } from 'src/app/services/decorators/validate-schema.decorator';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
@@ -26,25 +28,33 @@ export class MessageAsyncService {
|
||||
).subscribe(async (message: any) => {
|
||||
|
||||
console.log('message async ', message)
|
||||
const id = message.id
|
||||
|
||||
const id = message.id + ''
|
||||
delete message.id;
|
||||
|
||||
const result = await this.messageLocalDataSourceService.createMessage({
|
||||
const incomingMessage = {
|
||||
...message,
|
||||
messageId: id,
|
||||
sending: false,
|
||||
...message
|
||||
})
|
||||
|
||||
if(result.isOk()) {
|
||||
|
||||
console.log(result.value)
|
||||
console.log("nice send receive")
|
||||
|
||||
} else {
|
||||
console.log(result.error)
|
||||
roomId:message.chatRoomId
|
||||
}
|
||||
|
||||
this.incomingMessage(incomingMessage)
|
||||
|
||||
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
@SafeValidateSchema(IncomingMessageSchema, 'socket/incomingMessage')
|
||||
async incomingMessage(IncomingMessageSchema: any) {
|
||||
|
||||
const result = await this.messageLocalDataSourceService.sendMessage(IncomingMessageSchema)
|
||||
|
||||
if(result.isOk()) {
|
||||
|
||||
} else {
|
||||
console.log(result.error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,24 @@ const tableSchema = z.object({
|
||||
id: z.any().optional(),
|
||||
messageId: z.string().optional(),
|
||||
roomId: z.string().uuid(),
|
||||
senderId: z.number(),
|
||||
message: z.string(),
|
||||
messageType: z.number(),
|
||||
canEdit: z.boolean(),
|
||||
oneShot: z.boolean(),
|
||||
sentAt: z.string().optional(),
|
||||
requireUnlock: z.boolean(),
|
||||
sender: z.object({
|
||||
wxUserId: z.number(),
|
||||
wxFullName: z.string(),
|
||||
wxeMail: z.string(),
|
||||
userPhoto: z.string(),
|
||||
}),
|
||||
sending: z.boolean().optional()
|
||||
})
|
||||
|
||||
export const IncomingMessageSchema = z.object({
|
||||
messageId: z.string().optional(),
|
||||
roomId: z.string().uuid(),
|
||||
message: z.string(),
|
||||
messageType: z.number(),
|
||||
canEdit: z.boolean(),
|
||||
@@ -36,7 +53,7 @@ export const messageDataSource = new Dexie('chat-message') as Dexie & {
|
||||
};
|
||||
|
||||
messageDataSource.version(1).stores({
|
||||
message: '++id, roomId, senderId, message, messageType, canEdit, oneShot, requireUnlock, messageId'
|
||||
message: '++id, roomId, message, messageType, canEdit, oneShot, requireUnlock, messageId'
|
||||
});
|
||||
|
||||
@Injectable({
|
||||
|
||||
@@ -6,6 +6,7 @@ import { MessageLocalDataSourceService, TableMessage } from '../data-source/mess
|
||||
import { SessionStore } from 'src/app/store/session.service';
|
||||
import { SignalRService } from '../../infra/socket/signal-r.service';
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import { filter } from 'rxjs/operators';
|
||||
|
||||
export const InstanceId = uuidv4();
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ export class SignalRService {
|
||||
|
||||
private async establishConnection() {
|
||||
|
||||
const connection = new SignalRConnection({url:'https://gdapi-dev.dyndns.info/stage/chathub'})
|
||||
const connection = new SignalRConnection({url:'https://gdapi-dev.dyndns.info/stage/api/v2/chathub'})
|
||||
const attempConnection = await connection.establishConnection()
|
||||
|
||||
if(attempConnection.isOk()) {
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
const connection = new signalR.HubConnectionBuilder()
|
||||
.withAutomaticReconnect()
|
||||
.withUrl("https://gdapi-dev.dyndns.info/stage/chathub")
|
||||
.withUrl("https://gdapi-dev.dyndns.info/stage/api/v2/chathub")
|
||||
.build();
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
import { HttpErrorResponse } from '@angular/common/http';
|
||||
import { Result } from 'neverthrow';
|
||||
import { z, ZodError } from 'zod';
|
||||
import * as Sentry from '@sentry/capacitor';
|
||||
import { ColoredLoggerService } from '../logger/colored/service';
|
||||
|
||||
export function SocketStreamReturn(schema: z.ZodTypeAny, context: string) {
|
||||
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
|
||||
const originalMethod = descriptor.value;
|
||||
|
||||
descriptor.value = async function (...args: any[]) {
|
||||
const result: Result<any, HttpErrorResponse> = await originalMethod.apply(this, args);
|
||||
|
||||
if(result.isOk()) {
|
||||
try {
|
||||
// Validate the result using the provided schema
|
||||
schema.parse(result.value);
|
||||
|
||||
} catch (error) {
|
||||
if (error instanceof ZodError) {
|
||||
// If validation fails, throw an error with the details
|
||||
//
|
||||
ColoredLoggerService.error(error.errors, 'socket unexpected data structure '+ context, schema._def.description)
|
||||
|
||||
} else {
|
||||
console.log('failed to setup the SocketStreamReturn successful')
|
||||
// Throw any other unexpected errors
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
return descriptor;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
import { err } from 'neverthrow';
|
||||
import { Schema } from 'zod';
|
||||
import { Schema, ZodError } from 'zod';
|
||||
import { ColoredLoggerService } from '../logger/colored/service';
|
||||
import { TracingType } from '../monitoring/opentelemetry/tracer';
|
||||
|
||||
export function ValidateSchema(schema: Schema) {
|
||||
return (
|
||||
@@ -14,8 +16,54 @@ export function ValidateSchema(schema: Schema) {
|
||||
args[0] = model;
|
||||
return originalMethod.apply(this, args);
|
||||
} catch (e) {
|
||||
if (e instanceof ZodError) {
|
||||
// If validation fails, throw an error with the details
|
||||
//
|
||||
ColoredLoggerService.error(e.errors, 'socket unexpected data structure '+ schema._def.description)
|
||||
|
||||
}
|
||||
return err(e)
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export function SafeValidateSchema(schema: Schema, context: string) {
|
||||
return (
|
||||
target: unknown,
|
||||
propertyKey: string,
|
||||
descriptor: PropertyDescriptor,
|
||||
) => {
|
||||
const originalMethod = descriptor.value;
|
||||
descriptor.value = function (...args: unknown[]) {
|
||||
|
||||
const tracing: TracingType = args[args.length - 1] as any;
|
||||
|
||||
try {
|
||||
const model = schema.parse(args[0]);
|
||||
args[0] = model;
|
||||
return originalMethod.apply(this, args);
|
||||
} catch (e) {
|
||||
if (e instanceof ZodError) {
|
||||
// If validation fails, throw an error with the details
|
||||
//
|
||||
// If validation fails, throw an error with the details
|
||||
console.error('unexpected data structure', context)
|
||||
// Capture the Zod validation error with additional context
|
||||
console.error('Validation failed:', e.errors);
|
||||
|
||||
tracing?.setAttribute?.('APIReturn.error', 'true')
|
||||
|
||||
let i = 0;
|
||||
for(const schema of e.errors) {
|
||||
tracing?.setAttribute?.('map.error.schema-'+i, JSON.stringify(schema))
|
||||
}
|
||||
ColoredLoggerService.error(e.errors, 'socket unexpected data structure '+ context, schema._def.description)
|
||||
|
||||
}
|
||||
return originalMethod.apply(this, args);
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { CaptureLogService } from './capture-log.service';
|
||||
|
||||
describe('CaptureLogService', () => {
|
||||
let service: CaptureLogService;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({});
|
||||
service = TestBed.inject(CaptureLogService);
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -32,8 +32,3 @@ 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');
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -18,7 +18,6 @@ Device.getInfo().then(e => {
|
||||
device = e
|
||||
});
|
||||
|
||||
|
||||
const createTracingInstance = ({bugPrint, name, module, autoFinish}): TracingType => {
|
||||
const requestId = uuidv4()
|
||||
|
||||
@@ -59,6 +58,10 @@ const createTracingInstance = ({bugPrint, name, module, autoFinish}): TracingTyp
|
||||
setAttribute: (key: string, value: string) => {
|
||||
data.tags[key] = value;
|
||||
span.setAttribute(key, value);
|
||||
|
||||
if(key =='outcome' && value == 'failed') {
|
||||
span.setAttribute('error', 'true')
|
||||
}
|
||||
},
|
||||
getAttribute: (key: string) => {
|
||||
return data.tags[key]
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex header-bottom" >
|
||||
|
||||
|
||||
<div class="header-bottom-icon">
|
||||
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " src="assets/icon/icons-user.svg"></ion-icon>
|
||||
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " src="assets/icon/theme/gov/icons-user.svg"></ion-icon>
|
||||
@@ -42,8 +42,8 @@
|
||||
|
||||
<div class="messages height-100 width-100 d-flex flex-column" #scrollMe>
|
||||
|
||||
<div
|
||||
*ngFor="let message of roomMessage$ | async" class="messages-list-item-wrapper"
|
||||
<div
|
||||
*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}">
|
||||
{{ message.message }} == {{ message.id }}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user