send all file

This commit is contained in:
Peter Maquiran
2024-08-15 14:29:11 +01:00
parent bf50c923d1
commit 2aae4da3cd
9 changed files with 123 additions and 63 deletions
+7 -7
View File
@@ -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
View File
@@ -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": {
+5 -8
View File
@@ -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
View File
@@ -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
* ```
*/
+11
View File
@@ -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))
}
}