mirror of
https://code.equilibrium.co.ao/ITO/doneit-web.git
synced 2026-04-18 20:47:54 +00:00
send all file
This commit is contained in:
Generated
+7
-7
@@ -200,7 +200,7 @@
|
||||
"webpack": "^5.88.2",
|
||||
"wordcloud": "^1.1.2",
|
||||
"ws": "^7.5.9",
|
||||
"zod": "^3.22.2",
|
||||
"zod": "^3.23.8",
|
||||
"zone.js": "~0.11.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -44378,9 +44378,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/zod": {
|
||||
"version": "3.22.2",
|
||||
"resolved": "https://registry.npmjs.org/zod/-/zod-3.22.2.tgz",
|
||||
"integrity": "sha512-wvWkphh5WQsJbVk1tbx1l1Ly4yg+XecD+Mq280uBGt9wa5BKSWf4Mhp6GmrkPixhMxmabYY7RbzlwVP32pbGCg==",
|
||||
"version": "3.23.8",
|
||||
"resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz",
|
||||
"integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/colinhacks"
|
||||
}
|
||||
@@ -78365,9 +78365,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"zod": {
|
||||
"version": "3.22.2",
|
||||
"resolved": "https://registry.npmjs.org/zod/-/zod-3.22.2.tgz",
|
||||
"integrity": "sha512-wvWkphh5WQsJbVk1tbx1l1Ly4yg+XecD+Mq280uBGt9wa5BKSWf4Mhp6GmrkPixhMxmabYY7RbzlwVP32pbGCg=="
|
||||
"version": "3.23.8",
|
||||
"resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz",
|
||||
"integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g=="
|
||||
},
|
||||
"zone.js": {
|
||||
"version": "0.11.4",
|
||||
|
||||
+1
-1
@@ -217,7 +217,7 @@
|
||||
"webpack": "^5.88.2",
|
||||
"wordcloud": "^1.1.2",
|
||||
"ws": "^7.5.9",
|
||||
"zod": "^3.22.2",
|
||||
"zod": "^3.23.8",
|
||||
"zone.js": "~0.11.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import { z } from "zod";
|
||||
import { MessageAttachmentFileType, MessageAttachmentSource } from "../../data/dto/message/messageOutputDTO";
|
||||
import { SafeResourceUrl } from "@angular/platform-browser";
|
||||
import { base64Schema } from "src/app/utils/zod";
|
||||
|
||||
const MessageEntitySchema = z.object({
|
||||
export const MessageEntitySchema = z.object({
|
||||
$id: z.any().optional(),
|
||||
id: z.string().optional(),
|
||||
roomId: z.string().uuid(),
|
||||
message: z.string(),
|
||||
roomId: z.string(),
|
||||
message: z.string().optional(),
|
||||
messageType: z.number(),
|
||||
canEdit: z.boolean(),
|
||||
oneShot: z.boolean(),
|
||||
@@ -22,15 +23,11 @@ const MessageEntitySchema = z.object({
|
||||
attachments: z.array(z.object({
|
||||
fileType: z.nativeEnum(MessageAttachmentFileType),
|
||||
source: z.nativeEnum(MessageAttachmentSource),
|
||||
file: z.string().optional(),
|
||||
file: base64Schema.optional(),
|
||||
fileName: z.string().optional(),
|
||||
applicationId: z.string().optional(),
|
||||
docId: z.string().optional()
|
||||
})),
|
||||
attachmentsSource: z.array(z.object({
|
||||
file: z.string(),
|
||||
id: z.string(),
|
||||
})),
|
||||
})
|
||||
|
||||
type Message = z.infer<typeof MessageEntitySchema>;
|
||||
|
||||
@@ -48,6 +48,6 @@ export class MessageAttachmentByMessageIdUseCase {
|
||||
return dataUrl
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { MessageEntity } from '../entity/message';
|
||||
import { MessageEntity, MessageEntitySchema, } from '../entity/message';
|
||||
import { MessageRepositoryService } from "src/app/module/chat/data/repository/message-respository.service"
|
||||
import { AttachmentRepositoryService } from "src/app/module/chat/data/repository/attachment-repository.service"
|
||||
import { z } from 'zod';
|
||||
import { z, ZodError } from 'zod';
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import { InstanceId } from '../chat-service.service';
|
||||
import { createDataURL } from 'src/app/utils/ToBase64';
|
||||
import { DomSanitizer } from '@angular/platform-browser';
|
||||
import { zodSafeValidation } from 'src/app/utils/zodValidation';
|
||||
|
||||
const MessageInputUseCaseSchema = z.object({
|
||||
memberId: z.number(),
|
||||
@@ -24,48 +25,61 @@ export class MessageCreateUseCaseService {
|
||||
constructor(
|
||||
private MessageRepositoryService: MessageRepositoryService,
|
||||
private AttachmentRepositoryService: AttachmentRepositoryService,
|
||||
private sanitizer: DomSanitizer
|
||||
private sanitizer: DomSanitizer,
|
||||
) { }
|
||||
|
||||
|
||||
async execute(message: MessageEntity) {
|
||||
|
||||
message.sendAttemp++;
|
||||
const validation = zodSafeValidation<MessageEntity>(MessageEntitySchema, message)
|
||||
|
||||
message.requestId = InstanceId +'@'+ uuidv4();
|
||||
if(validation.isOk()) {
|
||||
message.sendAttemp++;
|
||||
|
||||
const createMessageLocally = await this.MessageRepositoryService.createMessageLocally(message)
|
||||
message.requestId = InstanceId +'@'+ uuidv4();
|
||||
|
||||
if(createMessageLocally.isOk()) {
|
||||
const createMessageLocally = await this.MessageRepositoryService.createMessageLocally(message)
|
||||
|
||||
console.log('==========================',message);
|
||||
if(message.hasAttachment) {
|
||||
if(createMessageLocally.isOk()) {
|
||||
|
||||
for (const attachment of message.attachments) {
|
||||
console.log('==========================',message);
|
||||
if(message.hasAttachment) {
|
||||
|
||||
const createAttachmentLocally = this.AttachmentRepositoryService.create({
|
||||
$messageId: createMessageLocally.value.$id,
|
||||
file: createDataURL(attachment.file, attachment.mimeType)
|
||||
})
|
||||
for (const attachment of message.attachments) {
|
||||
|
||||
const createAttachmentLocally = this.AttachmentRepositoryService.create({
|
||||
$messageId: createMessageLocally.value.$id,
|
||||
file: createDataURL(attachment.file, attachment.mimeType)
|
||||
})
|
||||
|
||||
attachment.safeFile = createDataURL(attachment.file, attachment.mimeType)
|
||||
}
|
||||
|
||||
attachment.safeFile = createDataURL(attachment.file, attachment.mimeType)
|
||||
}
|
||||
|
||||
const sendToServer = await this.MessageRepositoryService.sendMessage(message)
|
||||
|
||||
|
||||
if(!sendToServer.isOk()) {
|
||||
console.log('sendToServer error', sendToServer.error)
|
||||
}
|
||||
|
||||
|
||||
return sendToServer
|
||||
}
|
||||
|
||||
const sendToServer = await this.MessageRepositoryService.sendMessage(message)
|
||||
const result = await this.MessageRepositoryService.sendMessage(message)
|
||||
|
||||
return result
|
||||
} else {
|
||||
|
||||
if(!sendToServer.isOk()) {
|
||||
console.log('sendToServer error', sendToServer.error)
|
||||
if(validation.error.formErrors.fieldErrors.attachments) {
|
||||
console.log(message.attachments)
|
||||
console.error('invalid attachment', validation.error.formErrors.fieldErrors.attachments)
|
||||
}
|
||||
|
||||
|
||||
return sendToServer
|
||||
}
|
||||
|
||||
const result = await this.MessageRepositoryService.sendMessage(message)
|
||||
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
</div>
|
||||
|
||||
<div *ngFor="let attachment of message.attachments; let i = index">
|
||||
<div *ngIf="attachment.fileType == 1">
|
||||
<div *ngIf="attachment.source == MessageAttachmentFileSource.Webtrix">
|
||||
|
||||
<ion-icon src="assets/icon/webtrix.svg" class="file-icon font-25"></ion-icon>
|
||||
<ion-label>{{ attachment.fileName}}</ion-label>
|
||||
@@ -66,10 +66,33 @@
|
||||
|
||||
</div>
|
||||
|
||||
<div *ngIf="attachment.fileType == 2">
|
||||
<div *ngIf="attachment.fileType == MessageAttachmentFileType.Image">
|
||||
<img [src]="attachment.safeFile">
|
||||
</div>
|
||||
|
||||
<div *ngIf="attachment.fileType == MessageAttachmentFileType.Audio">
|
||||
<audio controls>
|
||||
<source [src]="attachment.safeFile" >
|
||||
Your browser does not support the audio element.
|
||||
</audio>
|
||||
</div>
|
||||
|
||||
<div *ngIf="attachment.fileType == MessageAttachmentFileType.Doc">
|
||||
<fa-icon *ngIf="attachment.mimeType == 'application/pdf'" icon="file-pdf" class="pdf-icon"></fa-icon>
|
||||
<fa-icon *ngIf="attachment.mimeType == 'application/word'" icon="file-word" class="word-icon">
|
||||
</fa-icon>
|
||||
<fa-icon *ngIf="attachment.mimeType == 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'" icon="file-word" class="word-icon"></fa-icon>
|
||||
<fa-icon
|
||||
*ngIf="attachment.mimeType == 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'"
|
||||
icon="file-word" class="excel-icon"></fa-icon>
|
||||
<ion-icon *ngIf="attachment.mimeType == 'application/webtrix'" src="assets/icon/webtrix.svg">
|
||||
</ion-icon>
|
||||
<ion-icon *ngIf="attachment.mimeType == 'application/meeting'" src="assets/icon/webtrix.svg">
|
||||
</ion-icon>
|
||||
|
||||
<ion-label>{{ attachment.fileName}}</ion-label>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -137,6 +137,8 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
|
||||
messageSendSubject: Subscription
|
||||
|
||||
messages1: {[key: string]: MessageEntity[]} = {}
|
||||
MessageAttachmentFileType = MessageAttachmentFileType
|
||||
MessageAttachmentFileSource = MessageAttachmentSource
|
||||
|
||||
constructor(
|
||||
public popoverController: PopoverController,
|
||||
@@ -875,7 +877,7 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
|
||||
}
|
||||
message.attachments = [{
|
||||
fileName: res.data.selected.Assunto,
|
||||
source: MessageAttachmentSource.Webtrix,
|
||||
source: MessageAttachmentSource.Device,
|
||||
fileType: MessageAttachmentFileType.Doc,
|
||||
applicationId: res.data.selected.ApplicationType,
|
||||
docId: res.data.selected.Id,
|
||||
@@ -927,7 +929,7 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
|
||||
}
|
||||
|
||||
message.attachments = [{
|
||||
file: file.value.base64String,
|
||||
file: file.value.base64String.split(',')[1],
|
||||
fileName: "foto",
|
||||
source: MessageAttachmentSource.Device,
|
||||
fileType: MessageAttachmentFileType.Image,
|
||||
@@ -984,7 +986,7 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
|
||||
}
|
||||
|
||||
message.attachments = [{
|
||||
file: fileBase64.value,
|
||||
file: fileBase64.value.split(',')[1],
|
||||
fileName: file.value.name,
|
||||
source: MessageAttachmentSource.Device,
|
||||
fileType: MessageAttachmentFileType.Doc,
|
||||
|
||||
+32
-19
@@ -23,28 +23,41 @@ export const zodDataUrlSchema = z.string().refine(value => zodDataUrlRegex.test(
|
||||
message: 'Invalid data URL',
|
||||
});
|
||||
|
||||
|
||||
//===============================================================================
|
||||
/**
|
||||
* Validates if a string is a valid data URL.
|
||||
* A schema for validating Base64 encoded strings.
|
||||
*
|
||||
* @param url - The string to validate as a data URL.
|
||||
* @returns {void} - Logs the result of the validation.
|
||||
* This schema checks if the string is valid Base64 and ensures that the first 20 characters
|
||||
* do not contain a comma.
|
||||
*
|
||||
* @example
|
||||
* validateDataUrl('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDCAAAAC0BEMAAW9R3AAAAAElFTkSuQmCC');
|
||||
* // Output: Valid data URL: data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDCAAAAC0BEMAAW9R3AAAAAElFTkSuQmCC
|
||||
*
|
||||
* validateDataUrl('invalid-url');
|
||||
* // Output: Validation error: [ ... ]
|
||||
* ```typescript
|
||||
* const validString = 'SGVsbG8sIHdvcmxkIQ=='; // Base64 for "Hello, world!"
|
||||
* const invalidString = 'SGVsbG8sIHdvcmxkIQ,,=='; // Invalid due to commas
|
||||
*
|
||||
* console.log(base64Schema.safeParse(validString).success); // true
|
||||
* console.log(base64Schema.safeParse(invalidString).success); // false
|
||||
* ```
|
||||
*/
|
||||
const validateDataUrl = (url: string) => {
|
||||
const result: any = zodDataUrlSchema.safeParse(url);
|
||||
if (result.success) {
|
||||
console.log('Valid data URL:', url);
|
||||
} else {
|
||||
console.error('Validation error:', result.error.errors);
|
||||
}
|
||||
};
|
||||
export const base64Schema = z.string().refine(value => {
|
||||
// Regular expression for Base64 validation
|
||||
const isBase64 = /^[A-Za-z0-9+/=]*$/.test(value) && (value.length % 4 === 0);
|
||||
// Check if the first 20 characters do not contain a comma
|
||||
return isBase64 && !value.substring(0, 20).includes(',');
|
||||
}, {
|
||||
message: 'Invalid Base64 string or comma found in the first 20 characters'
|
||||
});
|
||||
|
||||
// Test the schema
|
||||
validateDataUrl('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDCAAAAC0BEMAAW9R3AAAAAElFTkSuQmCC');
|
||||
validateDataUrl('invalid-url');
|
||||
/**
|
||||
* Validates a given string against the Base64 schema.
|
||||
*
|
||||
* @param input - The string to validate.
|
||||
* @returns `true` if the input is valid according to the schema, `false` otherwise.
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* console.log(validateInput('SGVsbG8sIHdvcmxkIQ==')); // true
|
||||
* console.log(validateInput('SGVsbG8sIHdvcmxkIQ,,==')); // false
|
||||
* ```
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
import { err, ok } from 'neverthrow';
|
||||
import { ZodError, ZodSchema, z } from 'zod';
|
||||
export function zodSafeValidation<T>(schema: ZodSchema, data) {
|
||||
const validation = (schema as ZodSchema<T>).safeParse(data)
|
||||
|
||||
if(validation.success) {
|
||||
return ok(validation.data)
|
||||
} else {
|
||||
return err((validation.error))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user