diff --git a/android/app/capacitor.build.gradle b/android/app/capacitor.build.gradle index 0e5e194e7..6795d7e61 100644 --- a/android/app/capacitor.build.gradle +++ b/android/app/capacitor.build.gradle @@ -24,6 +24,7 @@ dependencies { implementation project(':capacitor-share') implementation project(':capacitor-storage') implementation project(':capacitor-voice-recorder') + implementation project(':capacitor2-file-picker') implementation "com.soundcloud.android:android-crop:1.0.0@aar" implementation "com.squareup.okhttp:okhttp-urlconnection:2+" } diff --git a/android/app/src/main/assets/capacitor.plugins.json b/android/app/src/main/assets/capacitor.plugins.json index fda6bba97..36daaa9bc 100644 --- a/android/app/src/main/assets/capacitor.plugins.json +++ b/android/app/src/main/assets/capacitor.plugins.json @@ -58,5 +58,9 @@ { "pkg": "capacitor-voice-recorder", "classpath": "com.tchvu3.capacitorvoicerecorder.VoiceRecorder" + }, + { + "pkg": "capacitor2-file-picker", + "classpath": "com.devmantosh.filepicker.FilePicker" } ] diff --git a/android/capacitor.settings.gradle b/android/capacitor.settings.gradle index 32a311c9a..8284edc48 100644 --- a/android/capacitor.settings.gradle +++ b/android/capacitor.settings.gradle @@ -46,3 +46,6 @@ project(':capacitor-storage').projectDir = new File('../node_modules/@capacitor/ include ':capacitor-voice-recorder' project(':capacitor-voice-recorder').projectDir = new File('../node_modules/capacitor-voice-recorder/android') + +include ':capacitor2-file-picker' +project(':capacitor2-file-picker').projectDir = new File('../node_modules/capacitor2-file-picker/android') diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 9f749397f..b40868293 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -35,7 +35,7 @@ import {MatDatepickerModule} from '@angular/material/datepicker'; import {MAT_DATE_FORMATS, MAT_DATE_LOCALE} from '@angular/material/core'; import { NgxMatDateFormats, NGX_MAT_DATE_FORMATS } from '@angular-material-components/datetime-picker'; import { Network } from '@ionic-native/network/ngx'; -import { File } from '@ionic-native/file/ngx'; +import { File } from 'node_modules_/@ionic-native/file/ngx'; import { MultipleDocumentsPicker } from '@awesome-cordova-plugins/multiple-document-picker/ngx'; diff --git a/src/app/pages/chat/messages/messages.module.ts b/src/app/pages/chat/messages/messages.module.ts index 98fb7cae3..d8982cd8c 100644 --- a/src/app/pages/chat/messages/messages.module.ts +++ b/src/app/pages/chat/messages/messages.module.ts @@ -12,6 +12,7 @@ import { BtnModalDismissPage } from 'src/app/shared/btn-modal-dismiss/btn-modal- import { FontAwesomeModule } from '@fortawesome/angular-fontawesome'; import { MatMenuModule } from '@angular/material/menu'; import { LettersAvatarModule } from "ngx-letters-avatar"; +import { PdfViewerModule } from 'ng2-pdf-viewer'; @NgModule({ imports: [ @@ -21,7 +22,8 @@ import { LettersAvatarModule } from "ngx-letters-avatar"; FontAwesomeModule, MessagesPageRoutingModule, MatMenuModule, - LettersAvatarModule + LettersAvatarModule, + PdfViewerModule ], declarations: [MessagesPage] }) diff --git a/src/app/pages/chat/messages/messages.page.ts b/src/app/pages/chat/messages/messages.page.ts index 98571d874..576ce9bef 100644 --- a/src/app/pages/chat/messages/messages.page.ts +++ b/src/app/pages/chat/messages/messages.page.ts @@ -20,7 +20,7 @@ import { ChatUserStorage } from 'src/app/store/chat/chat-user.service'; import { environment } from 'src/environments/environment'; import { ThemeService } from 'src/app/services/theme.service' -import { Directory, Encoding , Filesystem, FilesystemDirectory, } from '@capacitor/filesystem'; +import { Directory, Encoding, Filesystem, FilesystemDirectory, } from '@capacitor/filesystem'; import { VoiceRecorder, VoiceRecorderPlugin, RecordingData, GenericResponse, CurrentRecordingStatus } from 'capacitor-voice-recorder'; import { Haptics, ImpactStyle } from '@capacitor/haptics'; import { PreviewCameraPage } from 'src/app/modals/preview-camera/preview-camera.page'; @@ -42,7 +42,9 @@ import { FileToBase64Service } from 'src/app/services/file/file-to-base64.servic import { Camera, CameraResultType, CameraSource } from '@capacitor/camera'; import { Plugins, Capacitor } from '@capacitor/core'; import { MultipleDocumentsPicker } from '@awesome-cordova-plugins/multiple-document-picker/ngx'; - +import { DomSanitizer} from '@angular/platform-browser'; +import { StringDecoder } from 'string_decoder'; +//import { File } from 'node_modules_/@ionic-native/file/ngx'; const IMAGE_DIR = 'stored-images'; @@ -93,7 +95,12 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy { myAudio: any; downloadfile: any; downloadFile: any; - files:any[] = []; + files: any[] = []; + @ViewChild('filechooser') fileChooserElementRef: ElementRef; + //items: File[] = []; + fileSelected?: Blob; + pdfUrl?:string; + base64File: string; constructor( public popoverController: PopoverController, @@ -119,7 +126,9 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy { private processesService: ProcessesService, private storage: Storage, private fileToBase64Service: FileToBase64Service, - private multipleDocumentsPicker: MultipleDocumentsPicker + private multipleDocumentsPicker: MultipleDocumentsPicker, + private sant: DomSanitizer, + //private file: File ) { this.loggedUser = authService.ValidatedUserChat['data']; this.roomId = this.navParams.get('roomId'); @@ -670,90 +679,161 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy { } + getFileReader(): FileReader { + const fileReader = new FileReader(); + const zoneOriginalInstance = (fileReader as any)["__zone_symbol__originalInstance"]; + return zoneOriginalInstance || fileReader; +} +fileToBase64 = (blob,filename) => { + return new Promise(resolve => { + var file = new File([blob], filename); + var reader = this.getFileReader(); // Read file content on file loaded event + reader.onloadend = (evt) => { + console.log(evt.target.result) + resolve(evt.target.result); }; // Convert data to base64 + reader.readAsDataURL(file); + } ) + }; async addFileToChat(types: typeof FileType[]) { - this.multipleDocumentsPicker.pick(2) - .then(async (res: any) => { - this.files = JSON.parse(res) - console.log('1 Add file', this.files[0].uri) - + /* this.multipleDocumentsPicker.pick(2) + .then(async (res: any) => { + this.files = JSON.parse(res) + console.log('1 Add file', this.files[0].uri) + console.log('1 Add file', JSON.stringify(this.files[0].uri)) + + - - // Here's an example of reading a file with a full file path. Use this to - // read binary data (base64 encoded) from plugins that return File URIs, such as - // the Camera. - const contents = await Filesystem.readFile({ - path: this.files[0].uri - }); - - console.log('data:', contents); - - - /* const response = await fetch(this.files[0].uri); - const blob = await response.blob(); */ - - - const blob = new Blob([res]) - console.log('Add Blob file', blob) - - const formData = new FormData(); - formData.append("blobFile", blob); - console.log(formData) - - this.wsChatMethodsService.getDmRoom(this.roomId).send({ - file: { - "type": 'application/pdf', - "guid": '', - }, - attachments: [{ - "title": 'pdf1', - "name": 'pdf1', - // "text": "description", - "title_link_download": false, - }], - temporaryData: formData - }) - }) - .catch((error: any) => console.error(error)); - - /* const roomId = this.roomId + const downloadPath = ( + this.platform.is('android') + ) ? this.file.externalDataDirectory : this.file.documentsDirectory; + + this.file.writeFile(downloadPath, 'YHaaa2.pdf', 'Eudes InĂ¡cio').then((fil)=> { + console.log('write file', fil) + }) + + + this.fileToBase64('GS_FOLHETO_AUTOMOVEL_AC.pdf',this.files[0].uri).then( + (data) => console.log(data) + ); + - const file: any = await this.fileService.getFileFromDevice(types); - + const blob = new Blob([res]) + console.log('Add Blob file', blob) - console.log('Add file', file) - const blob = new Blob([file], { type: file.type }); - //const blob = new Blob([file.size], {type: file.type }); - console.log('Add Blob file', blob) - this.blobToBase64(file) - .then(base64String => console.log(base64String)); + const formData = new FormData(); + formData.append("blobFile", blob); + console.log(formData) - const formData = new FormData(); - formData.append('blobFile', file); - console.log(formData) - - this.wsChatMethodsService.getDmRoom(roomId).send({ - file: { - "type": file.type, - "guid": '', - }, - attachments: [{ - "title": file.name, - "name": file.name, - // "text": "description", - "title_link_download": false, - }], - temporaryData: formData - }); - */ + this.wsChatMethodsService.getDmRoom(this.roomId).send({ + file: { + "type": 'application/pdf', + "guid": '', + }, + attachments: [{ + "title": 'pdf1', + "name": 'pdf1', + // "text": "description", + "title_link_download": false, + }], + temporaryData: formData + }) + }) + .catch((error: any) => console.error(error)); */ + + const roomId = this.roomId + + const file: any = await this.fileService.getFileFromDevice(types); + + console.log('Add file', JSON.stringify(await this.getBase64(file))) + + const encodedData = btoa(JSON.stringify( await this.getBase64(file))); + const blob = this.base64toBlob(encodedData, 'application/pdf') + console.log('Add Blob file', blob) + //console.log('Add Blob file', await this.blobToBase64(blob)) + //console.log('Add Blob file', await this.fileToByteArray(file)) + + + + const formData = new FormData(); + formData.append('blobFile', blob); + console.log(formData) + + this.wsChatMethodsService.getDmRoom(roomId).send({ + file: { + "type": file.type, + "guid": '', + }, + attachments: [{ + "title": file.name, + "name": file.name, + // "text": "description", + "title_link_download": false, + }], + temporaryData: formData + }); + } + base64toBlob(base64Data, contentType) { + contentType = contentType || ''; + var sliceSize = 1024; + var byteCharacters = atob(base64Data); + var bytesLength = byteCharacters.length; + var slicesCount = Math.ceil(bytesLength / sliceSize); + var byteArrays = new Array(slicesCount); + + for (var sliceIndex = 0; sliceIndex < slicesCount; ++sliceIndex) { + var begin = sliceIndex * sliceSize; + var end = Math.min(begin + sliceSize, bytesLength); + + var bytes = new Array(end - begin); + for (var offset = begin, i = 0; offset < end; ++i, ++offset) { + bytes[i] = byteCharacters[offset].charCodeAt(0); + } + byteArrays[sliceIndex] = new Uint8Array(bytes); + } + return new Blob(byteArrays, { type: contentType }); +} + + getBase64(file) { + var reader = this.getFileReader(); + reader.readAsDataURL(file); + return new Promise(resolve => { + reader.onload = function () { + resolve(reader.result) + }; + reader.onerror = function (error) { + console.log('Error: ', error); + }; + }); + + } + + fileToByteArray(file) { + return new Promise((resolve, reject) => { + try { + let reader = this.getFileReader(); + //var file = new File([filepath], filename); + reader.readAsBinaryString(file); + reader.onloadend = (evt) => { + console.log(evt.target.result) + resolve(evt.target.result); // Convert data to base64 + reader.readAsDataURL(file); + } + } + catch (e) { + reject(e); + } + }) +} + blobToBase64 = blob => { - const reader = new FileReader(); + const reader = this.getFileReader(); reader.readAsDataURL(blob); return new Promise(resolve => { reader.onloadend = () => { @@ -893,7 +973,9 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy { this.downloadFile = 'data:image/jpeg;base64,' + btoa(new Uint8Array(event.body).reduce((data, byte) => data + String.fromCharCode(byte), '')); } else { //console.log('TRY THIS LIBRARY ',fromByteArray(event.body)); - this.downloadFile = event.body; + this.downloadFile = new Uint8Array(event.body).reduce((data, byte) => data + String.fromCharCode(byte), ''); + //this.downloadFile = event.body + console.log(event.body) console.log(this._arrayBufferToBase64(event.body)) } diff --git a/src/app/shared/chat/messages/messages.page.ts b/src/app/shared/chat/messages/messages.page.ts index 390e234b1..bfec30405 100644 --- a/src/app/shared/chat/messages/messages.page.ts +++ b/src/app/shared/chat/messages/messages.page.ts @@ -75,7 +75,7 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy scrollToBottomBtn = false; longPressActive = false; frameUrl: any; - downloadFile: any; + downloadFile: string; massages: MessageService[] = [] showAvatar = true @@ -750,8 +750,9 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy this.downloadFile = 'data:image/jpeg;base64,' + btoa(new Uint8Array(event.body).reduce((data, byte) => data + String.fromCharCode(byte), '')); } else if (msg.file.type === 'application/pdf') { - this.downloadFile = 'data:application/pdf;base64,' + btoa(new Uint8Array(event.body).reduce((data, byte) => data + String.fromCharCode(byte), ''));; - console.log(this._arrayBufferToBase64(event.body)) + this.downloadFile = new Uint8Array(event.body).reduce((data, byte) => data + String.fromCharCode(byte), ''); + //console.log(this._arrayBufferToBase64(event.body)) + console.log(eval(this.downloadFile)) } msg.attachments[0] = {