imporve attendie and add video upload

This commit is contained in:
Peter Maquiran
2024-01-06 20:37:49 +01:00
parent 15e9b312e3
commit eb790266f1
21 changed files with 657 additions and 165 deletions
+1
View File
@@ -395,6 +395,7 @@
[adding]="adding"
[taskParticipants]="taskParticipants"
[taskParticipantsCc]="taskParticipantsCc"
[hideExternalDomain]="false"
(setIntervenient)="setIntervenient($event)"
(setIntervenientCC)="setIntervenientCC($event)"
>
@@ -97,7 +97,7 @@ export class NewEventPage implements OnInit {
environment = environment
eventPersons: EventPerson[];
contacts: EventPerson[];
constructor(
private modalController: ModalController,
@@ -552,6 +552,7 @@ export class NewEventPage implements OnInit {
const modal = await this.modalController.create({
component: AttendeesPageModal,
componentProps: {
hideExternalDomain: false,
adding: this.adding,
taskParticipants: this.taskParticipants,
taskParticipantsCc: this.taskParticipantsCc
@@ -26,6 +26,7 @@ export class AttendeesPageModal implements OnInit {
taskParticipantsCc:EventPerson[] = [];
loggeduser: LoginUserRespose;
@Input() loggedAttendSon: boolean;
hideExternalDomain = true;
taskType: any;
@@ -41,6 +42,7 @@ export class AttendeesPageModal implements OnInit {
this.taskParticipants = this.navParams.get('taskParticipants');
this.taskParticipantsCc = this.navParams.get('taskParticipantsCc');
this.taskType = this.navParams.get('taskType');
this.hideExternalDomain = this.navParams.get('hideExternalDomain');
this.loggeduser = SessionStore.user;
@@ -134,8 +136,15 @@ export class AttendeesPageModal implements OnInit {
async fetchContacts(filter: string) {
this.showLoader = true;
this.contactsService.getContacts(filter).subscribe(result =>
{
this.contactsService.getContacts(filter).subscribe(_result => {
let result
if(this.hideExternalDomain) {
result = _result.filter( e => e.UserType == 'GD')
} else {
result = _result
}
if (this.eventPersons != null)
{
this.eventPersons.forEach(attendee => {
@@ -72,7 +72,7 @@ export class EditEventPage implements OnInit {
else{
this.pageId = paramMap.get('eventId');
eventid = paramMap.get('eventId');
}
if (paramMap.has("caller")){
@@ -89,6 +89,7 @@ export class EditEventPage implements OnInit {
const modal = await this.modalCtrl.create({
component: AttendeesPageModal,
componentProps: {
hideExternalDomain: false,
eventAttendees: this.loadedEvent.Attendees
},
cssClass: 'attendee modal-desktop',
@@ -165,7 +166,7 @@ export class EditEventPage implements OnInit {
this.activatedRoute.paramMap.subscribe(paramMap =>{
if (paramMap.has("profile")){
}
});
@@ -193,7 +194,7 @@ export class EditEventPage implements OnInit {
{
this.attachamentsService.getAttachmentsById(this.pageId).subscribe(res => {
this.loadedEventAttachments = res;
},((erro) => {
console.error('loadAttchament', erro)
@@ -26,6 +26,7 @@ export class AttendeesPageModal implements OnInit {
taskParticipantsCc:EventPerson[] = [];
loggeduser: LoginUserRespose;
@Input() loggedAttendSon: boolean;
@Input() hideExternalDomain = true;
taskType: any;
@@ -133,8 +134,17 @@ export class AttendeesPageModal implements OnInit {
async fetchContacts(filter: string) {
this.showLoader = true;
this.contactsService.getContacts(filter).subscribe(result =>
this.contactsService.getContacts(filter).subscribe(_result =>
{
let result
if(this.hideExternalDomain) {
result = _result.filter( e => e.UserType == 'GD')
} else {
result = _result
}
if (this.eventPersons != null)
{
this.eventPersons.forEach(attendee => {
+6 -30
View File
@@ -11,41 +11,17 @@ export class HttpServiceService {
constructor(private http: HttpClient) {}
put<T>(url: string, body: any | null, options: Options): Observable<T> {
return this.http.put(url, body, options as any).pipe(
tap((response) => {
// Handle success response if needed
}),
catchError((error) => {
// Handle error response if needed
return of(error);
})
);
put<T>(url: string, body: any | null, options: Options) {
return this.http.put<T>(url, body, options as any)
}
post<T>(url: string, body: any | null, options: Options): Observable<T> {
return this.http.post(url, body, options as any).pipe(
tap((response) => {
// Handle success response if needed
}),
catchError((error) => {
// Handle error response if needed
return of(error);
})
);
post<T>(url: string, body: any | null, options: Options) {
return this.http.post<T>(url, body, options as any)
}
get<T>(url: string, options: Options): Observable<T> {
return this.http.get(url, options ).pipe(
tap((response) => {
// Handle success response if needed
}),
catchError((error) => {
// Handle error response if needed
return of(error);
})
);
get<T>(url: string, options: Options) {
return this.http.get<T>(url, options )
}
}
@@ -3,7 +3,7 @@ import { environment } from 'src/environments/environment';
import { HttpServiceService } from 'src/app/services/http/http-service.service';
import { Observable} from 'rxjs';
import { CreateEvent, EditEvent, EventDetailsDTO, EventsDTO, refreshTokenDTO } from "./interface";
import { HttpParams } from '@angular/common/http';
import { HttpHeaders, HttpParams } from '@angular/common/http';
import { DetectCalendars, makeHeaderForCalendar } from '../../utils/utils';
import { z } from "zod";
import { ok, err } from 'neverthrow';
@@ -18,14 +18,16 @@ export class MiddlewareServiceService {
constructor(
private HttpServiceService: HttpServiceService,
) {}
) {
window["MiddlewareServiceService"] = this
}
refreshToken(refreshToken: string): Observable<refreshTokenDTO> {
refreshToken(refreshToken: string){
const data = {
refreshToken: refreshToken
}
return this.HttpServiceService.put(environment.apiURL + "UserAuthentication/RefreshToken", data, {})
return this.HttpServiceService.put<refreshTokenDTO>(environment.apiURL + "UserAuthentication/RefreshToken", data, {})
// .pipe(
// map((response: HttpResponse<refreshToken>) => {
// return response.body
@@ -134,4 +136,22 @@ export class MiddlewareServiceService {
}
// ================================ Acções =================================================
// ========== LKFRT
uploadFileLK(formData: FormData) {
const headers = new HttpHeaders();
headers.set('Authorization', 'Bearer ' + SessionStore.user.Authorization);
//const geturl = environment.apiURL + 'Tasks/DelegateTask';
const geturl = environment.apiURL + 'ObjectServer/UploadFiles';
let options = {
headers: headers
};
return this.HttpServiceService.post(`${geturl}`, formData, options);
}
}
@@ -32,6 +32,9 @@ export class AttendeePage implements OnInit {
@Output() dynamicSetIntervenient = new EventEmitter<any>();
@Input() hideExternalDomain = true;
@Input() taskParticipants: EventPerson[] = [];
@Input() taskParticipantsCc: EventPerson[] = [];
@Input() loggedAttendSon: boolean;
@@ -231,7 +234,15 @@ export class AttendeePage implements OnInit {
async fetchContacts(filter: string) {
this.showLoader = true;
this.contactsService.getContacts(filter).subscribe(result => {
this.contactsService.getContacts(filter).subscribe(_result => {
let result
if(this.hideExternalDomain) {
result = _result.filter( e => e.UserType == 'GD')
} else {
result = _result
}
if (this.eventPersons != null) {
this.eventPersons.forEach(attendee => {
const index: number = result.findIndex((cont) => {
@@ -0,0 +1,16 @@
import { TestBed } from '@angular/core/testing';
import { PublicationAttachmentEntityService } from './publication-attachment-entity.service';
describe('PublicationAttachmentEntityService', () => {
let service: PublicationAttachmentEntityService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(PublicationAttachmentEntityService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});
@@ -0,0 +1,31 @@
export class PublicationAttachmentEntityService {
FileBase64: string
FileExtension: string
FileType: 'image' | 'video'
OriginalFileName: string
blob: any
constructor({base64, extension, blob = null, OriginalFileName = null, FileType}) {
this.FileBase64 = base64;
this.FileExtension = extension;
this.blob = blob
this.OriginalFileName = OriginalFileName
this.FileType = FileType
this.fixFileBase64();
}
fixFileBase64() {
if(this.FileType == 'image' ) {
if(!this.FileBase64.startsWith('data:')) {
this.FileBase64 = 'data:image/jpg;base64,' + this.FileBase64
}
} else if (this.FileType == 'video' ) {
if(!this.FileBase64.startsWith('data:')) {
this.FileBase64 = 'data:video/mp4;base64,' + this.FileBase64
}
}
}
}
@@ -0,0 +1,16 @@
import { TestBed } from '@angular/core/testing';
import { PublicationFormModelService } from './publication-form-model.service';
describe('PublicationFormModelService', () => {
let service: PublicationFormModelService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(PublicationFormModelService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});
@@ -0,0 +1,22 @@
import { Injectable } from '@angular/core';
import { IPublicationFormModelEntity } from '../../interface/interface';
import { PublicationAttachmentEntityService } from "./publication-attachment-entity.service"
@Injectable({
providedIn: 'root'
})
export class PublicationFormModelService {
constructor() {}
DateIndex: any;
DocumentId: any;
ProcessId: any;
Title: any;
Message: any;
DatePublication: any;
OriginalFileName: string;
Files: PublicationAttachmentEntityService[];
setData(data: IPublicationFormModelEntity) {
Object.assign(this, data)
}
}
@@ -0,0 +1,16 @@
import { TestBed } from '@angular/core/testing';
import { PublicationFromMVService } from './publication-from-mv.service';
describe('PublicationFromMVService', () => {
let service: PublicationFromMVService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(PublicationFromMVService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});
@@ -0,0 +1,39 @@
import { Injectable } from '@angular/core';
import { UploadFileUserCaseService } from "src/app/shared/publication/new-publication/usercase/upload-file-user-case.service"
import { IPublicationFormModelEntity } from '../interface/interface';
import { PublicationFormModelService } from "./model/publication-form-model.service"
import { PublicationAttachmentEntityService } from './model/publication-attachment-entity.service';
@Injectable({
providedIn: 'root'
})
export class PublicationFromMVService {
constructor(
public UploadFileUserCaseService: UploadFileUserCaseService,
public form: PublicationFormModelService) {}
setDataToFrom(data: IPublicationFormModelEntity) {
this.form.setData(data)
}
private getVideoFiles() {
return this.form.Files.filter( x => x.FileType == 'video')
}
private async upload(PublicationAttachmentEntity: PublicationAttachmentEntityService) {
console.log(PublicationAttachmentEntity)
this.UploadFileUserCaseService.execute(PublicationAttachmentEntity)
}
uploadVideosFiles() {
const videosFiles = this.getVideoFiles()
console.log(this.form)
for(const file of videosFiles) {
this.upload(file)
}
}
}
@@ -0,0 +1,18 @@
export interface IPublicationFormModelEntity {
DateIndex: any
DocumentId: any
ProcessId: any
Title: any
Message: any
DatePublication: any
Files: PublicationAttachmentEntity[]
}
export class IPublicationAttachmentEntity {
FileBase64: string
FileExtension: string
FileType: 'image' | 'video'
OriginalFileName: string
blob: any
}
@@ -47,18 +47,20 @@
<ion-thumbnail *ngFor="let seleted of seletedContent.slice(0, displayLimit), let i = index" (click)="deleteFromSeletedContent(i)" lot="start">
<ion-img *ngIf="checkFileType.checkFileType(seleted.FileExtension) == 'image'"
name="image" ngDefaultControl [src]="'data:image/jpg;base64,' + seleted.FileBase64"></ion-img>
name="image" ngDefaultControl [src]="seleted.FileBase64"></ion-img>
<video *ngIf="checkFileType.checkFileType(seleted.FileExtension) == 'video'" width="70" height="70"
controls="controls" preload="metadata" autoplay="autoplay" webkit-playsinline="webkit-playsinline">
<source type="video/mp4" [src]="'data:video/mp4;base64,' + seleted.FileBase64">
preload="metadata" webkit-playsinline="webkit-playsinline">
<source type="video/mp4" [src]="seleted.FileBase64">
</video>
</ion-thumbnail>
<!-- Display the blurred image and count if there are more images -->
<ion-thumbnail *ngIf="seletedContent.length > displayLimit" lot="start">
<ion-img [src]="'data:image/jpg;base64,' + seletedContent[displayLimit - 1].base64"
<ion-img [src]="'data:image/jpg;base64,' + seletedContent[displayLimit - 1].FileBase64"
style="filter: blur(5px);"></ion-img>
<p>mais {{ seletedContent.length - displayLimit }}</p>
@@ -1,8 +1,6 @@
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { SafeResourceUrl } from '@angular/platform-browser';
import { PublicationsService } from 'src/app/services/publications.service';
import { Publication } from 'src/app/models/publication';
import { Image } from 'src/app/models/image';
import { PhotoService } from 'src/app/services/photo.service';
import { ToastService } from 'src/app/services/toast.service';
import { FormControl, FormGroup, Validators } from '@angular/forms';
@@ -11,10 +9,17 @@ import { Camera, CameraResultType, CameraSource } from '@capacitor/camera';
import { HttpErrorHandle } from 'src/app/services/http-error-handle.service';
import { PublicationFolderService } from 'src/app/store/publication-folder.service';
import { FilePicker } from '@capawesome/capacitor-file-picker';
import { Directory, Encoding, Filesystem } from '@capacitor/filesystem';
import { utf8Encode } from '@angular/compiler/src/util';
import { checkFileTypeService } from 'src/app/services/checkFileType.service';
import { FileValidatorService } from "src/app/services/file/file-validator.service"
import { MiddlewareServiceService } from "src/app/shared/API/middleware/middleware-service.service"
import { LakefsRepositoryService } from '../../repository/lakefs/lakefs-repository.service';
enum ActionType {
newRapid = "1",
new = "2",
edit = "3"
}
@Component({
selector: 'app-new-publication',
@@ -33,7 +38,6 @@ export class NewPublicationPage implements OnInit {
Form: FormGroup;
validateFrom = false
@Input() publication!: Publication;
@Input() publicationType: string;
@Input() folderId: string;
@@ -51,10 +55,13 @@ export class NewPublicationPage implements OnInit {
fileType: string;
filecontent: boolean;
captureContent: any;
seletedContent: any[] = []
seletedContent: PublicationAttachmentEntity[] = []
displayLimit = 4;
filesSizeSum = 0;
publicationFormMV = new PublicationFormMV()
constructor(
public photoService: PhotoService,
private publications: PublicationsService,
@@ -63,16 +70,16 @@ export class NewPublicationPage implements OnInit {
private httpErroHandle: HttpErrorHandle,
public PublicationFolderService: PublicationFolderService,
public checkFileType: checkFileTypeService,
private FileValidatorService: FileValidatorService
private FileValidatorService: FileValidatorService,
private MiddlewareServiceService: MiddlewareServiceService,
private LakefsRepositoryService: LakefsRepositoryService
) {
this.publicationTitle = 'Nova Publicação';
if (this.publication) {
this.seletedContent = this.publication.Files;
this.filecontent = true;
}
}
ngOnInit() {
@@ -93,7 +100,6 @@ export class NewPublicationPage implements OnInit {
this.setData()
}
setData() {
if (!this.publicationType) {
setTimeout(() => {
@@ -106,10 +112,9 @@ export class NewPublicationPage implements OnInit {
}
}
getPublicationDetail() {
console.log('edit 1', this.publicationType)
if (this.publicationType != '2') {
if (this.publicationType != ActionType.new) {
this.showLoader = true;
this.publications.GetPublicationWithArrayOfFilesById(this.documentId).subscribe(res => {
this.publication = {
@@ -133,8 +138,6 @@ export class NewPublicationPage implements OnInit {
this.goBack()
});
}
}
async takePicture() {
@@ -159,7 +162,20 @@ export class NewPublicationPage implements OnInit {
FileBase64: picture,
FileExtension: this.removeTextBeforeSlash('jpeg','/')
}
this.seletedContent.push(fileObject)
const FileExtension = this.removeTextBeforeSlash('jpeg','/')
const newAttachment = new PublicationAttachmentEntity(
{
base64: picture,
extension: FileExtension,
OriginalFileName: "foto",
FileType: 'image'
}
)
this.seletedContent.push(newAttachment)
});
/* } else {
this.toastService._badRequest("Imagem inválida")
@@ -188,7 +204,19 @@ export class NewPublicationPage implements OnInit {
FileBase64: picture,
FileExtension: this.removeTextBeforeSlash('jpeg','/')
}
this.seletedContent.push(fileObject)
const FileExtension = this.removeTextBeforeSlash('jpeg','/')
const newAttachment = new PublicationAttachmentEntity(
{
base64: picture,
extension: FileExtension,
OriginalFileName: "foto",
FileType: 'image'
}
)
this.seletedContent.push(newAttachment)
});
}
@@ -200,20 +228,25 @@ export class NewPublicationPage implements OnInit {
multiple: true,
});
result.files.forEach(async element => {
console.log(element)
if(this.checkFileType.checkFileType(element.mimeType) == 'image' || this.checkFileType.checkFileType(element.mimeType) == 'video') {
this.convertBlobToBase64(element.blob).then((value) => {
this.filesSizeSum = this.filesSizeSum + element.size
this.filesSizeSum = this.filesSizeSum + element.size
if(this.fileSizeToMB(this.filesSizeSum) <= 20) {
let fileObject = {
FileBase64: value,
FileExtension: this.removeTextBeforeSlash(element.mimeType,'/')
}
this.seletedContent.push(fileObject)
const FileExtension = this.removeTextBeforeSlash(element.mimeType,'/')
const newAttachment = new PublicationAttachmentEntity(
{
base64: value,
extension: FileExtension,
blob: element.blob,
FileType: 'video'
}
)
this.seletedContent.push(newAttachment)
this.filecontent = true;
} else {
if(this.seletedContent.length === 0)
@@ -225,7 +258,7 @@ export class NewPublicationPage implements OnInit {
} else {
this.httpErroHandle.validationMessagge('filetype');
}
});
/* this.capturedImage = 'data:image/jpeg;base64,' +capturedImage.base64String;
@@ -282,7 +315,7 @@ export class NewPublicationPage implements OnInit {
}
if (this.publicationType == '3') {
if (this.publicationType == ActionType.edit) {
if (!this.publication?.OriginalFileName || !this.pub.OriginalFileName) {
@@ -328,7 +361,7 @@ export class NewPublicationPage implements OnInit {
}
} else {
}/*
}/*
else if (!this.PublicationFolderService.PublicationHasImage(this.publication)) { //
this.publication = {
@@ -373,27 +406,12 @@ export class NewPublicationPage implements OnInit {
Files: this.seletedContent,
}
const loader = this.toastService.loading()
this.publicationFormMV.setDataToFrom(this.publication)
this.publicationFormMV.uploadVideosFiles();
try {
await this.publications.CreatePublication(this.publication.ProcessId, this.publication).toPromise()
if (this.publicationTitle == '1') {
} else if (this.publicationTitle == '2') {
this.httpErroHandle.httpsSucessMessagge('Criar publicação')
} else if (this.publicationTitle == '3') {
this.httpErroHandle.httpsSucessMessagge('Editar publicação')
}
this.goBackToViewPublications.emit();
} catch (error) {
this.httpErroHandle.httpStatusHandle(error)
} finally {
loader.remove()
}
} else {
}
}
@@ -414,13 +432,13 @@ export class NewPublicationPage implements OnInit {
}
setTitle() {
if (this.publicationType == '1') {
if (this.publicationType == ActionType.newRapid) {
this.publicationTitle = 'Nova Publicação Rápida';
}
else if (this.publicationType == '2') {
else if (this.publicationType == ActionType.new) {
this.publicationTitle = 'Nova Publicação';
}
else if (this.publicationType == '3') {
else if (this.publicationType == ActionType.edit) {
this.publicationTitle = 'Editar Publicação';
this.pub = this.publication;
}
@@ -428,7 +446,7 @@ export class NewPublicationPage implements OnInit {
async goBack() {
if (this.publicationType == '2') {
if (this.publicationType == ActionType.new) {
this.goBackToViewPublications.emit();
} else {
this.goBackToViewPublications.emit();
@@ -500,55 +518,55 @@ export class NewPublicationPage implements OnInit {
// Decode the base64 video string to an ArrayBuffer
const trimmedBase64 = base64String.trim();
const videoBuffer = this.base64ToArrayBuffer(this.removeTextBeforeSlash(trimmedBase64, ','));
// Create a Blob from the ArrayBuffer
const videoBlob = new Blob([videoBuffer], { type: 'video/mp4' });
// Create an object URL from the Blob
const videoObjectUrl = URL.createObjectURL(videoBlob);
// Create a video element
const video = document.createElement('video');
video.src = videoObjectUrl;
// Wait for the video to load metadata
video.addEventListener('loadedmetadata', async () => {
const canvas = document.createElement('canvas');
let newWidth = video.videoWidth;
let newHeight = video.videoHeight;
if (newWidth > maxWidth) {
newHeight *= maxWidth / newWidth;
newWidth = maxWidth;
}
if (newHeight > maxHeight) {
newWidth *= maxHeight / newHeight;
newHeight = maxHeight;
}
canvas.width = newWidth;
canvas.height = newHeight;
const context = canvas.getContext('2d');
// Start continuous rendering
function render() {
context?.drawImage(video, 0, 0, newWidth, newHeight);
requestAnimationFrame(render);
}
render();
// Convert the canvas to a Blob
canvas.toBlob(async (blob) => {
if (blob) {
// Read the Blob as an ArrayBuffer
const compressedVideoBuffer = await this.readBlobAsArrayBuffer(blob);
// Convert the ArrayBuffer back to base64
const compressedBase64 = this.arrayBufferToBase64(compressedVideoBuffer);
resolve(compressedBase64);
} else {
reject('Error creating compressed video blob.');
@@ -560,7 +578,7 @@ export class NewPublicationPage implements OnInit {
}
});
}
/* async compressVideoBase64(base64String: string, maxWidth: number, maxHeight: number, quality: number): Promise<string> {
@@ -568,147 +586,147 @@ export class NewPublicationPage implements OnInit {
try {
// Decode the base64 video string to an ArrayBuffer
const videoBuffer = this.base64ToArrayBuffer(this.removeTextBeforeSlash(base64String,','));
// Create a Blob from the ArrayBuffer
const videoBlob = new Blob([videoBuffer], { type: 'video/mp4' });
// Create an object URL from the Blob
const videoObjectUrl = URL.createObjectURL(videoBlob);
// Create a video element
const video = document.createElement('video');
// Create a source element and set its type attribute
const source = document.createElement('source');
source.type = 'video/mp4';
// Set the source URL
source.src = videoObjectUrl;
// Append the source element to the video element
video.appendChild(source);
// Wait for the video to load
video.addEventListener('loadedmetadata', async () => {
const canvas = document.createElement('canvas');
let newWidth = video.videoWidth;
let newHeight = video.videoHeight;
if (newWidth > maxWidth) {
newHeight *= maxWidth / newWidth;
newWidth = maxWidth;
}
if (newHeight > maxHeight) {
newWidth *= maxHeight / newHeight;
newHeight = maxHeight;
}
canvas.width = newWidth;
canvas.height = newHeight;
const context = canvas.getContext('2d');
// Create a function to draw each video frame onto the canvas
const drawFrame = () => {
context?.drawImage(video, 0, 0, newWidth, newHeight);
// Convert the canvas to a Blob with the correct MIME type
canvas.toBlob(async (blob) => {
if (blob) {
// Read the Blob as an ArrayBuffer
const compressedVideoBuffer = await this.readBlobAsArrayBuffer(blob);
// Convert the ArrayBuffer back to base64
const compressedBase64 = this.arrayBufferToBase64(compressedVideoBuffer);
resolve(compressedBase64);
} else {
reject('Error creating compressed video blob.');
}
}, 'video/mp4', quality);
// Request the next video frame
requestAnimationFrame(drawFrame);
};
// Start drawing frames
drawFrame();
// Start playing the video
video.play();
});
} catch (error) {
reject(error);
}
});
} */
/* async compressVideoBase64(base64String: string, maxWidth: number, maxHeight: number, quality: number): Promise<string> {
return new Promise(async (resolve, reject) => {
try {
// Decode the base64 video string to an ArrayBuffer
const videoBuffer = this.base64ToArrayBuffer(this.removeTextBeforeSlash(base64String,','));
// Create a Blob from the ArrayBuffer
const videoBlob = new Blob([videoBuffer], { type: 'video/mp4' });
// Create an object URL from the Blob
const videoObjectUrl = URL.createObjectURL(videoBlob);
// Create a video element
const video = document.createElement('video');
video.src = videoObjectUrl;
// Wait for the video to load metadata
video.addEventListener('loadedmetadata', async () => {
const canvas = document.createElement('canvas');
let newWidth = video.videoWidth;
let newHeight = video.videoHeight;
if (newWidth > maxWidth) {
newHeight *= maxWidth / newWidth;
newWidth = maxWidth;
}
if (newHeight > maxHeight) {
newWidth *= maxHeight / newHeight;
newHeight = maxHeight;
}
canvas.width = newWidth;
canvas.height = newHeight;
const context = canvas.getContext('2d');
context?.drawImage(video, 0, 0, newWidth, newHeight);
// Convert the canvas to a Blob with the correct MIME type
canvas.toBlob(async (blob) => {
if (blob) {
// Read the Blob as an ArrayBuffer
const compressedVideoBuffer = await this.readBlobAsArrayBuffer(blob);
// Convert the ArrayBuffer back to base64
const compressedBase64 = this.arrayBufferToBase64(compressedVideoBuffer);
resolve(compressedBase64);
} else {
reject('Error creating compressed video blob.');
}
}, 'video/mp4', quality);
});
} catch (error) {
reject(error);
}
});
} */
/* async compressVideoBase64(base64String: string, maxWidth: number, maxHeight: number, quality: number): Promise<string> {
return new Promise(async (resolve, reject) => {
@@ -718,62 +736,62 @@ export class NewPublicationPage implements OnInit {
const trimmedBase64 = base64String.trim();
console.log(this.removeTextBeforeSlash(trimmedBase64,','))
const videoBuffer = this.base64ToArrayBuffer(this.removeTextBeforeSlash(trimmedBase64,','));
// Create a Blob from the ArrayBuffer
const videoBlob = new Blob([videoBuffer], { type: 'video/mp4' });
// Create an object URL from the Blob
const videoObjectUrl = URL.createObjectURL(videoBlob);
// Create a video element
const video = document.createElement('video');
video.src = videoObjectUrl;
// Wait for the video to load metadata
video.addEventListener('loadedmetadata', async () => {
const canvas = document.createElement('canvas');
let newWidth = video.videoWidth;
let newHeight = video.videoHeight;
if (newWidth > maxWidth) {
newHeight *= maxWidth / newWidth;
newWidth = maxWidth;
}
if (newHeight > maxHeight) {
newWidth *= maxHeight / newHeight;
newHeight = maxHeight;
}
canvas.width = newWidth;
canvas.height = newHeight;
const context = canvas.getContext('2d');
context?.drawImage(video, 0, 0, newWidth, newHeight);
// Convert the canvas to a Blob
canvas.toBlob(async (blob) => {
if (blob) {
// Read the Blob as an ArrayBuffer
const compressedVideoBuffer = await this.readBlobAsArrayBuffer(blob);
// Convert the ArrayBuffer back to base64
const compressedBase64 = this.arrayBufferToBase64(compressedVideoBuffer);
resolve(compressedBase64);
} else {
reject('Error creating compressed video blob.');
}
}, 'video/mp4', quality);
});
} catch (error) {
reject(error);
}
});
} */
private base64ToArrayBuffer(base64: string): ArrayBuffer {
const binaryString = window.atob(base64);
const len = binaryString.length;
@@ -783,7 +801,7 @@ export class NewPublicationPage implements OnInit {
}
return bytes.buffer;
}
private async readBlobAsArrayBuffer(blob: Blob): Promise<ArrayBuffer> {
return new Promise((resolve, reject) => {
const reader = new FileReader();
@@ -797,12 +815,12 @@ export class NewPublicationPage implements OnInit {
reader.readAsArrayBuffer(blob);
});
}
private arrayBufferToBase64(buffer: ArrayBuffer): string {
const binary = String.fromCharCode(...new Uint8Array(buffer));
return btoa(binary);
}
fileSizeToMB(sizeInBytes) {
var sizeInMB = (sizeInBytes / (1024 * 1024)).toFixed(2);
@@ -810,8 +828,199 @@ export class NewPublicationPage implements OnInit {
return parseInt(sizeInMB)
}
deleteFromSeletedContent(index){
this.seletedContent.splice(index,1)
deleteFromSeletedContent(index) {
this.seletedContent.splice(index, 1)
}
}
class UploadFileUseCase {
LakefsRepositoryService: LakefsRepositoryService = window["LakefsRepositoryService"]
constructor() {}
execute(attachment: PublicationAttachmentEntity) {
const file: File = attachment.blob
const chunkSize = 1024 * 100; // Adjust the chunk size as needed
const fileSize = file.size;
let uploadedSize = 0
const totalChunks = Math.ceil(fileSize / chunkSize);
let offset = 0;
let i = 1;
let j = 0;
let path;
function count () {
j++
return j
}
const readAndUploadChunk = async(index: number) => {
return new Promise<void>((resolve, reject) => {
const chunk = file.slice(offset, offset + chunkSize);
const reader = new FileReader();
reader.onload = async () => {
const blob = new Blob([reader.result as ArrayBuffer]);
const formData = new FormData();
const file = new File([blob], "test.mp4", { type: blob.type });
uploadedSize =+ file.size
formData.append("blobFile", file);
formData.append("length", totalChunks.toString());
formData.append("index", index.toString());
formData.append("path", path);
try {
const response = await this.LakefsRepositoryService.uploadFile(formData).toPromise()
console.log({response})
resolve()
} catch (erro) {
reject()
}
};
reader.readAsArrayBuffer(chunk);
offset += chunkSize;
});
}
const loop = async() => {
for (let index = 2; index <= totalChunks; index++) {
await readAndUploadChunk(index);
}
}
const startUpload = async() => {
const index = count();
const chunk = file.slice(offset, offset + chunkSize);
const reader = new FileReader();
reader.onload = async () => {
const blob = new Blob([reader.result as ArrayBuffer]);
const formData = new FormData();
const file = new File([blob], "test.mp4", { type: blob.type });
uploadedSize =+ file.size
formData.append("blobFile", file);
formData.append("length", totalChunks.toString());
formData.append("index", index.toString());
const response: any = await this.LakefsRepositoryService.uploadFile(formData).toPromise()
console.log({ response, index });
if (index === 1) {
path = response.path;
}
await loop();
};
reader.readAsArrayBuffer(chunk);
offset += chunkSize;
}
startUpload();
}
}
class PublicationAttachmentEntity {
FileBase64: string
FileExtension: string
FileType: 'image' | 'video'
OriginalFileName: string
blob: any
constructor({base64, extension, blob = null, OriginalFileName = null, FileType}) {
this.FileBase64 = base64;
this.FileExtension = extension;
this.blob = blob
this.OriginalFileName = OriginalFileName
this.FileType = FileType
this.fixFileBase64();
}
fixFileBase64() {
if(this.FileType == 'image' ) {
if(!this.FileBase64.startsWith('data:')) {
this.FileBase64 = 'data:image/jpg;base64,' + this.FileBase64
}
} else if (this.FileType == 'video' ) {
if(!this.FileBase64.startsWith('data:')) {
this.FileBase64 = 'data:video/mp4;base64,' + this.FileBase64
}
}
}
}
interface IPublicationFormModelEntity {
DateIndex: any
DocumentId: any
ProcessId: any
Title: any
Message: any
DatePublication: any
Files: PublicationAttachmentEntity[]
}
class PublicationFormModel implements IPublicationFormModelEntity {
constructor() {}
DateIndex: any;
DocumentId: any;
ProcessId: any;
Title: any;
Message: any;
DatePublication: any;
OriginalFileName: string;
Files: PublicationAttachmentEntity[];
setData(data: IPublicationFormModelEntity) {
Object.assign(this, data)
}
}
class PublicationFormMV {
private UploadFileUseCase = new UploadFileUseCase()
private form = new PublicationFormModel()
setDataToFrom(data: IPublicationFormModelEntity) {
this.form.setData(data)
}
private getVideoFiles() {
return this.form.Files.filter( x => x.FileType == 'video')
}
private async upload(PublicationAttachmentEntity: PublicationAttachmentEntity) {
console.log(PublicationAttachmentEntity)
this.UploadFileUseCase.execute(PublicationAttachmentEntity)
}
uploadVideosFiles() {
const videosFiles = this.getVideoFiles()
console.log(this.form)
for(const file of videosFiles) {
this.upload(file)
}
}
}
@@ -0,0 +1,16 @@
import { TestBed } from '@angular/core/testing';
import { UploadFileUserCaseService } from './upload-file-user-case.service';
describe('UploadFileUserCaseService', () => {
let service: UploadFileUserCaseService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(UploadFileUserCaseService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});
@@ -0,0 +1,45 @@
import { Injectable } from '@angular/core';
import { LakefsRepositoryService } from "src/app/shared/repository/lakefs/lakefs-repository.service"
import { IPublicationFormModelEntity, IPublicationAttachmentEntity } from "src/app/shared/publication/new-publication/interface/interface"
@Injectable({
providedIn: 'root'
})
export class UploadFileUserCaseService {
constructor(LakefsRepositoryService: LakefsRepositoryService) {}
execute(attachment: IPublicationAttachmentEntity) {
const file: File = attachment.blob
const chunkSize = 1024 * 1024; // Adjust the chunk size as needed
const fileSize = file.size;
const totalChunks = Math.ceil(fileSize / chunkSize);
let offset = 0;
let i = 1;
// while (offset < file.size) {
// console.log("while", i)
// const chunk = file.slice(offset, offset + chunkSize);
// const reader = new FileReader();
// reader.onload = async () => {
// // const uint8Array = new Uint8Array(reader.result as ArrayBuffer)
// // Convert Uint8Array to Blob
// const blob = new Blob([reader.result as ArrayBuffer]);
// const formData = new FormData();
// formData.append("blob", blob)
// formData.append("length", totalChunks.toString())
// formData.append("length", i.toString())
// this.LakefsRepositoryService.uploadFile(formData)
// };
// reader.readAsArrayBuffer(chunk);
// offset += chunkSize;
// i++;
// }
}
}
@@ -0,0 +1,16 @@
import { TestBed } from '@angular/core/testing';
import { LakefsRepositoryService } from './lakefs-repository.service';
describe('LakefsRepositoryService', () => {
let service: LakefsRepositoryService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(LakefsRepositoryService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});
@@ -0,0 +1,17 @@
import { Injectable } from '@angular/core';
import { MiddlewareServiceService } from "src/app/shared/API/middleware/middleware-service.service";
@Injectable({
providedIn: 'root'
})
export class LakefsRepositoryService {
constructor(public MiddlewareServiceService: MiddlewareServiceService) {
window["LakefsRepositoryService"] = this
}
uploadFile(formData: FormData) {
return this.MiddlewareServiceService.uploadFileLK(formData)
}
}