diff --git a/src/app/interceptors/token.interceptors.ts b/src/app/interceptors/token.interceptors.ts index 4e7327679..bea20116f 100644 --- a/src/app/interceptors/token.interceptors.ts +++ b/src/app/interceptors/token.interceptors.ts @@ -8,6 +8,7 @@ import { HTTP_INTERCEPTORS, HttpClient, } from "@angular/common/http"; +import { AuthService } from '../services/auth.service'; import { Observable, throwError, BehaviorSubject, of } from "rxjs"; import { catchError, filter, take, switchMap, tap } from "rxjs/operators"; import { SessionStore } from '../store/session.service'; @@ -59,8 +60,8 @@ export class TokenInterceptor implements HttpInterceptor { return this.refreshToken().pipe( switchMap((token: any) => { this.isRefreshing = false; - this.refreshTokenSubject.next(token['result'].accessToken); - return next.handle(this.addToken(request, token['result'].accessToken)); + this.refreshTokenSubject.next(token.Authorization); + return next.handle(this.addToken(request, token.Authorization)); }) ); } else { @@ -87,9 +88,11 @@ export class TokenInterceptor implements HttpInterceptor { console.log(tokens) SessionStore.user.Authorization = tokens.Authorization; SessionStore.user.RefreshToken = tokens.refreshToken; + SessionStore.save(); }), catchError((error) => { + console.log(error) SessionStore.user.Authorization = ""; SessionStore.user.RefreshToken = ""; SessionStore.setInativity(false) @@ -113,4 +116,4 @@ export const tokenInterceptor = { provide: HTTP_INTERCEPTORS, useClass: TokenInterceptor, multi: true -}; +}; \ No newline at end of file diff --git a/src/app/pages/publications/new-publication/new-publication.page.ts b/src/app/pages/publications/new-publication/new-publication.page.ts index 9074afb5b..d268ccf10 100644 --- a/src/app/pages/publications/new-publication/new-publication.page.ts +++ b/src/app/pages/publications/new-publication/new-publication.page.ts @@ -115,6 +115,7 @@ export class NewPublicationPage implements OnInit { seletedContent: any[] = [] // Set a limit for the number of images to display displayLimit = 4; + filesSizeSum = 0; constructor( private modalController: ModalController, @@ -179,26 +180,33 @@ export class NewPublicationPage implements OnInit { console.log(capturedImage) + this.capturedImage = 'data:image/jpeg;base64,' + capturedImage.base64String; this.capturedImageTitle = 'foto'; - - const compressedImage = await this.compressImageBase64( - this.capturedImage, - 800, // maxWidth - 800, // maxHeight - 0.9 // quality - ).then((picture) => { - console.log('take picture', this.removeTextBeforeSlash(picture, ','),) - this.filecontent = true; - this.photoOrVideo = false; - let fileObject = { - FileBase64: this.removeTextBeforeSlash(picture, ','), - FileExtension: capturedImage.format - } - this.seletedContent.push(fileObject) + if (this.fileSizeToMB(capturedImage.base64String.length) <= 20) { + const compressedImage = await this.compressImageBase64( + this.capturedImage, + 800, // maxWidth + 800, // maxHeight + 0.9 // quality + ).then((picture) => { + console.log('take picture', this.removeTextBeforeSlash(picture, ','),) + this.filecontent = true; + this.photoOrVideo = false; + let fileObject = { + FileBase64: this.removeTextBeforeSlash(picture, ','), + FileExtension: capturedImage.format + } + this.seletedContent.push(fileObject) - }); + }); + } else { + if (this.seletedContent.length === 0) + this.filesSizeSum = 0 + + this.httpErrorHandle.validationMessagge('filessize'); + } } async laodPicture() { @@ -230,24 +238,32 @@ export class NewPublicationPage implements OnInit { this.video = data[0]; console.log(data) data.forEach(async element => { + this.filesSizeSum = this.filesSizeSum + element.size + if (this.fileSizeToMB(this.filesSizeSum) <= 20) { + const savedFile = await Filesystem.copy({ + from: element.fullPath, // directory prop removed, Capacitor parses filename for us + to: "video.mp4", + toDirectory: FilesystemDirectory.Data + }); + console.log(savedFile.uri) + Filesystem.readFile({ path: savedFile.uri }) - const savedFile = await Filesystem.copy({ - from: element.fullPath, // directory prop removed, Capacitor parses filename for us - to: "video.mp4", - toDirectory: FilesystemDirectory.Data - }); - console.log(savedFile.uri) - Filesystem.readFile({ path: savedFile.uri }) + .then(async (content) => { + this.filecontent = true; + let fileObject = { + FileBase64: content.data, + FileExtension: 'mp4' + } + this.seletedContent.push(fileObject) + }) + .catch((err) => console.error(err)); + } else { + if (this.seletedContent.length === 0) + this.filesSizeSum = 0 + + this.httpErrorHandle.validationMessagge('filessize') + } - .then(async (content) => { - this.filecontent = true; - let fileObject = { - FileBase64: content.data, - FileExtension: 'mp4' - } - this.seletedContent.push(fileObject) - }) - .catch((err) => console.error(err)); }); } catch (error) { console.log('record video error: ', error) @@ -262,23 +278,30 @@ export class NewPublicationPage implements OnInit { }); result.files.forEach(element => { - if (this.checkFileType.checkFileType(element.mimeType) == 'image' || this.checkFileType.checkFileType(element.mimeType) == 'video') { - let resultUrl = decodeURIComponent(element.path); - Filesystem.readFile({ path: resultUrl }) + this.filesSizeSum = this.filesSizeSum + element.size + if (this.fileSizeToMB(this.filesSizeSum) <= 20) { + if (this.checkFileType.checkFileType(element.mimeType) == 'image' || this.checkFileType.checkFileType(element.mimeType) == 'video') { + let resultUrl = decodeURIComponent(element.path); + Filesystem.readFile({ path: resultUrl }) - .then(async (content) => { - console.log(result) - console.log(content) - this.filecontent = true; - let fileObject = { - FileBase64: content.data, - FileExtension: this.removeTextBeforeSlash(element.mimeType, '/') - } - this.seletedContent.push(fileObject) - }) - .catch((err) => console.error(err)); + .then(async (content) => { + console.log(result) + console.log(content) + this.filecontent = true; + let fileObject = { + FileBase64: content.data, + FileExtension: this.removeTextBeforeSlash(element.mimeType, '/') + } + this.seletedContent.push(fileObject) + }) + .catch((err) => console.error(err)); + } + } else { + if (this.seletedContent.length === 0) + this.filesSizeSum = 0 + + this.httpErrorHandle.validationMessagge('filessize') } - }); }; @@ -674,14 +697,16 @@ export class NewPublicationPage implements OnInit { type: this.intent.type, url: this.intent.url } - filesArray = this.intent?.additionalItems; + if(this.intent?.additionalItems) { + filesArray = this.intent?.additionalItems; + } filesArray.push(fistFile) filesArray.forEach(element => { let FileExtension = this.removeTextBeforeSlash(element.title, '.') if (this.checkFileType.checkFileType(FileExtension) == 'image' || this.checkFileType.checkFileType(FileExtension) == 'video') { let resultUrl = decodeURIComponent(element.url); Filesystem.readFile({ path: resultUrl }).then(async (content) => { - console.log('shared base',content.data) + console.log('shared base', content.data) let fileObject = { FileBase64: this.removeTextBeforeSlash(content.data, ','), FileExtension: FileExtension @@ -696,5 +721,12 @@ export class NewPublicationPage implements OnInit { } + fileSizeToMB(sizeInBytes) { + var sizeInMB = (sizeInBytes / (1024 * 1024)).toFixed(2); + console.log(sizeInMB + 'MB'); + return parseInt(sizeInMB) + } + + } diff --git a/src/app/services/auth.service.ts b/src/app/services/auth.service.ts index 4992452b3..d46be8058 100644 --- a/src/app/services/auth.service.ts +++ b/src/app/services/auth.service.ts @@ -4,7 +4,7 @@ import { HttpClient, HttpHeaders, HttpEventType } from '@angular/common/http'; import { LoginUserRespose, UserForm, UserSession } from '../models/user.model'; import { environment } from 'src/environments/environment'; import { BehaviorSubject, of } from 'rxjs'; -import { AlertController } from '@ionic/angular'; +import { AlertController, Platform } from '@ionic/angular'; import { SessionStore } from '../store/session.service'; import { AESEncrypt } from '../services/aesencrypt.service'; import { RochetChatConnectorService } from 'src/app/services/chat/rochet-chat-connector.service'; @@ -50,7 +50,8 @@ export class AuthService { public p: PermissionService, public ChatSystemService: ChatSystemService, private httpErroHandle: HttpErrorHandle, - private errorHandler: ErrorHandler) { + private errorHandler: ErrorHandler, + private platform: Platform,) { if (SessionStore.exist) { if (this.p.userPermission(this.p.permissionList.Chat.access) == true) { @@ -90,9 +91,16 @@ export class AuthService { "Content-Type": "application/json", "Accept": "application/json", } + let channelId; + if ( this.platform.is('desktop') || this.platform.is("mobileweb")){ + channelId = 2 + } else { + channelId = 1 + } + let body = { "Auth": user.BasicAuthKey, - "ChannelId": 1 + "ChannelId": channelId } let response: any; diff --git a/src/app/services/chat.service.ts b/src/app/services/chat.service.ts index 323d75925..c650cdf12 100644 --- a/src/app/services/chat.service.ts +++ b/src/app/services/chat.service.ts @@ -370,7 +370,7 @@ export class ChatService { async refreshtoken() { - if(this.headers && SessionStore.user.ChatData) { + /* if(this.headers && SessionStore.user.ChatData) { this.headers = this.headers.set('Authorization', 'Bearer ' + SessionStore.user.Authorization); let options = { headers: this.headers @@ -406,10 +406,13 @@ export class ChatService { }) } else { - setTimeout(async () => { - this.resetTimer(); - await this.refreshtoken(); - }, 60000) + if(SessionStore.user.Authorization != '') { + setTimeout(async () => { + this.resetTimer(); + await this.refreshtoken(); + }, 60000) + } + } @@ -420,7 +423,7 @@ export class ChatService { } else if (!this.headers) { this.setheader() this.refreshtoken() - } + } */ } diff --git a/src/app/services/http-error-handle.service.ts b/src/app/services/http-error-handle.service.ts index 038005bfb..8683bef7e 100644 --- a/src/app/services/http-error-handle.service.ts +++ b/src/app/services/http-error-handle.service.ts @@ -96,6 +96,9 @@ export class HttpErrorHandle { case 'filetype': this.toastService._badRequest('Formato de ficheiro inválido!') break; + case 'filessize': + this.toastService._badRequest('Excedeu o limite de 20 MB!') + break; default: this.toastService._badRequest('') diff --git a/src/app/services/videoCompression.service.ts b/src/app/services/videoCompression.service.ts new file mode 100644 index 000000000..2a6a85599 --- /dev/null +++ b/src/app/services/videoCompression.service.ts @@ -0,0 +1,124 @@ +import { Injectable } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { Filesystem, FilesystemDirectory } from '@capacitor/filesystem'; +import { Platform } from '@ionic/angular'; + +declare var FFmpeg: any; + +@Injectable({ + providedIn: 'root' +}) +export class VideoCompressionService { + + constructor( + private http: HttpClient, + private platform: Platform + ) { } + + async compressVideo(inputFile: string, outputFileName: string, quality: string = 'medium'): Promise { + // Load FFmpeg + await this.loadFFmpeg(); + + // Input file + const inputBuffer = await this.fetchVideo(inputFile); + + // Output file path + const outputPath = await this.getOutputFilePath(outputFileName); + + // Run FFmpeg command + await this.runFFmpegCommand(inputBuffer, outputPath, quality); + + console.log('Video compression complete!'); + } + + private async loadFFmpeg(): Promise { + if (!FFmpeg.isLoaded()) { + await FFmpeg.load(); + } + } + + private async fetchVideo(url: string): Promise { + const response = await this.http.get(url, { responseType: 'arraybuffer' }).toPromise(); + return response; + } + + private async getOutputFilePath(outputFileName: string): Promise { + const dataDirectory = await Filesystem.getUri({ + directory: FilesystemDirectory.Data, + path: '' + }); + + return `${dataDirectory.uri}/${outputFileName}`; + } + + private async runFFmpegCommand(inputBuffer: ArrayBuffer, outputPath: string, quality: string): Promise { + await FFmpeg.run('-i', inputBuffer, '-c:v', 'libx264', '-preset', quality, outputPath); + } +} + + + + +//Mobile +/* import { Injectable } from '@angular/core'; +import { HTTP } from '@ionic-native/http/ngx'; +import { Filesystem, FilesystemDirectory, FilesystemEncoding } from '@capacitor/filesystem'; +import { Platform } from '@ionic/angular'; + +declare var FFmpeg: any; + +@Injectable({ + providedIn: 'root' +}) +export class VideoCompressionService { + + constructor( + private http: HTTP, + private platform: Platform + ) { } + + async compressVideo(inputFile: string, outputFileName: string, quality: string = 'medium'): Promise { + // Load FFmpeg + await this.loadFFmpeg(); + + // Input file + const inputBuffer = await this.fetchVideo(inputFile); + + // Output file path + const outputPath = await this.getOutputFilePath(outputFileName); + + // Run FFmpeg command + await this.runFFmpegCommand(inputBuffer, outputPath, quality); + + console.log('Video compression complete!'); + } + + private async loadFFmpeg(): Promise { + if (!FFmpeg.isLoaded()) { + await FFmpeg.load(); + } + } + + private async fetchVideo(url: string): Promise { + const response = await this.http.sendRequest(url, { + method: 'get', + responseType: 'arraybuffer' + }); + + return response.data; + } + + private async getOutputFilePath(outputFileName: string): Promise { + const dataDirectory = await Filesystem.getUri({ + directory: FilesystemDirectory.Data, + path: '' + }); + + return `${dataDirectory.uri}/${outputFileName}`; + } + + private async runFFmpegCommand(inputBuffer: ArrayBuffer, outputPath: string, quality: string): Promise { + await FFmpeg.run('-i', inputBuffer, '-c:v', 'libx264', '-preset', quality, outputPath); + } +} + */ \ No newline at end of file diff --git a/src/app/shared/agenda/new-event/new-event.page.ts b/src/app/shared/agenda/new-event/new-event.page.ts index 574d8af61..30e2e6d3a 100644 --- a/src/app/shared/agenda/new-event/new-event.page.ts +++ b/src/app/shared/agenda/new-event/new-event.page.ts @@ -159,6 +159,7 @@ export class NewEventPage implements OnInit { ngOnInit() { + console.log(' INTERVENIENTES',this.taskParticipants) this.changeProfileService.registerCallback(() => { this.initializeData() }) @@ -1009,7 +1010,7 @@ export class NewEventPage implements OnInit { } async fetchContacts(filter: string) { - +console.log(this.loggeduser.Profile) if (this.loggeduser.Profile == 'PR') { this.contactsService.getContacts(filter).subscribe(result => { if (this.eventPersons != null) { diff --git a/src/app/shared/publication/new-publication/new-publication.page.ts b/src/app/shared/publication/new-publication/new-publication.page.ts index 834158dce..628c5dccd 100644 --- a/src/app/shared/publication/new-publication/new-publication.page.ts +++ b/src/app/shared/publication/new-publication/new-publication.page.ts @@ -53,6 +53,7 @@ export class NewPublicationPage implements OnInit { captureContent: any; seletedContent: any[] = [] displayLimit = 4; + filesSizeSum = 0; constructor( public photoService: PhotoService, @@ -156,7 +157,7 @@ export class NewPublicationPage implements OnInit { ).then((picture) => { let fileObject = { FileBase64: picture, - FileExtension: this.removeTextBeforeSlash('jpeg') + FileExtension: this.removeTextBeforeSlash('jpeg','/') } this.seletedContent.push(fileObject) }); @@ -185,7 +186,7 @@ export class NewPublicationPage implements OnInit { ).then((picture) => { let fileObject = { FileBase64: picture, - FileExtension: this.removeTextBeforeSlash('jpeg') + FileExtension: this.removeTextBeforeSlash('jpeg','/') } this.seletedContent.push(fileObject) }); @@ -198,18 +199,28 @@ 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) => { - - console.log(element.mimeType) + this.filesSizeSum = this.filesSizeSum + element.size + if(this.fileSizeToMB(this.filesSizeSum) <= 20) { let fileObject = { FileBase64: value, - FileExtension: this.removeTextBeforeSlash(element.mimeType) + FileExtension: this.removeTextBeforeSlash(element.mimeType,'/') } this.seletedContent.push(fileObject) this.filecontent = true; - + } else { + if(this.seletedContent.length === 0) + this.filesSizeSum = 0 + + this.httpErroHandle.validationMessagge('filessize'); + } }) } else { this.httpErroHandle.validationMessagge('filetype'); @@ -471,14 +482,330 @@ export class NewPublicationPage implements OnInit { }) } - removeTextBeforeSlash(inputString) { - if (inputString.includes('/')) { - const parts = inputString.split('/'); + removeTextBeforeSlash(inputString,mark) { + if (inputString.includes(mark)) { + const parts = inputString.split(mark); return parts.length > 1 ? parts[1] : inputString; } else { return inputString; } } + async compressVideoBase64(base64String: string, maxWidth: number, maxHeight: number, quality: number): Promise { + console.log(base64String) + return new Promise(async (resolve, reject) => { + try { + // 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.'); + } + }, 'video/mp4', 0.5); + }); + } catch (error) { + reject(error); + } + }); + } + + + +/* async compressVideoBase64(base64String: string, maxWidth: number, maxHeight: number, quality: number): Promise { + 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'); + + // 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 { + 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 { + return new Promise(async (resolve, reject) => { + try { + // Decode the base64 video string to an ArrayBuffer + + 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; + const bytes = new Uint8Array(len); + for (let i = 0; i < len; ++i) { + bytes[i] = binaryString.charCodeAt(i); + } + return bytes.buffer; + } + + private async readBlobAsArrayBuffer(blob: Blob): Promise { + return new Promise((resolve, reject) => { + const reader = new FileReader(); + reader.onloadend = () => { + if (reader.result instanceof ArrayBuffer) { + resolve(reader.result); + } else { + reject('Error reading blob as ArrayBuffer.'); + } + }; + 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); + console.log(sizeInMB + 'MB'); + return parseInt(sizeInMB) + } } diff --git a/version/git-version.ts b/version/git-version.ts index 52f285240..c07f0842a 100644 --- a/version/git-version.ts +++ b/version/git-version.ts @@ -5,7 +5,7 @@ export let versionData = { "lastCommitAuthor": "'Peter Maquiran'", "lastCommitTime": "'Thu Aug 31 12:00:52 2023 +0100'", "lastCommitMessage": "add attachments", - "lastCommitNumber": "1571", + "lastCommitNumber": "1572", "change": "diff --git a/src/app/modals/create-process/create-process.page.ts b/src/app/modals/create-process/create-process.page.ts\nindex 6b58016d7..a27c5e424 100644\n--- a/src/app/modals/create-process/create-process.page.ts\n+++ b/src/app/modals/create-process/create-process.page.ts\n@@ -282,7 +282,8 @@ export class CreateProcessPage implements OnInit {\n const DocumentToSave = this.documents.map((e: any) => {\n return {\n ApplicationId: e.ApplicationType || e.ApplicationId,\n- SourceId: e.Id || e.DocId || e.SourceId\n+ SourceId: e.Id || e.DocId || e.SourceId,\n+ SourceName: e.Assunto || e.SourceName || e.Description,\n }\n });\n \ndiff --git a/src/app/modals/document-detail/document-detail.page.ts b/src/app/modals/document-detail/document-detail.page.ts\nindex 629d48c91..1bfcca6e3 100644\n--- a/src/app/modals/document-detail/document-detail.page.ts\n+++ b/src/app/modals/document-detail/document-detail.page.ts\n@@ -129,7 +129,7 @@ export class DocumentDetailPage implements OnInit {\n \n async viewDocumentModal() {\n \n- const selectedDoc = this.LoadedDocument.Documents[ this.dicIndex]\n+ const selectedDoc = this.LoadedDocument\n \n let task = {\n serialNumber: '',\n@@ -154,7 +154,7 @@ export class DocumentDetailPage implements OnInit {\n url: '',\n title_link: '',\n },\n- Document: this.LoadedDocument.Documents[ this.dicIndex],\n+ Document: this.LoadedDocument,\n applicationId: task.workflowInstanceDataFields.SourceSecFsID,\n docId: task.workflowInstanceDataFields.SourceID ,\n folderId: '',\n@@ -192,7 +192,8 @@ export class DocumentDetailPage implements OnInit {\n componentProps: {\n taskAction: taskAction,\n task: this.DocumentTask,\n- aplicationId: this.LoadedDocument.ApplicationId || this.LoadedDocument.ApplicationID\n+ aplicationId: this.LoadedDocument.ApplicationId || this.LoadedDocument.ApplicationID,\n+ document: this.LoadedDocument\n },\n cssClass: classs,\n });\n@@ -213,6 +214,7 @@ export class DocumentDetailPage implements OnInit {\n } else {\n classs = 'modal modal-desktop showAsideOptions'\n }\n+\n const modal = await this.modalController.create({\n component: DocumentSetUpMeetingPage,\n componentProps: {\n@@ -238,7 +240,8 @@ export class DocumentDetailPage implements OnInit {\n cssClass: 'exp-options',\n componentProps: {\n task: this.task,\n- LoadedDocument: this.LoadedDocument\n+ LoadedDocument: this.LoadedDocument,\n+ document: this.LoadedDocument,\n },\n translucent: true\n });\ndiff --git a/src/app/modals/document-set-up-meeting/document-set-up-meeting.page.ts b/src/app/modals/document-set-up-meeting/document-set-up-meeting.page.ts\nindex 8c68182d4..f7bb03bb0 100644\n--- a/src/app/modals/document-set-up-meeting/document-set-up-meeting.page.ts\n+++ b/src/app/modals/document-set-up-meeting/document-set-up-meeting.page.ts\n@@ -22,7 +22,7 @@ import { SessionStore } from 'src/app/store/session.service';\n import { HttpErrorHandle } from 'src/app/services/http-error-handle.service';\n import { environment } from 'src/environments/environment';\n import { TaskService } from 'src/app/services/task.service'\n-\n+import { AttachmentsService } from 'src/app/services/attachments.service';\n \n const CUSTOM_DATE_FORMATS: NgxMatDateFormats = {\n parse: {\n@@ -111,15 +111,47 @@ export class DocumentSetUpMeetingPage implements OnInit {\n public ThemeService: ThemeService,\n public _eventService: EventsService,\n private httpErroHandle: HttpErrorHandle,\n- public TaskService: TaskService\n+ public TaskService: TaskService,\n+ private attachmentsService: AttachmentsService,\n ) {\n this.loggeduser = SessionStore.user;\n this.document = this.navParams.get('document')\n \n- if(Array.isArray(this.document)) {\n- this.attachments = this.document\n- } else {\n- this.attachments = [this.document]\n+\n+ if(this.document) {\n+ console.log('this.document', this.document)\n+ if(Array.isArray(this.document)) {\n+ const docs: any = this.document\n+ for(let doc of docs ) {\n+ this.attachments.push({\n+ ApplicationId: (doc.ApplicationType || doc.ApplicationId), \n+ ApplicationType: (doc.ApplicationType || doc.ApplicationId),\n+ SourceId: (doc.Id || doc.DocId || doc.SourceId), \n+ Id: (doc.Id || doc.DocId || doc.SourceId), \n+ EntidadeOrganicaNome: (doc.Stakeholders || doc.sender || doc.EntidadeOrganicaNome ),\n+ Sender: (doc.Stakeholders || doc.sender || doc. EntidadeOrganicaNome ),\n+ Data: (doc.DocDate || doc.Data),\n+ DocDate: (doc.DocDate || doc.Data),\n+ Assunto: doc.Assunto || doc.SourceName || doc.Description,\n+ SourceName: doc.Assunto || doc.SourceName || doc.Description,\n+ } as any)\n+ }\n+ } else {\n+ const doc: any = this.document\n+ this.attachments.push({\n+ ApplicationId: (doc.ApplicationType || doc.ApplicationId), \n+ ApplicationType: (doc.ApplicationType || doc.ApplicationId),\n+ SourceId: (doc.Id || doc.DocId || doc.SourceId), \n+ Id: (doc.Id || doc.DocId || doc.SourceId), \n+ EntidadeOrganicaNome: (doc.Stakeholders || doc.sender || doc.EntidadeOrganicaNome ),\n+ Sender: (doc.Stakeholders || doc.sender || doc. EntidadeOrganicaNome ),\n+ Data: (doc.DocDate || doc.Data),\n+ DocDate: (doc.DocDate || doc.Data),\n+ Assunto: doc.Assunto || doc.SourceName || doc.Description,\n+ SourceName: doc.Assunto || doc.SourceName || doc.Description,\n+ } as any)\n+ }\n+\n }\n \n \n@@ -278,7 +310,7 @@ export class DocumentSetUpMeetingPage implements OnInit {\n let Attendees = this.taskParticipants.concat(this.taskParticipantsCc);\n \n if(this.document.Documents) {\n- this.document.Documents.forEach((e)=> {\n+ this.attachments.forEach((e: any)=> {\n this.docs.push({\n ApplicationId: e.ApplicationId || e.ApplicationType,\n Source: 1,\n@@ -287,14 +319,6 @@ export class DocumentSetUpMeetingPage implements OnInit {\n })\n })\n }\n- else{\n- this.docs.push({\n- ApplicationId: this.document.ApplicationId || this.document.ApplicationType,\n- Source: 1,\n- SourceId: this.document.DocId || this.document.docID || this.document.docId || this.document.SourceId || this.document.Id,\n- SourceName: this.document.Assunto\n- })\n- }\n \n let postEvent = {\n EventId: '',\n@@ -318,13 +342,14 @@ export class DocumentSetUpMeetingPage implements OnInit {\n Type: this.EventRecurrenceType,\n LastOccurrence: this.Occurrence,\n },\n- // Attachments: this.docs,\n+ Attachments: this.attachments,\n }\n \n const laoder = this.toastService.loading()\n \n this.eventService.create({ body: postEvent, calendar: this.postData.CalendarName }).subscribe(async (respose) => {\n laoder.remove();\n+ // this.saveAttachment()\n this.httpErroHandle.httpsSucessMessagge('new event');\n this.modalController.dismiss()\n }, (error) => {\n@@ -336,6 +361,17 @@ export class DocumentSetUpMeetingPage implements OnInit {\n \n }\n \n+ async saveAttachment() {\n+ this.attachments.forEach( async (attachments, i) => {\n+ try {\n+ await this.attachmentsService.setEventAttachmentById(attachments).toPromise();\n+ } catch(error) {\n+ \n+ }\n+\n+ });\n+ }\n+\n async addParticipants() {\n \n this.adding = \"intervenient\";\ndiff --git a/src/app/pages/gabinete-digital/expediente/expedient-task-modal/expedient-task-modal.page.ts b/src/app/pages/gabinete-digital/expediente/expedient-task-modal/expedient-task-modal.page.ts\nindex 66826fc22..b9f20c744 100644\n--- a/src/app/pages/gabinete-digital/expediente/expedient-task-modal/expedient-task-modal.page.ts\n+++ b/src/app/pages/gabinete-digital/expediente/expedient-task-modal/expedient-task-modal.page.ts\n@@ -130,19 +130,37 @@ export class ExpedientTaskModalPage implements OnInit {\n \n \n if(this.document) {\n- const doc: any = this.document\n-\n- this.documents.push({\n- ApplicationId: (doc.ApplicationType || doc.ApplicationId), \n- ApplicationType: (doc.ApplicationType || doc.ApplicationId),\n- SourceId: (doc.Id || doc.DocId || doc.SourceId), \n- Id: (doc.Id || doc.DocId || doc.SourceId), \n- EntidadeOrganicaNome: (doc.sender || doc.SourceName || doc. EntidadeOrganicaNome),\n- Sender: (doc.sender || doc.SourceName || doc. EntidadeOrganicaNome),\n- Data: (doc.DocDate || doc.Data),\n- DocDate: (doc.DocDate || doc.Data),\n- Assunto: doc.Assunto,\n- } as any)\n+ \n+ if(Array.isArray(this.document)) {\n+ const docs: any = this.document\n+ for(let doc of docs ) {\n+ this.documents.push({\n+ ApplicationId: (doc.ApplicationType || doc.ApplicationId), \n+ ApplicationType: (doc.ApplicationType || doc.ApplicationId),\n+ SourceId: (doc.Id || doc.DocId || doc.SourceId), \n+ Id: (doc.Id || doc.DocId || doc.SourceId), \n+ EntidadeOrganicaNome: (doc.Stakeholders || doc.sender || doc.EntidadeOrganicaNome ),\n+ Sender: (doc.Stakeholders || doc.sender || doc. EntidadeOrganicaNome ),\n+ Data: (doc.DocDate || doc.Data),\n+ DocDate: (doc.DocDate || doc.Data),\n+ Assunto: doc.Assunto || doc.SourceName || doc.Description,\n+ } as any)\n+ }\n+ } else {\n+ const doc: any = this.document\n+ this.documents.push({\n+ ApplicationId: (doc.ApplicationType || doc.ApplicationId), \n+ ApplicationType: (doc.ApplicationType || doc.ApplicationId),\n+ SourceId: (doc.Id || doc.DocId || doc.SourceId), \n+ Id: (doc.Id || doc.DocId || doc.SourceId), \n+ EntidadeOrganicaNome: (doc.Stakeholders || doc.sender || doc.EntidadeOrganicaNome ),\n+ Sender: (doc.Stakeholders || doc.sender || doc. EntidadeOrganicaNome ),\n+ Data: (doc.DocDate || doc.Data),\n+ DocDate: (doc.DocDate || doc.Data),\n+ Assunto: doc.Assunto || doc.SourceName || doc.Description,\n+ } as any)\n+ }\n+\n }\n \n \ndiff --git a/src/app/shared/agenda/edit-event-to-approve/edit-event-to-approve.page.html b/src/app/shared/agenda/edit-event-to-approve/edit-event-to-approve.page.html\nindex 38fc8af46..b5a0f5b4e 100644\n--- a/src/app/shared/agenda/edit-event-to-approve/edit-event-to-approve.page.html\n+++ b/src/app/shared/agenda/edit-event-to-approve/edit-event-to-approve.page.html\n@@ -283,7 +283,7 @@\n \n \n Adicionar Intervenientes*\n- {{participant.Name}}\n+ {{participant.EmailAddress }}\n \n \n \n@@ -306,7 +306,7 @@\n \n \n Adicionar Intervenientes\n- {{participant.Name}}\n+ {{participant.EmailAddress }}\n \n \n \ndiff --git a/src/app/shared/gabinete-digital/edit-event-to-approve/edit-event.page.html b/src/app/shared/gabinete-digital/edit-event-to-approve/edit-event.page.html\nindex c306e743e..fe896ef2a 100644\n--- a/src/app/shared/gabinete-digital/edit-event-to-approve/edit-event.page.html\n+++ b/src/app/shared/gabinete-digital/edit-event-to-approve/edit-event.page.html\n@@ -225,7 +225,7 @@\n \n \n Adicionar Intervenientes*\n- {{participant.Name}}\n+ {{participant.EmailAddress}}\n \n \n \n@@ -248,7 +248,7 @@\n \n \n Adicionar Intervenientes\n- {{participant.Name}}\n+ {{participant.EmailAddress }}\n \n \n ", "changeStatus": "On branch notification-header/feature\nChanges to be committed:\n (use \"git restore --staged ...\" to unstage)\n\tmodified: src/app/modals/profile/profile.page.html\n\tmodified: src/app/modals/profile/profile.page.ts\n\tmodified: src/app/services/notifications.service.ts\n\tmodified: src/app/shared/header/header.page.html\n\tmodified: src/app/shared/header/header.page.ts\n\tnew file: src/app/store/notification-holder.service.spec.ts\n\tnew file: src/app/store/notification-holder.service.ts\n\nChanges not staged for commit:\n (use \"git add ...\" to update what will be committed)\n (use \"git restore ...\" to discard changes in working directory)\n\tmodified: src/app/modals/create-process/create-process.page.ts\n\tmodified: src/app/modals/document-detail/document-detail.page.ts\n\tmodified: src/app/modals/document-set-up-meeting/document-set-up-meeting.page.ts\n\tmodified: src/app/pages/gabinete-digital/expediente/expedient-task-modal/expedient-task-modal.page.ts\n\tmodified: src/app/shared/agenda/edit-event-to-approve/edit-event-to-approve.page.html\n\tmodified: src/app/shared/gabinete-digital/edit-event-to-approve/edit-event.page.html", "changeAuthor": "peter.maquiran"