diff --git a/android/app/src/main/AndroidManifest.xml.orig b/android/app/src/main/AndroidManifest.xml.orig deleted file mode 100644 index 66301e3a7..000000000 --- a/android/app/src/main/AndroidManifest.xml.orig +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/package-lock.json b/package-lock.json index 969fd6b0c..f9eacf4e2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -799,6 +799,14 @@ "integrity": "sha512-H71nDOOL8Y7kWRLqf6Sums+01Q5msqBW2KhDUTemh1tvY04eSkSXrK0uj/4mmY0Xr16/3zyZmsrxN7CKuRbNRg==", "dev": true }, + "@awesome-cordova-plugins/media-capture": { + "version": "5.40.0", + "resolved": "https://registry.npmjs.org/@awesome-cordova-plugins/media-capture/-/media-capture-5.40.0.tgz", + "integrity": "sha512-Es5qhC6VeCzo0pq0V9txlMwSL3v1ZAUKtT74DDsTnItvbX56ZPdawL4u4fLA40VikaRNYZbYNnkYopifb8nJIw==", + "requires": { + "@types/cordova": "^0.0.34" + } + }, "@babel/code-frame": { "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", @@ -2194,6 +2202,7 @@ "integrity": "sha512-HCFwOxmK7igEgNm20y+zYi+XQ0OlZYnE4oCaI82TGmA7sehlDpBBKbjmI2Bd8aM09+BXFbAAtq7JCxkEfY8nIg==" }, "@capacitor/filesystem": { +<<<<<<< HEAD "version": "1.0.6", "resolved": "https://registry.npmjs.org/@capacitor/filesystem/-/filesystem-1.0.6.tgz", "integrity": "sha512-8xqUbDZFGBMhgqoBSn9wEd9OBPdHIRegQ9zCCZcpHNf3FFAIby1ck+aDFnoq+Da49xhD6ks1SKCBSxz/26qWTw==" @@ -2207,6 +2216,21 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/@capacitor/ios/-/ios-3.3.0.tgz", "integrity": "sha512-KImT4hVoQJuAfe01wUYiMLnutMu7PxVCv4c8HVWiW+OuyyOua3lC8wQ5gAauGDugAo6mdM7fVva5a0Vtyhnbdg==" +======= + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@capacitor/filesystem/-/filesystem-1.1.0.tgz", + "integrity": "sha512-8O3UuvL8HNUEJvZnmn8yUmvgB1evtXfcF0oxIo3YbSlylqywJwS3JTiuhKmsvSxCdpbTy8IaTsutVh3gZgWbKg==" + }, + "@capacitor/haptics": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@capacitor/haptics/-/haptics-1.1.4.tgz", + "integrity": "sha512-+pJIb5X7xAcbrWj6rJaV+cwBlv8aFwB1/Ob6EV4atydThuuVSSsAL4hI4ZYlPNOxM6H5s+ZDLj7Pa2os4eFmtg==" + }, + "@capacitor/ios": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/@capacitor/ios/-/ios-3.4.1.tgz", + "integrity": "sha512-ycFCyKI8DsgedVg7PW5MpCVgqFuD0PMHQGVfC5ichXc2C/jAATX32EVdEMCB0N3guKoH2k6T3Efwg59+Fcdx2w==" +>>>>>>> 0b14c4c0c63a6d55c9945163d7afb971a7375994 }, "@capacitor/keyboard": { "version": "1.1.3", @@ -2989,6 +3013,7 @@ "integrity": "sha512-68hdPn0hA7yn4YNTgmLF32x/l7arFulboGhNiyFQ35/QxqrOmppf77p4xaPOyJtNyICKHLaiStC6w1eEAtl9MA==", "requires": { "@types/cordova": "^0.0.34" +<<<<<<< HEAD }, "dependencies": { "@types/cordova": { @@ -2996,6 +3021,8 @@ "resolved": "https://registry.npmjs.org/@types/cordova/-/cordova-0.0.34.tgz", "integrity": "sha1-6nrd907Ow9dimCegw54smt3HPQQ=" } +======= +>>>>>>> 0b14c4c0c63a6d55c9945163d7afb971a7375994 } }, "@ionic-native/core": { @@ -5071,11 +5098,6 @@ "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", "dev": true }, - "@types/pdfjs-dist": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@types/pdfjs-dist/-/pdfjs-dist-0.1.2.tgz", - "integrity": "sha512-BvRLWz6RCI8FMKbgfdTCadVwimUv8920gLsnBEAkECjtqIy95jtt+G1ebNQE2b8PTnLjJICPpmBOGhgkSsiPKA==" - }, "@types/prettier": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.1.tgz", @@ -6241,7 +6263,8 @@ "big.js": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==" + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "dev": true }, "binary-extensions": { "version": "2.2.0", @@ -6962,9 +6985,9 @@ "dev": true }, "capacitor-voice-recorder": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/capacitor-voice-recorder/-/capacitor-voice-recorder-2.0.0.tgz", - "integrity": "sha512-YU0tN8+A963sCYjL9du6jbUqOh5w5dJf++8IFBkuV0sDQZuuLaK//1RypJi0MQLifQESZSjhTVWoXTViIthA/w==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/capacitor-voice-recorder/-/capacitor-voice-recorder-2.1.0.tgz", + "integrity": "sha512-H0c/sUVD7cduVS5VqutKk00whyqXZUFi56ChRMl9Ke/LBU71HhHwzonPmheT8i9gQmgOaplc3TOpaKqckXb+3A==", "requires": { "get-blob-duration": "^1.2.0" } @@ -7262,7 +7285,8 @@ "co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true }, "code-point-at": { "version": "1.1.0", @@ -8131,8 +8155,8 @@ "integrity": "sha1-TZ6Jgsz7OOBPqQnIe0vsBuLR2Ss=" }, "cordova-plugin-dbcopy": { - "version": "git+ssh://git@github.com/an-rahulpandey/cordova-plugin-dbcopy.git#861f585e4313db828d6b8c7d354c32c83373d0d2", - "from": "cordova-plugin-dbcopy@git+https://github.com/an-rahulpandey/cordova-plugin-dbcopy.git" + "version": "git+https://github.com/an-rahulpandey/cordova-plugin-dbcopy.git#861f585e4313db828d6b8c7d354c32c83373d0d2", + "from": "git+https://github.com/an-rahulpandey/cordova-plugin-dbcopy.git" }, "cordova-plugin-device": { "version": "2.0.3", @@ -9533,7 +9557,8 @@ "emojis-list": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==" + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true }, "enabled": { "version": "2.0.0", @@ -16543,6 +16568,7 @@ "tslib": "^2.3.0" } }, +<<<<<<< HEAD "ng2-pdf-viewer": { "version": "3.0.8", "resolved": "https://registry.npmjs.org/ng2-pdf-viewer/-/ng2-pdf-viewer-3.0.8.tgz", @@ -16563,6 +16589,8 @@ } } }, +======= +>>>>>>> 0b14c4c0c63a6d55c9945163d7afb971a7375994 "ngx-cookie-service": { "version": "12.0.3", "resolved": "https://registry.npmjs.org/ngx-cookie-service/-/ngx-cookie-service-12.0.3.tgz", @@ -16648,11 +16676,6 @@ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==" }, - "node-ensure": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/node-ensure/-/node-ensure-0.0.0.tgz", - "integrity": "sha1-7K52QVDemYYexcgQ/V0Jaxg5Mqc=" - }, "node-fetch": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", @@ -24862,64 +24885,6 @@ "resolved": "https://registry.npmjs.org/wordcloud/-/wordcloud-1.2.2.tgz", "integrity": "sha512-fUnDsGrHXou+49j1OeKaC7nOeZPx+sWjIet0L/j6eAcm0nXy+a+AuUs/iDAX4PLBg1Zc6wgXWXhoXdQsXRWAEw==" }, - "worker-loader": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/worker-loader/-/worker-loader-0.8.1.tgz", - "integrity": "sha1-6OmVMx6jTfW/aCloJL+38K1XjUM=", - "requires": { - "loader-utils": "^1.0.2", - "schema-utils": "^0.3.0" - }, - "dependencies": { - "ajv": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", - "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", - "requires": { - "co": "^4.6.0", - "fast-deep-equal": "^1.0.0", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.3.0" - } - }, - "fast-deep-equal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", - "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=" - }, - "json-schema-traverse": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", - "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=" - }, - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "requires": { - "minimist": "^1.2.0" - } - }, - "loader-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - } - }, - "schema-utils": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.3.0.tgz", - "integrity": "sha1-9YdyIs4+kx7a4DnxfrNxbnE3+M8=", - "requires": { - "ajv": "^5.0.0" - } - } - } - }, "wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", diff --git a/package.json b/package.json index 0f1d8dd46..958407be1 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "@angular/platform-browser": "~12.1.2", "@angular/platform-browser-dynamic": "~12.1.2", "@angular/router": "~12.1.2", + "@awesome-cordova-plugins/media-capture": "^5.40.0", "@byteowls/capacitor-filesharer": "^3.0.0", "@capacitor-community/camera-preview": "^1.2.1", "@capacitor/android": "3.3.3", @@ -39,9 +40,9 @@ "@capacitor/camera": "^1.2.0", "@capacitor/core": "^3.3.2", "@capacitor/device": "^1.1.0", - "@capacitor/filesystem": "^1.0.6", - "@capacitor/haptics": "^1.1.2", - "@capacitor/ios": "3.3.0", + "@capacitor/filesystem": "^1.1.0", + "@capacitor/haptics": "^1.1.4", + "@capacitor/ios": "3.4.1", "@capacitor/keyboard": "^1.1.2", "@capacitor/local-notifications": "^1.1.0", "@capacitor/network": "^1.0.6", @@ -101,7 +102,7 @@ "beast-orm": "^1.0.0", "bootstrap": "^4.5.0", "build": "0.1.4", - "capacitor-voice-recorder": "^2.0.0", + "capacitor-voice-recorder": "^2.1.0", "ci": "^2.1.1", "cordova": "^10.0.0", "cordova-plugin-crop": "^0.4.0", @@ -135,7 +136,6 @@ "lite-server": "^2.6.1", "moment": "^2.29.1", "ng-lazyload-image": "^9.1.2", - "ng2-pdf-viewer": "^3.0.8", "ngx-cookie-service": "^12.0.3", "ngx-image-compress": "^11.0.3", "ngx-image-cropper": "^5.0.1", diff --git a/src/app/app.module.ts b/src/app/app.module.ts index ed93e7c49..e20702ceb 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -12,18 +12,15 @@ import { HttpClientModule } from '@angular/common/http'; import { InAppBrowser } from '@ionic-native/in-app-browser/ngx'; - //import { File } from '@ionic-native/File/ngx'; import { WebView } from '@ionic-native/ionic-webview/ngx'; import { FilePath } from '@ionic-native/file-path/ngx'; import { Camera } from '@ionic-native/camera/ngx'; import { IonicStorageModule } from '@ionic/storage'; -// import { CommonModule } from '@angular/common'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; - import { CalendarModule, DateAdapter } from 'angular-calendar'; import { adapterFactory } from 'angular-calendar/date-adapters/date-fns'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; @@ -35,10 +32,6 @@ 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 { NgxMatDatetimePickerModule, NgxMatNativeDateModule, @@ -56,13 +49,14 @@ import { far } from '@fortawesome/free-regular-svg-icons' import { fab } from '@fortawesome/free-brands-svg-icons' import { ScreenOrientation } from '@ionic-native/screen-orientation/ngx'; -import { PdfViewerModule } from 'ng2-pdf-viewer'; import { SQLite } from '@ionic-native/sqlite/ngx'; import { CookieService } from 'ngx-cookie-service'; import { ImagePicker } from '@ionic-native/image-picker/ngx'; import { MediaCapture } from '@ionic-native/media-capture/ngx'; import { Media } from '@ionic-native/media/ngx'; +import { File } from '@ionic-native/file/ngx'; + import { StreamingMedia } from '@ionic-native/streaming-media/ngx'; import { PhotoViewer } from '@ionic-native/photo-viewer/ngx'; import {NgxImageCompressService} from 'ngx-image-compress'; @@ -111,10 +105,8 @@ import { FirebaseX } from '@ionic-native/firebase-x/ngx'; */ MatSelectModule, MatDialogModule, // - PdfViewerModule, HammerModule, - CustomImageCachePageRoutingModule - + CustomImageCachePageRoutingModule, ], providers: [ @@ -126,7 +118,7 @@ import { FirebaseX } from '@ionic-native/firebase-x/ngx'; */ { provide: RouteReuseStrategy, useClass: IonicRouteStrategy }, InAppBrowser, Camera, - //File, + File, WebView, FilePath, /* FCM, diff --git a/src/app/modals/document-viewer/document-viewer.module.ts b/src/app/modals/document-viewer/document-viewer.module.ts index ad32d18c7..11f2f154a 100644 --- a/src/app/modals/document-viewer/document-viewer.module.ts +++ b/src/app/modals/document-viewer/document-viewer.module.ts @@ -7,7 +7,6 @@ import { IonicModule } from '@ionic/angular'; import { DocumentViewerPageRoutingModule } from './document-viewer-routing.module'; import { DocumentViewerPage } from './document-viewer.page'; -import { PdfViewerModule } from 'ng2-pdf-viewer'; @NgModule({ @@ -17,7 +16,6 @@ import { PdfViewerModule } from 'ng2-pdf-viewer'; IonicModule, DocumentViewerPageRoutingModule, // - PdfViewerModule ], declarations: [DocumentViewerPage] }) diff --git a/src/app/modals/view-media/view-media.module.ts b/src/app/modals/view-media/view-media.module.ts index 772ba6e59..eb52e9daf 100644 --- a/src/app/modals/view-media/view-media.module.ts +++ b/src/app/modals/view-media/view-media.module.ts @@ -8,7 +8,6 @@ import { ViewMediaPageRoutingModule } from './view-media-routing.module'; import { ViewMediaPage } from './view-media.page'; import { FontAwesomeModule } from '@fortawesome/angular-fontawesome'; -import { PdfViewerModule } from 'ng2-pdf-viewer'; @NgModule({ imports: [ @@ -17,7 +16,6 @@ import { PdfViewerModule } from 'ng2-pdf-viewer'; IonicModule, FontAwesomeModule, ViewMediaPageRoutingModule, - PdfViewerModule ], declarations: [ViewMediaPage] }) diff --git a/src/app/modals/view-media/view-media.page.html b/src/app/modals/view-media/view-media.page.html index 3334943bd..b4367aac4 100644 --- a/src/app/modals/view-media/view-media.page.html +++ b/src/app/modals/view-media/view-media.page.html @@ -24,13 +24,11 @@
- -
- + diff --git a/src/app/pages/chat/group-messages/group-messages.module.ts b/src/app/pages/chat/group-messages/group-messages.module.ts index f6047147e..910c7e4e4 100644 --- a/src/app/pages/chat/group-messages/group-messages.module.ts +++ b/src/app/pages/chat/group-messages/group-messages.module.ts @@ -16,6 +16,7 @@ import { FontAwesomeModule } from '@fortawesome/angular-fontawesome'; import { ImageCropperModule } from 'ngx-image-cropper'; import { AngularCropperjsModule } from 'angular-cropperjs'; import { LettersAvatarModule } from "ngx-letters-avatar"; +import { PipesModule } from 'src/app/pipes/pipes.module'; @NgModule({ imports: [ @@ -26,7 +27,8 @@ import { LettersAvatarModule } from "ngx-letters-avatar"; GroupMessagesPageRoutingModule, ChatPopoverPageModule, BtnModalDismissPageModule, - LettersAvatarModule + LettersAvatarModule, + PipesModule, /* ImageCropperModule, AngularCropperjsModule */ diff --git a/src/app/pages/chat/group-messages/group-messages.page.html b/src/app/pages/chat/group-messages/group-messages.page.html index 9bbe22d91..2ee9b4c4b 100644 --- a/src/app/pages/chat/group-messages/group-messages.page.html +++ b/src/app/pages/chat/group-messages/group-messages.page.html @@ -106,7 +106,7 @@
-
+
@@ -117,11 +117,14 @@ {{file.title}}
-
- +
+ +
+
+ {{file.description}} - {{msg.displayType}} + {{msg.displayType}}
@@ -190,32 +193,47 @@
{{ wsChatMethodsService.getGroupRoom(roomId).userThatIsTyping }} está a escrever...
+ +
+ {{durationDisplay}} + +
+
- +
- - - - +
+ - diff --git a/src/app/pages/chat/group-messages/group-messages.page.scss b/src/app/pages/chat/group-messages/group-messages.page.scss index 05a8e69b4..65dbba56d 100644 --- a/src/app/pages/chat/group-messages/group-messages.page.scss +++ b/src/app/pages/chat/group-messages/group-messages.page.scss @@ -177,7 +177,7 @@ -webkit-overflow-scrolling: touch; .messages-list-item-wrapper{ - overflow: auto; + overflow: hidden; } .messages-list-item-wrapper-active{ background: #e6f6ff75 !important; @@ -358,4 +358,4 @@ .typing ngx-letters-avatar { padding-right: 5px; -} \ No newline at end of file +} diff --git a/src/app/pages/chat/group-messages/group-messages.page.ts b/src/app/pages/chat/group-messages/group-messages.page.ts index 0180b6f80..ee66cee5b 100644 --- a/src/app/pages/chat/group-messages/group-messages.page.ts +++ b/src/app/pages/chat/group-messages/group-messages.page.ts @@ -32,6 +32,9 @@ import { Storage } from '@ionic/storage'; import { CameraService } from 'src/app/services/camera.service'; import { SearchPage } from 'src/app/pages/search/search.page'; import { ProcessesService } from 'src/app/services/processes.service'; +import { VoiceRecorder, VoiceRecorderPlugin, RecordingData, GenericResponse, CurrentRecordingStatus } from 'capacitor-voice-recorder'; +import { Filesystem, Directory, Encoding } from '@capacitor/filesystem'; +import { DomSanitizer } from '@angular/platform-browser'; @Component({ selector: 'app-group-messages', @@ -74,6 +77,15 @@ export class GroupMessagesPage implements OnInit, AfterViewInit, OnDestroy { @ViewChild('scrollMe') private myScrollContainer: ElementRef; + recording = false; + allowTyping = true; + storedFileNames = []; + lastAudioRecorded = ''; + audioRecorded:any = ""; + audioDownloaded:any = ""; + durationDisplay = ''; + duration = 0; + constructor( private menu: MenuController, private modalController: ModalController, @@ -97,8 +109,8 @@ export class GroupMessagesPage implements OnInit, AfterViewInit, OnDestroy { private AttachmentsService: AttachmentsService, private storage: Storage, private processesService: ProcessesService, - private CameraService: CameraService, + private sanitiser: DomSanitizer, ) { this.loggedUserChat = authService.ValidatedUserChat['data']; this.isGroupCreated = true; @@ -132,6 +144,8 @@ export class GroupMessagesPage implements OnInit, AfterViewInit, OnDestroy { this.wsChatMethodsService.getUserOfRoom(this.roomId).then((value) => { console.log('MEMBER', value) }) + VoiceRecorder.requestAudioRecordingPermission(); + //this.loadFiles(); } setStatus(status: string) { @@ -145,19 +159,8 @@ export class GroupMessagesPage implements OnInit, AfterViewInit, OnDestroy { } deleteMessage(msgId: string) { - let body = { - "roomId": this.roomId, - "msgId": msgId, - "asUser": false, - } - if (msgId) { - //this.alertService.confirmDeleteMessage(body); - } - else { - this.toastService.badRequest('Não foi possível apagar'); - } - this.showMessageOptions = false; - this.selectedMsgId = ""; + const room = this.wsChatMethodsService.getGroupRoom(this.roomId) + this.alertService.confirmDeleteMessage(msgId, room); } ngAfterViewInit() { @@ -197,6 +200,106 @@ export class GroupMessagesPage implements OnInit, AfterViewInit, OnDestroy { this.currentPosition = scroll; } + calculateDuration() { + if (!this.recording) { + this.duration = 0; + this.durationDisplay = ''; + return; + } + this.duration += 1; + const minutes = Math.floor(this.duration / 60); + const seconds = (this.duration % 60).toString().padStart(2, '0'); + this.durationDisplay = `${minutes}:${seconds}`; + + setTimeout(() => { + this.calculateDuration(); + }, 1000) + } + + async getFile(fileName?:any){ + const audioFile = await Filesystem.readFile({ + path: fileName, + directory: Directory.Data + }) + //console.log(audioFile); + const base64sound = audioFile.data; + + //Converting base64 to blob + const base64 = await fetch(base64sound); + //console.log(base64); + + const base64Response = await fetch(`data:audio/ogg;base64,${base64sound}`); + //console.log(base64Response); + + this.audioRecorded = base64Response.url; + + console.log(this.audioRecorded); + + } + + async loadFiles() { + + this.storage.get('fileName').then((fileName) => { + this.lastAudioRecorded = fileName; + }) + + this.storage.get('recordData').then((recordData) => { + console.log(recordData); + if(recordData.value.recordDataBase64.includes('data:audio')){ + this.audioRecorded = this.sanitiser.bypassSecurityTrustResourceUrl(recordData.value.recordDataBase64); + } + else{ + this.audioRecorded = this.sanitiser.bypassSecurityTrustResourceUrl(`data:${recordData.value.mimeType};base64,${recordData.value.recordDataBase64}`); + } + }); + } + + startRecording() { + console.log('Recording'); + + if (this.recording) { + return; + } + this.recording = true; + VoiceRecorder.startRecording(); + this.calculateDuration(); + } + + stopRecording() { + this.deleteRecording(); + this.allowTyping = false; + console.log('Stop'); + if (!this.recording) { + return; + } + this.recording = false; + VoiceRecorder.stopRecording().then(async (result: RecordingData) => { + console.log(result); + this.recording = false; + if (result.value && result.value.recordDataBase64) { + const recordData = result.value.recordDataBase64; + //console.log(recordData); + const fileName = new Date().getTime() + ".wav"; + //Save file + this.storage.set('fileName',fileName); + this.storage.set('recordData',result).then(() => { + console.log('Audio recorded saved'); + }) + } + }) + setTimeout(async () => { + this.loadFiles(); + }, 1000); + } + + async deleteRecording(){ + this.storage.remove('fileName'); + this.storage.remove('recordData'); + + this.allowTyping = true; + this.lastAudioRecorded = ''; + this.loadFiles(); + } async goToEvent(eventId: any) { let classs; @@ -268,6 +371,7 @@ export class GroupMessagesPage implements OnInit, AfterViewInit, OnDestroy { close() { this.modalController.dismiss(); + this.deleteRecording(); } doRefresh(ev: any) { @@ -311,13 +415,48 @@ export class GroupMessagesPage implements OnInit, AfterViewInit, OnDestroy { return i; } - - - sendMessage() { this.wsChatMethodsService.getGroupRoom(this.roomId).send({}) } + async sendAudio(fileName) { + + const roomId = this.roomId + this.storage.get('recordData').then((recordData) => { + console.log(recordData); + if(recordData.value.recordDataBase64.includes('data:audio')){ + this.audioRecorded = recordData.value.recordDataBase64; + } + else{ + this.audioRecorded = `data:${recordData.value.mimeType};base64,${recordData.value.recordDataBase64}`; + } + }); + + //Converting base64 to blob + const base64Response = await fetch(this.audioRecorded); + const blob = await base64Response.blob(); + + const formData = new FormData(); + formData.append("blobFile", blob); + + this.wsChatMethodsService.getGroupRoom(roomId).send({ + file: { + "type": "aplication/audio", + /* "guid": '', */ + }, + attachments: [{ + "title": fileName , + "title_link": this.audioRecorded, + "title_link_download": true, + "type": "file" + }], + temporaryData: formData + }) + this.deleteRecording(); + + } + + async openOptions() { const modal = await this.popoverController.create({ component: ChatPopoverPage, diff --git a/src/app/pages/chat/messages/messages.module.ts b/src/app/pages/chat/messages/messages.module.ts index 98fb7cae3..83d0d168c 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 { PipesModule } from 'src/app/pipes/pipes.module'; @NgModule({ imports: [ @@ -21,7 +22,8 @@ import { LettersAvatarModule } from "ngx-letters-avatar"; FontAwesomeModule, MessagesPageRoutingModule, MatMenuModule, - LettersAvatarModule + LettersAvatarModule, + PipesModule, ], declarations: [MessagesPage] }) diff --git a/src/app/pages/chat/messages/messages.page.html b/src/app/pages/chat/messages/messages.page.html index ddc994fd6..a985644d0 100644 --- a/src/app/pages/chat/messages/messages.page.html +++ b/src/app/pages/chat/messages/messages.page.html @@ -87,8 +87,8 @@
-
-
+
+
@@ -98,11 +98,14 @@ {{file.title}}
-
+
+ +
+
{{file.description}} - {{msg.displayType}} + {{msg.displayType}}
@@ -173,42 +176,41 @@ fontFamily="Roboto"> está a escrever ...
+
+ {{durationDisplay}} + +
- - - {{storedFileNames}} - - - {{storedFileNames}} - - - - -
- +
-
- - - - - +
- + - diff --git a/src/app/pages/chat/messages/messages.page.scss b/src/app/pages/chat/messages/messages.page.scss index c05d06a67..3676b8be4 100644 --- a/src/app/pages/chat/messages/messages.page.scss +++ b/src/app/pages/chat/messages/messages.page.scss @@ -56,9 +56,6 @@ width: calc(100% - 25px); text-align: right; - /* ion-icon{ - font-size: 25px; - } */ .middle-container-options-icons{ color: #0782c9; font-size: 23px; @@ -117,6 +114,7 @@ } } } + ion-content{ .welcome-text{ /* width: 322px; */ @@ -148,7 +146,7 @@ -webkit-overflow-scrolling: touch; .messages-list-item-wrapper{ - overflow: auto; + overflow: hidden; } .messages-list-item-wrapper-active{ background: #e6f6ff75 !important; @@ -228,7 +226,6 @@ justify-content: center; justify-content: space-evenly; align-items: center; - } .chat-icon-options{ @@ -319,4 +316,15 @@ display: block; .typing ngx-letters-avatar { padding-right: 5px; -} \ No newline at end of file +} + + +button{ + padding: 0px; + border: 0px; +} + +button::-moz-focus-inner { + padding: 0px; + border: 0px; +} diff --git a/src/app/pages/chat/messages/messages.page.ts b/src/app/pages/chat/messages/messages.page.ts index 9a30e8db7..d127c1a1d 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, FilesystemDirectory } from '@capacitor/filesystem'; +import { Filesystem, Directory, Encoding } 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'; @@ -40,13 +40,10 @@ import { SearchPage } from 'src/app/pages/search/search.page'; import { Storage } from '@ionic/storage'; import { FileToBase64Service } from 'src/app/services/file/file-to-base64.service'; import { Camera, CameraResultType, CameraSource } from '@capacitor/camera'; -import { Plugins } from '@capacitor/core'; -import { fromByteArray } from 'base64-js'; +import { DomSanitizer } from '@angular/platform-browser'; +/* import {Plugins} from '@capacitor/core'; -const { Filesystem } = Plugins; - - -const IMAGE_DIR = 'stored-images'; + const { Filesystem } = Plugins; */ @Component({ selector: 'app-messages', @@ -87,7 +84,11 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy { LoadedDocument: any = null; recording = false; + allowTyping = true; storedFileNames = []; + lastAudioRecorded = ''; + audioRecorded:any = ""; + audioDownloaded:any = ""; durationDisplay = ''; duration = 0; @ViewChild('recordbtn', { read: ElementRef }) recordBtn: ElementRef; @@ -120,6 +121,7 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy { private processesService: ProcessesService, private storage: Storage, private fileToBase64Service: FileToBase64Service, + private sanitiser: DomSanitizer, ) { this.loggedUser = authService.ValidatedUserChat['data']; this.roomId = this.navParams.get('roomId'); @@ -131,6 +133,8 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy { } }; + console.log(this.wsChatMethodsService.getDmRoom(this.roomId).loadHistory({})); + this.wsChatMethodsService.getDmRoom(this.roomId).loadHistory({}) this.wsChatMethodsService.getDmRoom(this.roomId).scrollDown = this.scrollToBottomClicked this.wsChatMethodsService.openRoom(this.roomId) @@ -145,15 +149,14 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy { this.wsChatMethodsService.getUserOfRoom(this.roomId).then((value) => { console.log('MEMBER', value) }) - //this.loadFiles(); VoiceRecorder.requestAudioRecordingPermission(); this.getChatMembers(); - Filesystem.mkdir({ + /* Filesystem.mkdir({ path: IMAGE_DIR, directory: Directory.Data, recursive: true - }); + }); */ } ngAfterViewInit() { @@ -167,11 +170,14 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy { onStart: ev => { Haptics.impact({ style: ImpactStyle.Light }) this.startRecording(); - this.calculateDuration(); + //this.calculateDuration(); }, onEnd: ev => { Haptics.impact({ style: ImpactStyle.Light }) this.stopRecording(); + /* setTimeout(() => { + this.loadFiles(); + }, 500); */ } }, true); longpress.enable(); @@ -194,61 +200,73 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy { } async loadFiles() { - Filesystem.readdir({ - path: '', - directory: Directory.Data - }).then(result => { - console.log(result); - const temp: any[] = result.files.reverse(); - this.storedFileNames = temp[0]; - console.log(this.storedFileNames); + + this.storage.get('fileName').then((fileName) => { + this.lastAudioRecorded = fileName; }) + + this.storage.get('recordData').then((recordData) => { + console.log(recordData); + if(recordData.value.recordDataBase64.includes('data:audio')){ + this.audioRecorded = this.sanitiser.bypassSecurityTrustResourceUrl(recordData.value.recordDataBase64); + } + else{ + this.audioRecorded = this.sanitiser.bypassSecurityTrustResourceUrl(`data:${recordData.value.mimeType};base64,${recordData.value.recordDataBase64}`); + } + }); } startRecording() { + console.log('Recording'); + if (this.recording) { return; } this.recording = true; - VoiceRecorder.startRecording(); + VoiceRecorder.startRecording() + .then((result: GenericResponse) => console.log(result.value)) + .catch(error => console.log(error)); + this.calculateDuration(); } stopRecording() { + this.deleteRecording(); + this.allowTyping = false; + console.log('Stop'); if (!this.recording) { return; } this.recording = false; VoiceRecorder.stopRecording().then(async (result: RecordingData) => { + console.log(result); this.recording = false; if (result.value && result.value.recordDataBase64) { const recordData = result.value.recordDataBase64; - console.log(recordData); - this.myAudio = recordData; + //console.log(recordData); const fileName = new Date().getTime() + ".wav"; - await Filesystem.writeFile({ - path: fileName, - directory: Directory.Data, - data: recordData, + //Save file + this.storage.set('fileName',fileName); + this.storage.set('recordData',result).then(() => { + console.log('Audio recorded saved'); }) } }) - + setTimeout(async () => { + this.loadFiles(); + }, 1000); } - async playFile(fileName?: any) { - const audioFile = await Filesystem.readFile({ - path: fileName, - directory: Directory.Data - }) - console.log(audioFile); - const base64sound = audioFile.data; - - const audioRef = new Audio(`data:audio/aac;base64,${base64sound}`) - audioRef.oncanplaythrough = () => audioRef.play(); - audioRef.load(); + async deleteRecording(){ + this.storage.remove('fileName'); + this.storage.remove('recordData'); + this.allowTyping = true; + this.lastAudioRecorded = ''; + this.loadFiles(); } + + handlePress(id?: string) { this.selectedMsgId = id; this.showMessageOptions = true; @@ -260,19 +278,8 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy { } deleteMessage(msgId: string) { - let body = { - "roomId": this.roomId, - "msgId": msgId, - "asUser": false, - } - if (msgId) { - //this.alertService.confirmDeleteMessage(body); - } - else { - this.toastService.badRequest('Não foi possível apagar'); - } - this.showMessageOptions = false; - this.selectedMsgId = ""; + const room = this.wsChatMethodsService.getDmRoom(this.roomId) + this.alertService.confirmDeleteMessage(msgId, room); } @@ -282,6 +289,7 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy { close() { this.modalController.dismiss(); + this.deleteRecording(); } load() { @@ -358,6 +366,53 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy { this.wsChatMethodsService.getDmRoom(this.roomId).send({}) } + async sendAudio(fileName) { + + const roomId = this.roomId + this.storage.get('recordData').then((recordData) => { + console.log(recordData); + if(recordData.value.recordDataBase64.includes('data:audio')){ + this.audioRecorded = recordData.value.recordDataBase64; + } + else{ + this.audioRecorded = `data:${recordData.value.mimeType};base64,${recordData.value.recordDataBase64}`; + } + }); + + //Converting base64 to blob + const base64Response = await fetch(this.audioRecorded); + const blob = await base64Response.blob(); + + const formData = new FormData(); + formData.append("blobFile", blob); + + this.wsChatMethodsService.getDmRoom(roomId).send({ + file: { + "type": "aplication/audio", + /* "guid": '', */ + }, + attachments: [{ + "title": fileName , + "title_link": this.audioRecorded, + "title_link_download": true, + "type": "file" + }], + temporaryData: formData + }) + this.deleteRecording(); + + } + + blobToBase64 = blob => { + const reader = new FileReader(); + reader.readAsDataURL(blob); + return new Promise(resolve => { + reader.onloadend = () => { + resolve(reader.result); + }; + }); + }; + viewDocument(msg: any, url?: string) { console.log(msg) if (msg.attachments.type == "application/webtrix") { @@ -396,6 +451,13 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy { } } + /* playSound(url?:any){ + alert('here') + console.log(url); + //this.audioDownloaded = this.sanitiser.bypassSecurityTrustResourceUrl(url); + this.audioDownloaded = url; + } */ + docIndex(index: number) { this.dicIndex = index } @@ -841,7 +903,7 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy { if (msg.file.type == "application/img") { 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)); + //console.log('TRY THIS LIBRARY ',fromByteArray(event.body)); this.downloadFile = event.body; } diff --git a/src/app/pages/events/events.module.ts b/src/app/pages/events/events.module.ts index 811e816ca..6bd3e5096 100644 --- a/src/app/pages/events/events.module.ts +++ b/src/app/pages/events/events.module.ts @@ -5,7 +5,6 @@ import { IonicModule } from '@ionic/angular'; import { EventsPageRoutingModule } from './events-routing.module'; import { EventsPage } from './events.page'; import { HeaderPageModule } from 'src/app/shared/header/header.module'; -import { PdfViewerModule } from 'ng2-pdf-viewer'; @NgModule({ imports: [ @@ -15,7 +14,6 @@ import { PdfViewerModule } from 'ng2-pdf-viewer'; EventsPageRoutingModule, HeaderPageModule, // - PdfViewerModule ], declarations: [EventsPage], schemas: [CUSTOM_ELEMENTS_SCHEMA] diff --git a/src/app/pipes/pipes.module.ts b/src/app/pipes/pipes.module.ts index f2017b539..351e00d4c 100644 --- a/src/app/pipes/pipes.module.ts +++ b/src/app/pipes/pipes.module.ts @@ -6,11 +6,12 @@ import { EventPipe } from './event.pipe'; import { PublicationPipe } from './publication.pipe'; import { ExpedienteTaskPipe } from './expediente-task.pipe'; import { ParticipantsPipe } from './participants.pipe'; +import { SafehtmlPipe } from './safehtml.pipe'; @NgModule({ - declarations: [FilterPipe, SearchDocumentPipe, CustomTaskPipe, EventPipe, PublicationPipe, ExpedienteTaskPipe, ParticipantsPipe], - exports: [FilterPipe], + declarations: [FilterPipe, SearchDocumentPipe, CustomTaskPipe, EventPipe, PublicationPipe, ExpedienteTaskPipe, ParticipantsPipe, SafehtmlPipe], + exports: [FilterPipe, SafehtmlPipe], imports: [] }) export class PipesModule { } diff --git a/src/app/pipes/safehtml.pipe.spec.ts b/src/app/pipes/safehtml.pipe.spec.ts new file mode 100644 index 000000000..dbc4806e0 --- /dev/null +++ b/src/app/pipes/safehtml.pipe.spec.ts @@ -0,0 +1,8 @@ +import { SafehtmlPipe } from './safehtml.pipe'; + +describe('SafehtmlPipe', () => { + it('create an instance', () => { + const pipe = new SafehtmlPipe(); + expect(pipe).toBeTruthy(); + }); +}); diff --git a/src/app/pipes/safehtml.pipe.ts b/src/app/pipes/safehtml.pipe.ts new file mode 100644 index 000000000..f33f62a5c --- /dev/null +++ b/src/app/pipes/safehtml.pipe.ts @@ -0,0 +1,14 @@ +import { Pipe, PipeTransform } from '@angular/core'; +import { DomSanitizer } from '@angular/platform-browser'; + +@Pipe({ + name: 'safehtml' +}) +export class SafehtmlPipe implements PipeTransform { + constructor(private sanitiser: DomSanitizer){} + + transform(html): unknown { + return this.sanitiser.bypassSecurityTrustResourceUrl(html); + } + +} diff --git a/src/app/services/chat/ws-chat.service.ts b/src/app/services/chat/ws-chat.service.ts index bfb47a6d9..75df35da7 100644 --- a/src/app/services/chat/ws-chat.service.ts +++ b/src/app/services/chat/ws-chat.service.ts @@ -728,7 +728,7 @@ export class WsChatService { this.wsMsgQueue[requestId] = {message, requestId, loginRequired} } else { let messageStr = JSON.stringify(message) - // console.log('messageStr', messageStr) + console.log('messageStr', messageStr) this.socket.send(messageStr) } diff --git a/src/app/services/events/events.module.ts b/src/app/services/events/events.module.ts index 811e816ca..6bd3e5096 100644 --- a/src/app/services/events/events.module.ts +++ b/src/app/services/events/events.module.ts @@ -5,7 +5,6 @@ import { IonicModule } from '@ionic/angular'; import { EventsPageRoutingModule } from './events-routing.module'; import { EventsPage } from './events.page'; import { HeaderPageModule } from 'src/app/shared/header/header.module'; -import { PdfViewerModule } from 'ng2-pdf-viewer'; @NgModule({ imports: [ @@ -15,7 +14,6 @@ import { PdfViewerModule } from 'ng2-pdf-viewer'; EventsPageRoutingModule, HeaderPageModule, // - PdfViewerModule ], declarations: [EventsPage], schemas: [CUSTOM_ELEMENTS_SCHEMA] diff --git a/src/app/services/events/events.page.html b/src/app/services/events/events.page.html index 5e192894f..4fb2378e8 100644 --- a/src/app/services/events/events.page.html +++ b/src/app/services/events/events.page.html @@ -113,9 +113,4 @@
- - diff --git a/src/app/shared/chat/group-messages/group-messages.module.ts b/src/app/shared/chat/group-messages/group-messages.module.ts index 2865c3427..bdbe70cc8 100644 --- a/src/app/shared/chat/group-messages/group-messages.module.ts +++ b/src/app/shared/chat/group-messages/group-messages.module.ts @@ -11,10 +11,10 @@ import { SharedModule } from 'src/app/shared/shared.module'; import { ChatPopoverPageModule } from '../../popover/chat-popover/chat-popover.module'; import { NewEventPageModule } from '../../agenda/new-event/new-event.module'; -import { PdfViewerModule } from 'ng2-pdf-viewer'; import { FontAwesomeModule } from '@fortawesome/angular-fontawesome'; import {MatMenuModule} from '@angular/material/menu'; import { LettersAvatarModule } from "ngx-letters-avatar"; +import { PipesModule } from 'src/app/pipes/pipes.module'; @NgModule({ imports: [ @@ -22,11 +22,11 @@ import { LettersAvatarModule } from "ngx-letters-avatar"; FormsModule, IonicModule, FontAwesomeModule, - PdfViewerModule, ChatPopoverPageModule, GroupMessagesPageRoutingModule, MatMenuModule, - LettersAvatarModule + LettersAvatarModule, + PipesModule, // ], exports: [GroupMessagesPage], diff --git a/src/app/shared/chat/group-messages/group-messages.page.html b/src/app/shared/chat/group-messages/group-messages.page.html index 71d34359b..53820a393 100644 --- a/src/app/shared/chat/group-messages/group-messages.page.html +++ b/src/app/shared/chat/group-messages/group-messages.page.html @@ -72,6 +72,7 @@
+ {{msg.u.name}} {{msg.duration}}
@@ -82,7 +83,7 @@
-
+
@@ -93,11 +94,14 @@ {{file.title}}
-
+
+ +
+
{{file.description}} - {{msg.displayType}} + {{msg.displayType}}
@@ -214,13 +218,14 @@ {{ wsChatMethodsService.getGroupRoom(roomId).userThatIsTyping }} está a escrever...
--> +
+ {{durationDisplay}} + +
- - + @@ -242,24 +247,34 @@ +
- +
-
+
+ - +
+
+ -
diff --git a/src/app/shared/chat/group-messages/group-messages.page.scss b/src/app/shared/chat/group-messages/group-messages.page.scss index 905a5cb1d..9742565e9 100644 --- a/src/app/shared/chat/group-messages/group-messages.page.scss +++ b/src/app/shared/chat/group-messages/group-messages.page.scss @@ -80,6 +80,10 @@ } } } + .btn-delete-recording{ + margin-left: 20px !important; + } + ion-content{ .welcome-text{ /* width: 322px; */ @@ -288,4 +292,4 @@ .typing ngx-letters-avatar { padding-right: 5px; -} \ No newline at end of file +} diff --git a/src/app/shared/chat/group-messages/group-messages.page.ts b/src/app/shared/chat/group-messages/group-messages.page.ts index e16cb668f..a50f31fac 100644 --- a/src/app/shared/chat/group-messages/group-messages.page.ts +++ b/src/app/shared/chat/group-messages/group-messages.page.ts @@ -33,6 +33,9 @@ import { element } from 'protractor'; import { FileType } from 'src/app/models/fileType'; import { ToastService } from 'src/app/services/toast.service'; import { Camera, CameraResultType, CameraSource } from '@capacitor/camera'; +import { VoiceRecorder, VoiceRecorderPlugin, RecordingData, GenericResponse, CurrentRecordingStatus } from 'capacitor-voice-recorder'; +import { Filesystem, Directory, Encoding } from '@capacitor/filesystem'; +import { DomSanitizer } from '@angular/platform-browser'; /* import * as pdfjsLib from 'pdfjs-dist'; @@ -85,7 +88,16 @@ export class GroupMessagesPage implements OnInit, OnChanges, AfterViewInit, OnDe pdfurl = "http://www.africau.edu/images/default/sample.pdf"; downloadFile: any; - showAvatar = false + showAvatar = false; + + recording = false; + allowTyping = true; + storedFileNames = []; + lastAudioRecorded = ''; + audioRecorded:any = ""; + audioDownloaded:any = ""; + durationDisplay = ''; + duration = 0; constructor( public wsChatMethodsService: WsChatMethodsService, @@ -108,6 +120,7 @@ export class GroupMessagesPage implements OnInit, OnChanges, AfterViewInit, OnDe private CameraService: CameraService, private toastService: ToastService, + private sanitiser: DomSanitizer, ) { console.log('OnCONSTRUCTOR'); @@ -134,6 +147,8 @@ export class GroupMessagesPage implements OnInit, OnChanges, AfterViewInit, OnDe this.showAvatar = true }, 50) + this.deleteRecording(); + } ngOnInit() { @@ -146,6 +161,9 @@ export class GroupMessagesPage implements OnInit, OnChanges, AfterViewInit, OnDe }, 1000); this.getChatMembers(); //this.getMessageDB(); + VoiceRecorder.requestAudioRecordingPermission(); + this.deleteRecording(); + this.loadFiles(); } @@ -229,12 +247,100 @@ export class GroupMessagesPage implements OnInit, OnChanges, AfterViewInit, OnDe this.currentPosition = scroll; } + calculateDuration() { + if (!this.recording) { + this.duration = 0; + this.durationDisplay = ''; + return; + } + this.duration += 1; + const minutes = Math.floor(this.duration / 60); + const seconds = (this.duration % 60).toString().padStart(2, '0'); + this.durationDisplay = `${minutes}:${seconds}`; + + setTimeout(() => { + this.calculateDuration(); + }, 1000) + } + + async getFile(fileName?:any){ + const audioFile = await Filesystem.readFile({ + path: fileName, + directory: Directory.Data + }) + const base64sound = audioFile.data; + const base64Response = await fetch(`data:audio/ogg;base64,${base64sound}`); + this.audioRecorded = base64Response.url; + } + + async loadFiles() { + + this.storage.get('fileName').then((fileName) => { + this.lastAudioRecorded = fileName; + }) + + this.storage.get('recordData').then((recordData) => { + console.log(recordData); + if(recordData.value.recordDataBase64.includes('data:audio')){ + this.audioRecorded = this.sanitiser.bypassSecurityTrustResourceUrl(recordData.value.recordDataBase64); + } + else{ + this.audioRecorded = this.sanitiser.bypassSecurityTrustResourceUrl(`data:${recordData.value.mimeType};base64,${recordData.value.recordDataBase64}`); + } + }); + } + + startRecording() { + console.log('Recording'); + + if (this.recording) { + return; + } + this.recording = true; + VoiceRecorder.startRecording(); + this.calculateDuration(); + } + + stopRecording() { + this.deleteRecording(); + this.allowTyping = false; + console.log('Stop'); + if (!this.recording) { + return; + } + this.recording = false; + VoiceRecorder.stopRecording().then(async (result: RecordingData) => { + console.log(result); + this.recording = false; + if (result.value && result.value.recordDataBase64) { + const recordData = result.value.recordDataBase64; + //console.log(recordData); + const fileName = new Date().getTime() + ".wav"; + //Save file + this.storage.set('fileName',fileName); + this.storage.set('recordData',result).then(() => { + console.log('Audio recorded saved'); + }) + } + }) + setTimeout(async () => { + this.loadFiles(); + }, 1000); + } + + async deleteRecording(){ + this.storage.remove('fileName'); + this.storage.remove('recordData'); + + this.allowTyping = true; + this.lastAudioRecorded = ''; + this.loadFiles(); + } + ngOnDestroy() { window.removeEventListener('scroll', this.scrollChangeCallback, true); } - - async getChatMembers() { //return await this.chatService.getMembers(roomId).toPromise(); this.chatService.getAllUsers().subscribe(res => { @@ -311,6 +417,43 @@ export class GroupMessagesPage implements OnInit, OnChanges, AfterViewInit, OnDe this.wsChatMethodsService.getGroupRoom(this.roomId).send({}) } + async sendAudio(fileName) { + + const roomId = this.roomId + this.storage.get('recordData').then((recordData) => { + console.log(recordData); + if(recordData.value.recordDataBase64.includes('data:audio')){ + this.audioRecorded = recordData.value.recordDataBase64; + } + else{ + this.audioRecorded = `data:${recordData.value.mimeType};base64,${recordData.value.recordDataBase64}`; + } + }); + + //Converting base64 to blob + const base64Response = await fetch(this.audioRecorded); + const blob = await base64Response.blob(); + + const formData = new FormData(); + formData.append("blobFile", blob); + + this.wsChatMethodsService.getGroupRoom(roomId).send({ + file: { + "type": "aplication/audio", + /* "guid": '', */ + }, + attachments: [{ + "title": fileName , + "title_link": this.audioRecorded, + "title_link_download": true, + "type": "file" + }], + temporaryData: formData + }) + this.deleteRecording(); + + } + deleteMessage(msgId: string) { const room = this.wsChatMethodsService.getGroupRoom(this.roomId) this.alertService.confirmDeleteMessage(msgId, room); @@ -842,10 +985,10 @@ export class GroupMessagesPage implements OnInit, OnChanges, AfterViewInit, OnDe if (msg.file.type == "application/img") { 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 = event.body; } - + msg.attachments[0] = { image_url: this.downloadFile, name: msg.attachments[0].name, diff --git a/src/app/shared/chat/messages/messages.module.ts b/src/app/shared/chat/messages/messages.module.ts index aec854bf1..574c55e8a 100644 --- a/src/app/shared/chat/messages/messages.module.ts +++ b/src/app/shared/chat/messages/messages.module.ts @@ -12,7 +12,7 @@ import { FontAwesomeModule } from '@fortawesome/angular-fontawesome'; import { MatButtonModule } from '@angular/material/button'; import {MatMenuModule} from '@angular/material/menu'; import { LettersAvatarModule } from "ngx-letters-avatar"; -import { PdfViewerModule } from 'ng2-pdf-viewer'; +import { PipesModule } from 'src/app/pipes/pipes.module'; @NgModule({ imports: [ @@ -24,7 +24,7 @@ import { PdfViewerModule } from 'ng2-pdf-viewer'; MatButtonModule, MatMenuModule, LettersAvatarModule, - PdfViewerModule + PipesModule, ], exports: [MessagesPage], diff --git a/src/app/shared/chat/messages/messages.page.html b/src/app/shared/chat/messages/messages.page.html index 634451a61..1315f0bd3 100644 --- a/src/app/shared/chat/messages/messages.page.html +++ b/src/app/shared/chat/messages/messages.page.html @@ -96,7 +96,7 @@
-
+
@@ -113,11 +113,14 @@ {{file.title}}
-
+
+ +
+
{{file.description}} - {{msg.displayType}} + {{msg.displayType}} @@ -169,14 +172,14 @@ fontFamily="Roboto"> está a escrever...
+
+ {{durationDisplay}} + +
- - - + @@ -198,30 +201,34 @@ +
- - - - +
+
- - +
diff --git a/src/app/shared/chat/messages/messages.page.scss b/src/app/shared/chat/messages/messages.page.scss index 3112f005a..f594b8b3f 100644 --- a/src/app/shared/chat/messages/messages.page.scss +++ b/src/app/shared/chat/messages/messages.page.scss @@ -328,4 +328,4 @@ display: block; .typing ngx-letters-avatar { padding-right: 5px; -} \ No newline at end of file +} diff --git a/src/app/shared/chat/messages/messages.page.ts b/src/app/shared/chat/messages/messages.page.ts index 7023dc705..d808f3411 100644 --- a/src/app/shared/chat/messages/messages.page.ts +++ b/src/app/shared/chat/messages/messages.page.ts @@ -33,6 +33,9 @@ import { ProcessesService } from 'src/app/services/processes.service'; import { FileToBase64Service } from 'src/app/services/file/file-to-base64.service'; import { Camera, CameraResultType, CameraSource } from '@capacitor/camera'; import { DocumentViewer, DocumentViewerOptions } from '@ionic-native/document-viewer'; +import { VoiceRecorder, VoiceRecorderPlugin, RecordingData, GenericResponse, CurrentRecordingStatus } from 'capacitor-voice-recorder'; +import { Filesystem, Directory, Encoding } from '@capacitor/filesystem'; +import { DomSanitizer } from '@angular/platform-browser'; const IMAGE_DIR = 'stored-images'; @Component({ @@ -77,7 +80,16 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy downloadFile: any; massages: MessageService[] = [] - showAvatar = true + showAvatar = true; + + recording = false; + allowTyping = true; + storedFileNames = []; + lastAudioRecorded = ''; + audioRecorded:any = ""; + audioDownloaded:any = ""; + durationDisplay = ''; + duration = 0; constructor( public popoverController: PopoverController, @@ -106,6 +118,7 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy private CameraService: CameraService, private processesService: ProcessesService, private fileToBase64Service: FileToBase64Service, + private sanitiser: DomSanitizer, ) { this.loggedUser = authService.ValidatedUserChat['data']; @@ -129,13 +142,17 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy this.showAvatar = true }, 150) + this.deleteRecording() + } ngOnInit() { this.scrollToBottom(); this.getChatMembers(); - + VoiceRecorder.requestAudioRecordingPermission(); + this.deleteRecording(); + this.loadFiles(); } @@ -208,6 +225,96 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy this.currentPosition = scroll; } + calculateDuration() { + if (!this.recording) { + this.duration = 0; + this.durationDisplay = ''; + return; + } + this.duration += 1; + const minutes = Math.floor(this.duration / 60); + const seconds = (this.duration % 60).toString().padStart(2, '0'); + this.durationDisplay = `${minutes}:${seconds}`; + + setTimeout(() => { + this.calculateDuration(); + }, 1000) + } + + async getFile(fileName?:any){ + const audioFile = await Filesystem.readFile({ + path: fileName, + directory: Directory.Data + }) + const base64sound = audioFile.data; + const base64Response = await fetch(`data:audio/ogg;base64,${base64sound}`); + this.audioRecorded = base64Response.url; + } + + async loadFiles() { + + this.storage.get('fileName').then((fileName) => { + this.lastAudioRecorded = fileName; + }) + + this.storage.get('recordData').then((recordData) => { + console.log(recordData); + if(recordData.value.recordDataBase64.includes('data:audio')){ + this.audioRecorded = this.sanitiser.bypassSecurityTrustResourceUrl(recordData.value.recordDataBase64); + } + else{ + this.audioRecorded = this.sanitiser.bypassSecurityTrustResourceUrl(`data:${recordData.value.mimeType};base64,${recordData.value.recordDataBase64}`); + } + }); + } + + startRecording() { + console.log('Recording'); + + if (this.recording) { + return; + } + this.recording = true; + VoiceRecorder.startRecording(); + this.calculateDuration(); + } + + stopRecording() { + this.deleteRecording(); + this.allowTyping = false; + console.log('Stop'); + if (!this.recording) { + return; + } + this.recording = false; + VoiceRecorder.stopRecording().then(async (result: RecordingData) => { + console.log(result); + this.recording = false; + if (result.value && result.value.recordDataBase64) { + const recordData = result.value.recordDataBase64; + //console.log(recordData); + const fileName = new Date().getTime() + ".wav"; + //Save file + this.storage.set('fileName',fileName); + this.storage.set('recordData',result).then(() => { + console.log('Audio recorded saved'); + }) + } + }) + setTimeout(async () => { + this.loadFiles(); + }, 1000); + } + + async deleteRecording(){ + this.storage.remove('fileName'); + this.storage.remove('recordData'); + + this.allowTyping = true; + this.lastAudioRecorded = ''; + this.loadFiles(); + } + ngOnDestroy() { this.checktimeOut = false; window.removeEventListener('scroll', this.scrollChangeCallback, true); @@ -749,7 +856,7 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy if (msg.file.type == "application/img") { 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 = event.body; } diff --git a/src/assets/audio/Audiorecord.mp3 b/src/assets/audio/Audiorecord.mp3 new file mode 100644 index 000000000..7f06c568b Binary files /dev/null and b/src/assets/audio/Audiorecord.mp3 differ diff --git a/src/assets/icon/theme/default/icons-chat-record-audio.svg b/src/assets/icon/theme/default/icons-chat-record-audio.svg new file mode 100644 index 000000000..867be5447 --- /dev/null +++ b/src/assets/icon/theme/default/icons-chat-record-audio.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/assets/icon/theme/gov/icons-chat-record-audio.svg b/src/assets/icon/theme/gov/icons-chat-record-audio.svg new file mode 100644 index 000000000..6e90079a1 --- /dev/null +++ b/src/assets/icon/theme/gov/icons-chat-record-audio.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/assets/images/theme/gov/icons-chat-record-audio.svg b/src/assets/images/theme/gov/icons-chat-record-audio.svg new file mode 100644 index 000000000..48eb285e7 --- /dev/null +++ b/src/assets/images/theme/gov/icons-chat-record-audio.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/environments/environment.ts b/src/environments/environment.ts index 2c9100ef6..cd809f519 100644 --- a/src/environments/environment.ts +++ b/src/environments/environment.ts @@ -5,7 +5,7 @@ export const environment = { production: false, apiURL: 'https://gabinetedigital.dyndns.info/GabineteDigital.Services/V5/api/', - // apiURL: 'http://gpr-dev-01.gabinetedigital.local/GabineteDigital.Services/V5/api/', + //apiURL: 'http://gpr-dev-01.gabinetedigital.local/GabineteDigital.Services/V5/api/', apiChatUrl: 'https://gabinetedigitalchat.dyndns.info/api/v1/', apiWsChatUrl: 'wss://gabinetedigitalchat.dyndns.info/websocket', //apiChatUrl: 'https://www.tabularium.pt/api/v1/', diff --git a/src/global.scss b/src/global.scss index 585fca574..4e6f94865 100644 --- a/src/global.scss +++ b/src/global.scss @@ -1138,6 +1138,7 @@ ngx-mat-datetime-content{ .messages{ .messages-list-item-wrapper{ .message-item{ + overflow: auto; .message-item-options{ .message-options-icon{ display: none; @@ -1146,6 +1147,11 @@ ngx-mat-datetime-content{ position: absolute !important; } } + .audio-contentainer{ + width: 200px !important; + display: flex; + overflow: auto !important; + } .title{ //border: 1px solid blue; @@ -1183,15 +1189,20 @@ ngx-mat-datetime-content{ //font-weight: 400; } +.add-attachment-bg-color{ + background-color: #42b9fe13; +} + .message-attachments{ border-radius: 5px; - background-color: #42b9fe13; - padding: 1px; + //background-color: #42b9fe13; .file{ width: 100%; align-items: center; overflow: auto; color: #000; + //border: 1px solid blue; + padding: 1px; ion-thumbnail{ --size: 20px; @@ -1199,7 +1210,7 @@ ngx-mat-datetime-content{ .file-details{ max-width: 100%; padding-left: 5px; - + padding: 1px; /* .file-title{ padding-left: 5px; } */ @@ -1238,6 +1249,13 @@ ngx-mat-datetime-content{ .powerpoint-icon{ color: #d24726; } +.icon-size-45{ + font-size: 45px !important; +} +.icon-size-27{ + font-size: 27px !important; + color: #797979; +} .menu-icon{ color: #42b9fe; padding: 0 5px 0 5px; diff --git a/src/plugin/player.js b/src/plugin/player.js new file mode 100644 index 000000000..642dc5645 --- /dev/null +++ b/src/plugin/player.js @@ -0,0 +1,19 @@ +{ + class AudioPlayer extends HTMLElement{ + constructor(){ + super() + + this.attachShadow({ mode: 'open' }); + this.render(); + } + + render(){ + this.shadowRoot.innerHTML = ` + + `; + } + + + } + customElements.define('audio-player', AudioPlayer) +}