diff --git a/.gitignore b/.gitignore index 5528da384..e1a04cb82 100644 --- a/.gitignore +++ b/.gitignore @@ -51,5 +51,6 @@ src/assets/www/pdfjs/web/compressed.tracemonkey-pldi-09.pdf.pdf node_modules_ node_modules__ plugins_ +android ios src/plugin/beast-orm diff --git a/android/app/capacitor.build.gradle b/android/app/capacitor.build.gradle index 0e5e194e7..230e0d62d 100644 --- a/android/app/capacitor.build.gradle +++ b/android/app/capacitor.build.gradle @@ -24,7 +24,10 @@ 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 "androidx.appcompat:appcompat:1.0.0" + implementation "com.android.support:support-v4:27.+" implementation "com.squareup.okhttp:okhttp-urlconnection:2+" } apply from: "../../node_modules/com-sarriaroman-photoviewer/src/android/photoviewer.gradle" diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 66301e3a7..e55b6e225 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -1,6 +1,6 @@ - + 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/android/app/src/main/assets/capacitor.config.json b/android/app/src/main/assets/capacitor.config.json index 2399c4927..eeb28f218 100644 --- a/android/app/src/main/assets/capacitor.config.json +++ b/android/app/src/main/assets/capacitor.config.json @@ -16,5 +16,8 @@ "sound" ] } + }, + "server": { + "url": "http://192.168.0.69:8101" } } 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/app/src/main/res/xml/config.xml b/android/app/src/main/res/xml/config.xml index ce530bfc9..48aee8664 100644 --- a/android/app/src/main/res/xml/config.xml +++ b/android/app/src/main/res/xml/config.xml @@ -10,11 +10,28 @@ + + + + + + + + + + + + + + + + + @@ -40,11 +57,6 @@ - - - - - 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/angular.json b/angular.json index ecd38fe24..191cebb37 100644 --- a/angular.json +++ b/angular.json @@ -25,6 +25,11 @@ "input": "src/assets", "output": "assets" }, + { + "glob": "**/*", + "input": "node_modules/ngx-extended-pdf-viewer/assets/", + "output": "/assets/" + }, { "glob": "**/*.svg", "input": "node_modules/ionicons/dist/ionicons/svg", diff --git a/config.xml b/config.xml index 7a4d9177f..17e317687 100644 --- a/config.xml +++ b/config.xml @@ -22,7 +22,7 @@ - + @@ -46,49 +46,6 @@ - - 3077110622 - 3619450036 - - - - - - 1979143311 - 1328564293 - - - - - - - 0 - - - - - - 0 - - - - - - 0 - - - - - 0 - - 8.0.0.00-20210905-154328 - - - - - en - /adapters/MobileAPIProxy - 2 diff --git a/package-lock.json b/package-lock.json index cc410f1a9..3c9b825e8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -799,12 +799,79 @@ "integrity": "sha512-H71nDOOL8Y7kWRLqf6Sums+01Q5msqBW2KhDUTemh1tvY04eSkSXrK0uj/4mmY0Xr16/3zyZmsrxN7CKuRbNRg==", "dev": true }, - "@awesome-cordova-plugins/media-capture": { + "@awesome-cordova-plugins/core": { "version": "5.40.0", - "resolved": "https://registry.npmjs.org/@awesome-cordova-plugins/media-capture/-/media-capture-5.40.0.tgz", - "integrity": "sha512-Es5qhC6VeCzo0pq0V9txlMwSL3v1ZAUKtT74DDsTnItvbX56ZPdawL4u4fLA40VikaRNYZbYNnkYopifb8nJIw==", + "resolved": "https://registry.npmjs.org/@awesome-cordova-plugins/core/-/core-5.40.0.tgz", + "integrity": "sha512-tk5QlnXfSE2Zu3mJVC3f11Guu5iqnLtNkvvClNHjz/e4FsJEmprfXWCv/QImWs5fLsismHcn31LKYBfWIhOv9g==", "requires": { "@types/cordova": "^0.0.34" + }, + "dependencies": { + "@types/cordova": { + "version": "0.0.34", + "resolved": "https://registry.npmjs.org/@types/cordova/-/cordova-0.0.34.tgz", + "integrity": "sha1-6nrd907Ow9dimCegw54smt3HPQQ=" + } + } + }, + "@awesome-cordova-plugins/document-viewer": { + "version": "5.41.0", + "resolved": "https://registry.npmjs.org/@awesome-cordova-plugins/document-viewer/-/document-viewer-5.41.0.tgz", + "integrity": "sha512-90zZvtYuCHTvK55LDoESd7F3OtuDj8AJ0C0Owz+PqZq2J2fUP4fzd7lJE89Cp6vZet7rjiOz7d/8hbTxKMWsdg==", + "requires": { + "@types/cordova": "^0.0.34" + }, + "dependencies": { + "@types/cordova": { + "version": "0.0.34", + "resolved": "https://registry.npmjs.org/@types/cordova/-/cordova-0.0.34.tgz", + "integrity": "sha1-6nrd907Ow9dimCegw54smt3HPQQ=" + } + } + }, + "@awesome-cordova-plugins/file": { + "version": "5.41.0", + "resolved": "https://registry.npmjs.org/@awesome-cordova-plugins/file/-/file-5.41.0.tgz", + "integrity": "sha512-1UrtbRdHIDZEFD6UnKFeBpITK+UqrAhr/saJmMsXLjCtsdJFB05abNHzcfdBO+z3mQFK/DnMQ0YdYJtR5x6zYw==", + "requires": { + "@types/cordova": "^0.0.34" + }, + "dependencies": { + "@types/cordova": { + "version": "0.0.34", + "resolved": "https://registry.npmjs.org/@types/cordova/-/cordova-0.0.34.tgz", + "integrity": "sha1-6nrd907Ow9dimCegw54smt3HPQQ=" + } + } + }, + "@awesome-cordova-plugins/file-opener": { + "version": "5.41.0", + "resolved": "https://registry.npmjs.org/@awesome-cordova-plugins/file-opener/-/file-opener-5.41.0.tgz", + "integrity": "sha512-CFdAum1EOxSdi+yMzEkOribU/joaDiqs1lL/ddxj7I78ryzlU+dj7rg6HZKvAN7aTjbWTX6A3p628eNpQoopgg==", + "requires": { + "@types/cordova": "^0.0.34" + }, + "dependencies": { + "@types/cordova": { + "version": "0.0.34", + "resolved": "https://registry.npmjs.org/@types/cordova/-/cordova-0.0.34.tgz", + "integrity": "sha1-6nrd907Ow9dimCegw54smt3HPQQ=" + } + } + }, + "@awesome-cordova-plugins/multiple-document-picker": { + "version": "5.40.0", + "resolved": "https://registry.npmjs.org/@awesome-cordova-plugins/multiple-document-picker/-/multiple-document-picker-5.40.0.tgz", + "integrity": "sha512-7mYRo2yulfgStK0XsPaTUJigFbYwlQy/qWjLRbNHMbEUOk372a/HnjTUwFBFT+oWX8k0Rn9hjX50Xsqoz46hyQ==", + "requires": { + "@types/cordova": "^0.0.34" + }, + "dependencies": { + "@types/cordova": { + "version": "0.0.34", + "resolved": "https://registry.npmjs.org/@types/cordova/-/cordova-0.0.34.tgz", + "integrity": "sha1-6nrd907Ow9dimCegw54smt3HPQQ=" + } } }, "@babel/code-frame": { @@ -3059,6 +3126,21 @@ } } }, + "@ionic-native/file-opener": { + "version": "5.36.0", + "resolved": "https://registry.npmjs.org/@ionic-native/file-opener/-/file-opener-5.36.0.tgz", + "integrity": "sha512-UKp3pbqvQXsAtLMJ5JE+KcTMxpjSZMFebf6nvy/KJvwy85JGIaCV4ZVM/H9CFUrHJMWBH6wDbY+WPygnsrl4Yg==", + "requires": { + "@types/cordova": "^0.0.34" + }, + "dependencies": { + "@types/cordova": { + "version": "0.0.34", + "resolved": "https://registry.npmjs.org/@types/cordova/-/cordova-0.0.34.tgz", + "integrity": "sha1-6nrd907Ow9dimCegw54smt3HPQQ=" + } + } + }, "@ionic-native/file-path": { "version": "5.36.0", "resolved": "https://registry.npmjs.org/@ionic-native/file-path/-/file-path-5.36.0.tgz", @@ -5077,6 +5159,11 @@ "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", @@ -5525,23 +5612,6 @@ "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=", "dev": true }, - "android-versions": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/android-versions/-/android-versions-1.7.0.tgz", - "integrity": "sha512-TCy4b8Dk8YS6A23ZPfhSKqK66JHFq0D8avGYiwvYpjno6HrrcI0DRgHx9+jtkvWYmrsE2vQWgbHJhvGGhhOb0g==", - "dev": true, - "requires": { - "semver": "^5.7.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, "angular-calendar": { "version": "0.28.28", "resolved": "https://registry.npmjs.org/angular-calendar/-/angular-calendar-0.28.28.tgz", @@ -6242,8 +6312,7 @@ "big.js": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "dev": true + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==" }, "binary-extensions": { "version": "2.2.0", @@ -6971,6 +7040,29 @@ "get-blob-duration": "^1.2.0" } }, + "capacitor2-file-picker": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/capacitor2-file-picker/-/capacitor2-file-picker-1.0.0.tgz", + "integrity": "sha512-mumuW44Bx6mMK0V5KEifu6EgBGPsWQ/kXKWMIaHGFYYUtmZTVpDl2DWiQe6VYFbaemhT+0C1EvKbP681RpLOpQ==", + "requires": { + "@capacitor/core": "^2.4.7" + }, + "dependencies": { + "@capacitor/core": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@capacitor/core/-/core-2.5.0.tgz", + "integrity": "sha512-WUkUnqqLtlEYn6tly8t6VR0ABlSVbXdlD/gBbYxx0P+gEqMF9b46uYb2YqyH+8HBDANzTweEySpLfhiSUvYS7w==", + "requires": { + "tslib": "^1.9.0" + } + }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + } + } + }, "capture-exit": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz", @@ -7264,8 +7356,7 @@ "co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", - "dev": true + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" }, "code-point-at": { "version": "1.1.0", @@ -7793,21 +7884,345 @@ } }, "cordova-android": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/cordova-android/-/cordova-android-9.1.0.tgz", - "integrity": "sha512-bzOX9E4eQsOSpa06oZZ7XAGq3DwB73juhhj0oPqHH/khWk0mkCD4aiVYMFoc0fmIaSQvzbY1ww7L6UBW5pyGfg==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cordova-android/-/cordova-android-5.0.0.tgz", + "integrity": "sha1-vFlPYEhSWGz3500gQqNzH9dts6o=", "dev": true, "requires": { - "android-versions": "^1.5.0", - "cordova-common": "^4.0.1", - "execa": "^4.0.2", - "fast-glob": "^3.2.4", - "fs-extra": "^9.0.1", - "is-path-inside": "^3.0.2", - "nopt": "^4.0.3", - "properties-parser": "^0.3.1", - "semver": "^7.3.4", - "which": "^2.0.2" + "cordova-common": "~1.0.0", + "elementtree": "^0.1.6", + "nopt": "^3.0.1", + "properties-parser": "^0.2.3", + "q": "^1.4.1", + "shelljs": "^0.5.3" + }, + "dependencies": { + "cordova-common": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "bplist-parser": "^0.1.0", + "cordova-registry-mapper": "^1.1.8", + "elementtree": "^0.1.6", + "glob": "^5.0.13", + "osenv": "^0.1.3", + "plist": "^1.1.0", + "q": "^1.4.1", + "semver": "^5.0.1", + "shelljs": "^0.5.1", + "underscore": "^1.8.3", + "unorm": "^1.3.3" + }, + "dependencies": { + "bplist-parser": { + "version": "0.1.0", + "bundled": true, + "dev": true + }, + "cordova-registry-mapper": { + "version": "1.1.13", + "bundled": true, + "dev": true, + "requires": { + "tape": "^3.5.0" + }, + "dependencies": { + "tape": { + "version": "3.5.0", + "bundled": true, + "dev": true, + "requires": { + "deep-equal": "~0.2.0", + "defined": "~0.0.0", + "glob": "~3.2.9", + "inherits": "~2.0.1", + "object-inspect": "~0.4.0", + "resumer": "~0.0.0", + "through": "~2.3.4" + }, + "dependencies": { + "deep-equal": { + "version": "0.2.2", + "bundled": true, + "dev": true + }, + "defined": { + "version": "0.0.0", + "bundled": true, + "dev": true + }, + "glob": { + "version": "3.2.11", + "bundled": true, + "dev": true, + "requires": { + "inherits": "2", + "minimatch": "0.3" + }, + "dependencies": { + "minimatch": { + "version": "0.3.0", + "bundled": true, + "dev": true, + "requires": { + "lru-cache": "2", + "sigmund": "~1.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "2.7.0", + "bundled": true, + "dev": true + }, + "sigmund": { + "version": "1.0.1", + "bundled": true, + "dev": true + } + } + } + } + }, + "inherits": { + "version": "2.0.1", + "bundled": true, + "dev": true + }, + "object-inspect": { + "version": "0.4.0", + "bundled": true, + "dev": true + }, + "resumer": { + "version": "0.0.0", + "bundled": true, + "dev": true, + "requires": { + "through": "~2.3.4" + } + }, + "through": { + "version": "2.3.8", + "bundled": true, + "dev": true + } + } + } + } + }, + "glob": { + "version": "5.0.15", + "bundled": true, + "dev": true, + "requires": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "dependencies": { + "inflight": { + "version": "1.0.4", + "bundled": true, + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + }, + "dependencies": { + "wrappy": { + "version": "1.0.1", + "bundled": true, + "dev": true + } + } + }, + "inherits": { + "version": "2.0.1", + "bundled": true, + "dev": true + }, + "minimatch": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "brace-expansion": "^1.0.0" + }, + "dependencies": { + "brace-expansion": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "requires": { + "balanced-match": "^0.2.0", + "concat-map": "0.0.1" + }, + "dependencies": { + "balanced-match": { + "version": "0.2.1", + "bundled": true, + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true + } + } + } + } + }, + "once": { + "version": "1.3.2", + "bundled": true, + "dev": true, + "requires": { + "wrappy": "1" + }, + "dependencies": { + "wrappy": { + "version": "1.0.1", + "bundled": true, + "dev": true + } + } + }, + "path-is-absolute": { + "version": "1.0.0", + "bundled": true, + "dev": true + } + } + }, + "osenv": { + "version": "0.1.3", + "bundled": true, + "dev": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + }, + "dependencies": { + "os-homedir": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "os-tmpdir": { + "version": "1.0.1", + "bundled": true, + "dev": true + } + } + }, + "plist": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "requires": { + "base64-js": "0.0.6", + "util-deprecate": "1.0.0", + "xmlbuilder": "2.2.1", + "xmldom": "0.1.x" + }, + "dependencies": { + "base64-js": { + "version": "0.0.6", + "bundled": true, + "dev": true + }, + "util-deprecate": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "xmlbuilder": { + "version": "2.2.1", + "bundled": true, + "dev": true, + "requires": { + "lodash-node": "~2.4.1" + }, + "dependencies": { + "lodash-node": { + "version": "2.4.1", + "bundled": true, + "dev": true + } + } + }, + "xmldom": { + "version": "0.1.19", + "bundled": true, + "dev": true + } + } + }, + "semver": { + "version": "5.0.3", + "bundled": true, + "dev": true + }, + "underscore": { + "version": "1.8.3", + "bundled": true, + "dev": true + }, + "unorm": { + "version": "1.4.1", + "bundled": true, + "dev": true + } + } + }, + "elementtree": { + "version": "0.1.6", + "bundled": true, + "dev": true, + "requires": { + "sax": "0.3.5" + }, + "dependencies": { + "sax": { + "version": "0.3.5", + "bundled": true, + "dev": true + } + } + }, + "nopt": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "requires": { + "abbrev": "1" + }, + "dependencies": { + "abbrev": { + "version": "1.0.7", + "bundled": true, + "dev": true + } + } + }, + "properties-parser": { + "version": "0.2.3", + "bundled": true, + "dev": true + }, + "q": { + "version": "1.4.1", + "bundled": true, + "dev": true + }, + "shelljs": { + "version": "0.5.3", + "bundled": true, + "dev": true + } } }, "cordova-android-support-gradle-release": { @@ -8149,11 +8564,20 @@ "integrity": "sha512-FUHI6eEVeoz2VkxbF0P56QlUQLGzXcvw3i4xuXyM9gEct6Y+FA3Xzgl2pJTZcTg5wRqLWzN08kgNoHPkom15pw==", "dev": true }, + "cordova-plugin-document-viewer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/cordova-plugin-document-viewer/-/cordova-plugin-document-viewer-1.0.0.tgz", + "integrity": "sha512-LQZiWVU543rLJ0wYoawSdMrAfoxBLWCx8a2CuQjFeav4U9CN16QAh1VHetHaHicp5ZEwTC7Zq/0TNbak6A7bVw==" + }, "cordova-plugin-file": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/cordova-plugin-file/-/cordova-plugin-file-6.0.2.tgz", - "integrity": "sha512-m7cughw327CjONN/qjzsTpSesLaeybksQh420/gRuSXJX5Zt9NfgsSbqqKDon6jnQ9Mm7h7imgyO2uJ34XMBtA==", - "dev": true + "integrity": "sha512-m7cughw327CjONN/qjzsTpSesLaeybksQh420/gRuSXJX5Zt9NfgsSbqqKDon6jnQ9Mm7h7imgyO2uJ34XMBtA==" + }, + "cordova-plugin-file-opener2": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/cordova-plugin-file-opener2/-/cordova-plugin-file-opener2-3.0.5.tgz", + "integrity": "sha512-tjLHDamH5+y0bJZYVe2967L1S4R8tL4Y0rJUzJGoxsyiw3FUlrJNS199POOpzZZ6Xhlntn9a2o7+84r1dMN21A==" }, "cordova-plugin-filepath": { "version": "1.6.0", @@ -8190,6 +8614,11 @@ "integrity": "sha512-pVQOrNM7VAuVUMXibAlMGIArrftHPrRs4dUCoE+e2HEFUp3LmN3Yj539LjdUxcWmz/A/cHC65m9E3DS56YJhcg==", "dev": true }, + "cordova-plugin-multiple-documents-picker": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/cordova-plugin-multiple-documents-picker/-/cordova-plugin-multiple-documents-picker-1.0.0.tgz", + "integrity": "sha512-MXc1A6bP8/gOSxRRijj5Tp61Sm4zd+yxz5s5ssWD/VQV+MWK88THPZyDuQ2efUbFVs6i2T255mkboLsEEY8EXQ==" + }, "cordova-plugin-network-information": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cordova-plugin-network-information/-/cordova-plugin-network-information-3.0.0.tgz", @@ -9536,8 +9965,7 @@ "emojis-list": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "dev": true + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==" }, "enabled": { "version": "2.0.0", @@ -15741,6 +16169,11 @@ "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=" }, + "lodash.deburr": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/lodash.deburr/-/lodash.deburr-4.1.0.tgz", + "integrity": "sha1-3bG7s+8HRYwBd7oH3hRCLLAz/5s=" + }, "lodash.isfinite": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/lodash.isfinite/-/lodash.isfinite-3.3.2.tgz", @@ -16547,6 +16980,26 @@ "tslib": "^2.3.0" } }, + "ng2-pdf-viewer": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/ng2-pdf-viewer/-/ng2-pdf-viewer-3.0.8.tgz", + "integrity": "sha512-p2qndFu1wQW4y+xXXw7yk1BhpRo5PGHKWD3PTc7pUULujx9d2vT26lhXR3p9WHitySadGqdCQpkA7W3v1dBlSg==", + "requires": { + "@types/pdfjs-dist": "^0.1.1", + "pdfjs-dist": "1.9.489" + }, + "dependencies": { + "pdfjs-dist": { + "version": "1.9.489", + "resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-1.9.489.tgz", + "integrity": "sha1-yuWf7d0WouXRlappUnlVz+QALB0=", + "requires": { + "node-ensure": "^0.0.0", + "worker-loader": "^0.8.0" + } + } + } + }, "ngx-cookie-service": { "version": "12.0.3", "resolved": "https://registry.npmjs.org/ngx-cookie-service/-/ngx-cookie-service-12.0.3.tgz", @@ -16555,6 +17008,15 @@ "tslib": "^2.0.0" } }, + "ngx-extended-pdf-viewer": { + "version": "13.0.0-alpha.2", + "resolved": "https://registry.npmjs.org/ngx-extended-pdf-viewer/-/ngx-extended-pdf-viewer-13.0.0-alpha.2.tgz", + "integrity": "sha512-/+aTZVW8uubzWHI1KK4eC6QaS2I59IHnJI/0jgyhDkF2bXywB+PR7O/g4aEstRU56lzayh/W8YGSAJbB8tobkw==", + "requires": { + "lodash.deburr": "^4.1.0", + "tslib": "^2.3.0" + } + }, "ngx-image-compress": { "version": "11.0.3", "resolved": "https://registry.npmjs.org/ngx-image-compress/-/ngx-image-compress-11.0.3.tgz", @@ -16632,6 +17094,11 @@ "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", @@ -19009,15 +19476,6 @@ "read": "1" } }, - "properties-parser": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/properties-parser/-/properties-parser-0.3.1.tgz", - "integrity": "sha1-ExbpU5/7/ZOEXjabIRAiq9R4dxo=", - "dev": true, - "requires": { - "string.prototype.codepointat": "^0.2.0" - } - }, "protobufjs": { "version": "6.11.2", "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.2.tgz", @@ -24841,6 +25299,64 @@ "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 b208ddaa9..3ea0653a1 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,11 @@ "@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", + "@awesome-cordova-plugins/core": "^5.40.0", + "@awesome-cordova-plugins/document-viewer": "^5.41.0", + "@awesome-cordova-plugins/file": "^5.41.0", + "@awesome-cordova-plugins/file-opener": "^5.41.0", + "@awesome-cordova-plugins/multiple-document-picker": "^5.40.0", "@byteowls/capacitor-filesharer": "^3.0.0", "@capacitor-community/camera-preview": "^1.2.1", "@capacitor/android": "3.3.3", @@ -63,6 +67,7 @@ "@ionic-native/document-viewer": "^5.36.0", "@ionic-native/fcm": "^5.36.0", "@ionic-native/file": "^5.36.0", + "@ionic-native/file-opener": "^5.36.0", "@ionic-native/file-path": "^5.30.0", "@ionic-native/fingerprint-aio": "^4.20.0", "@ionic-native/http": "^5.36.0", @@ -102,12 +107,17 @@ "beast-orm": "^1.0.3", "bootstrap": "^4.5.0", "build": "0.1.4", - "capacitor-voice-recorder": "^2.1.0", + "capacitor-voice-recorder": "^2.0.0", + "capacitor2-file-picker": "^1.0.0", "ci": "^2.1.1", "cordova": "^10.0.0", "cordova-plugin-crop": "^0.4.0", "cordova-plugin-dbcopy": "git+https://github.com/an-rahulpandey/cordova-plugin-dbcopy.git", + "cordova-plugin-document-viewer": "^1.0.0", + "cordova-plugin-file": "^6.0.2", + "cordova-plugin-file-opener2": "^3.0.5", "cordova-plugin-filepath": "^1.5.8", + "cordova-plugin-multiple-documents-picker": "^1.0.0", "cordova-plugin-okhttp": "^2.0.0", "cordova-plugin-screen-orientation": "^3.0.2", "cordova-res": "^0.15.3", @@ -136,7 +146,9 @@ "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-extended-pdf-viewer": "^13.0.0-alpha.2", "ngx-image-compress": "^11.0.3", "ngx-image-cropper": "^5.0.1", "ngx-letters-avatar": "^1.0.2", @@ -171,14 +183,13 @@ "@types/node": "^12.11.1", "codelyzer": "^6.0.0", "com-sarriaroman-photoviewer": "^1.2.5", - "cordova-android": "^9.1.0", + "cordova-android": "^5.0.0", "cordova-android-support-gradle-release": "^3.0.1", "cordova-browser": "^6.0.0", "cordova-plugin-androidx": "^3.0.0", "cordova-plugin-androidx-adapter": "^1.1.3", "cordova-plugin-device": "^2.0.2", "cordova-plugin-dialogs": "^2.0.2", - "cordova-plugin-file": "^6.0.2", "cordova-plugin-fingerprint-aio": "^4.0.2", "cordova-plugin-globalization": "^1.11.0", "cordova-plugin-inappbrowser": "^4.0.0", diff --git a/src/app/app.module.ts b/src/app/app.module.ts index e20702ceb..9a2d12d50 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -32,6 +32,11 @@ 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 { MultipleDocumentsPicker } from '@awesome-cordova-plugins/multiple-document-picker/ngx'; +import { DocumentViewer } from '@awesome-cordova-plugins/document-viewer/ngx'; + + + import { NgxMatDatetimePickerModule, NgxMatNativeDateModule, @@ -55,13 +60,15 @@ 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 { File } from '@awesome-cordova-plugins/file/ngx'; import { StreamingMedia } from '@ionic-native/streaming-media/ngx'; import { PhotoViewer } from '@ionic-native/photo-viewer/ngx'; import {NgxImageCompressService} from 'ngx-image-compress'; import { CustomImageCachePageRoutingModule } from './services/file/custom-image-cache/custom-image-cache-routing.module'; import { IonicImageLoaderComponent, IonicImageLoaderModule } from 'ionic-image-loader-v5'; +import { NgxExtendedPdfViewerModule } from 'ngx-extended-pdf-viewer'; +import { FileOpener } from '@awesome-cordova-plugins/file-opener/ngx'; /* import { FCM } from '@ionic-native/fcm/ngx'; import { FirebaseX } from '@ionic-native/firebase-x/ngx'; */ @@ -127,7 +134,6 @@ import { FirebaseX } from '@ionic-native/firebase-x/ngx'; */ ChatService, ScreenOrientation, Network, - File, SQLite, CookieService, ImagePicker, @@ -136,6 +142,11 @@ import { FirebaseX } from '@ionic-native/firebase-x/ngx'; */ StreamingMedia, PhotoViewer, NgxImageCompressService, + MultipleDocumentsPicker, + NgxExtendedPdfViewerModule, + FileOpener, + DocumentViewer + ], bootstrap: [AppComponent], schemas: [CUSTOM_ELEMENTS_SCHEMA] diff --git a/src/app/modals/view-media/view-media.module.ts b/src/app/modals/view-media/view-media.module.ts index eb52e9daf..bfaf41fe9 100644 --- a/src/app/modals/view-media/view-media.module.ts +++ b/src/app/modals/view-media/view-media.module.ts @@ -8,6 +8,8 @@ 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'; +import { NgxExtendedPdfViewerModule } from 'ngx-extended-pdf-viewer'; @NgModule({ imports: [ @@ -16,6 +18,8 @@ import { FontAwesomeModule } from '@fortawesome/angular-fontawesome'; IonicModule, FontAwesomeModule, ViewMediaPageRoutingModule, + PdfViewerModule, + NgxExtendedPdfViewerModule, ], 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 b4367aac4..338c1be1f 100644 --- a/src/app/modals/view-media/view-media.page.html +++ b/src/app/modals/view-media/view-media.page.html @@ -24,6 +24,13 @@
+ + +
diff --git a/src/app/modals/view-media/view-media.page.ts b/src/app/modals/view-media/view-media.page.ts index ff6820f19..417d57199 100644 --- a/src/app/modals/view-media/view-media.page.ts +++ b/src/app/modals/view-media/view-media.page.ts @@ -1,5 +1,7 @@ import { Component, OnInit } from '@angular/core'; import { ModalController, NavParams } from '@ionic/angular'; +import { DomSanitizer} from '@angular/platform-browser'; +import { pdfDefaultOptions } from 'ngx-extended-pdf-viewer'; @Component({ selector: 'app-view-media', @@ -18,19 +20,53 @@ export class ViewMediaPage implements OnInit { maxRation: 2 }; + base64Sanitize:any = ""; + constructor( private modalController: ModalController, private navParams:NavParams, + public sanitizer: DomSanitizer, + ) { this.image = this.navParams.get('image') this.type = this.navParams.get('type') this.name = this.navParams.get('username') this._updatedAt = this.navParams.get('_updatedAt') + pdfDefaultOptions.assetsFolder = 'bleeding-edge'; } ngOnInit() { + console.log(this.image) + + this.base64Sanitize = this.sanitizer.bypassSecurityTrustResourceUrl(this.image); + console.log(this.base64Sanitize) + } + b64toBlob = (b64Data, contentType = '', sliceSize = 512) => { + const byteCharacters = atob(b64Data); + const byteArrays = []; + + for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) { + const slice = byteCharacters.slice(offset, offset + sliceSize); + + const byteNumbers = new Array(slice.length); + for (let i = 0; i < slice.length; i++) { + byteNumbers[i] = slice.charCodeAt(i); + } + + const byteArray = new Uint8Array(byteNumbers); + byteArrays.push(byteArray); + } + + const blob = new Blob(byteArrays, { type: contentType }); + return blob; + }; + + + + + close(){ this.modalController.dismiss() } 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 d10e4cf45..b53e1b254 100644 --- a/src/app/pages/chat/group-messages/group-messages.page.ts +++ b/src/app/pages/chat/group-messages/group-messages.page.ts @@ -36,6 +36,8 @@ import { VoiceRecorder, VoiceRecorderPlugin, RecordingData, GenericResponse, Cur import { Filesystem, Directory, Encoding } from '@capacitor/filesystem'; import { DomSanitizer } from '@angular/platform-browser'; import { MessageService } from 'src/app/services/chat/message.service'; +import { File } from '@awesome-cordova-plugins/file/ngx'; +import { FileOpener } from '@awesome-cordova-plugins/file-opener/ngx'; @Component({ selector: 'app-group-messages', @@ -80,8 +82,8 @@ export class GroupMessagesPage implements OnInit, AfterViewInit, OnDestroy { allowTyping = true; storedFileNames = []; lastAudioRecorded = ''; - audioRecorded:any = ""; - audioDownloaded:any = ""; + audioRecorded: any = ""; + audioDownloaded: any = ""; durationDisplay = ''; duration = 0; showAvatar = true; @@ -111,6 +113,8 @@ export class GroupMessagesPage implements OnInit, AfterViewInit, OnDestroy { private processesService: ProcessesService, private CameraService: CameraService, private sanitiser: DomSanitizer, + private file: File, + private fileOpener: FileOpener, ) { this.loggedUserChat = authService.ValidatedUserChat['data']; this.isGroupCreated = true; @@ -224,7 +228,7 @@ export class GroupMessagesPage implements OnInit, AfterViewInit, OnDestroy { }, 1000) } - async getFile(fileName?:any){ + async getFile(fileName?: any) { const audioFile = await Filesystem.readFile({ path: fileName, directory: Directory.Data @@ -254,14 +258,14 @@ export class GroupMessagesPage implements OnInit, AfterViewInit, OnDestroy { try { this.storage.get('recordData').then((recordData) => { console.log(recordData); - if(recordData?.value?.recordDataBase64.includes('data:audio')){ + if (recordData?.value?.recordDataBase64.includes('data:audio')) { this.audioRecorded = this.sanitiser.bypassSecurityTrustResourceUrl(recordData?.value?.recordDataBase64); } - else{ + else { this.audioRecorded = this.sanitiser.bypassSecurityTrustResourceUrl(`data:${recordData.value.mimeType};base64,${recordData?.value?.recordDataBase64}`); } }); - } catch (error) {} + } catch (error) { } } @@ -275,7 +279,7 @@ export class GroupMessagesPage implements OnInit, AfterViewInit, OnDestroy { } this.recording = false; VoiceRecorder.stopRecording().then(async (result: RecordingData) => { - console.log('==================================',result); + console.log('==================================', result); this.recording = false; if (result.value && result.value.recordDataBase64) { @@ -283,8 +287,8 @@ export class GroupMessagesPage implements OnInit, AfterViewInit, OnDestroy { //console.log(recordData); const fileName = new Date().getTime() + ".mp3"; //Save file - await this.storage.set('fileName',fileName) - this.storage.set('recordData',result).then(() => { + await this.storage.set('fileName', fileName) + this.storage.set('recordData', result).then(() => { console.log('Audio recorded saved', result); setTimeout(async () => { @@ -309,7 +313,7 @@ export class GroupMessagesPage implements OnInit, AfterViewInit, OnDestroy { - async deleteRecording(){ + async deleteRecording() { this.storage.remove('fileName'); this.storage.remove('recordData'); @@ -444,17 +448,17 @@ export class GroupMessagesPage implements OnInit, AfterViewInit, OnDestroy { var byteArrays = new Array(slicesCount); for (var sliceIndex = 0; sliceIndex < slicesCount; ++sliceIndex) { - var begin = sliceIndex * sliceSize; - var end = Math.min(begin + sliceSize, bytesLength); + 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); + 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 }); -} + } async sendAudio(fileName) { @@ -463,35 +467,35 @@ export class GroupMessagesPage implements OnInit, AfterViewInit, OnDestroy { this.storage.get('recordData').then((recordData) => { console.log(recordData); audioFile = recordData; - if(recordData?.value?.recordDataBase64.includes('data:audio')){ + if (recordData?.value?.recordDataBase64.includes('data:audio')) { this.audioRecorded = recordData?.value?.recordDataBase64; } - else{ + else { this.audioRecorded = `data:${recordData.value.mimeType};base64,${recordData?.value?.recordDataBase64}`; } - //Converting base64 to blob - const encodedData = btoa(this.audioRecorded); - const blob = this.base64toBlob(encodedData, recordData.value.mimeType) - console.log(blob) - const formData = new FormData(); - formData.append("blobFile", blob); + //Converting base64 to blob + const encodedData = btoa(this.audioRecorded); + const blob = this.base64toBlob(encodedData, recordData.value.mimeType) + console.log(blob) + const formData = new FormData(); + formData.append("blobFile", blob); - this.wsChatMethodsService.getGroupRoom(roomId).send({ - file: { - "type": "application/audio", - "msDuration":audioFile.value.msDuration, - "mimeType":audioFile.value.mimeType, - }, - attachments: [{ - "title": fileName , - "title_link_download": true, - "type": "audio" - }], - temporaryData: formData - }) + this.wsChatMethodsService.getGroupRoom(roomId).send({ + file: { + "type": "application/audio", + "msDuration": audioFile.value.msDuration, + "mimeType": audioFile.value.mimeType, + }, + attachments: [{ + "title": fileName, + "title_link_download": true, + "type": "audio" + }], + temporaryData: formData + }) - }); + }); this.deleteRecording(); } @@ -673,6 +677,7 @@ export class GroupMessagesPage implements OnInit, AfterViewInit, OnDestroy { "DocId": res.data.selected.Id, "Assunto": res.data.selected.Assunto, }, + temporaryData: res, attachments: [{ "title": res.data.selected.Assunto, "description": res.data.selected.DocTypeDesc, @@ -692,37 +697,60 @@ export class GroupMessagesPage implements OnInit, AfterViewInit, OnDestroy { } - async addFileToChat(types: typeof FileType[] ) { + async addFileToChat(types: typeof FileType[]) { const roomId = this.roomId const file: any = await this.fileService.getFileFromDevice(types); - console.log('Add file', file) - /* const imageData = await this.fileToBase64Service.convert(file).then((filee) => { - console.log('Add file', filee) - }) */ - const response = await fetch(file); - const blob = await response.blob(); - console.log('Add file', blob) - const formData = new FormData(); - formData.append("blobFile", blob); + console.log('Add file', JSON.stringify(await this.getBase64(file))) - this.wsChatMethodsService.getGroupRoom(roomId).send({ - file: { - "type": file.type, - "guid": '', - }, - attachments: [{ - "title": file.name , - "name": file.name , - // "text": "description", - //"image_url": file.base64String, // rocketchat - "title_link_download": false, - }], - temporaryData: formData - }) + if (file.type != "application/img" && file.type != "image/png" && file.type != "image/jpeg" && file.type != "image/gif") { + const encodedData = btoa(JSON.stringify(await this.getBase64(file))); + const blob = this.base64toBlob(encodedData, file.type) + console.log('Add Blob file', blob) + const formData = new FormData(); + formData.append('blobFile', blob); + console.log(formData) + + this.wsChatMethodsService.getGroupRoom(roomId).send({ + file: { + "type": file.type, + "guid": '', + }, + attachments: [{ + "title": file.name, + "name": file.name, + // "text": "description", + "title_link_download": false, + }], + temporaryData: formData + }); + + } else { + console.log('File type invalid') + } + + } + + getFileReader(): FileReader { + const fileReader = new FileReader(); + const zoneOriginalInstance = (fileReader as any)["__zone_symbol__originalInstance"]; + return zoneOriginalInstance || fileReader; + } + + 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); + }; + }); } @@ -980,27 +1008,99 @@ export class GroupMessagesPage implements OnInit, AfterViewInit, OnDestroy { card.el.style['z-index'] = 11; } + b64toBlob(b64Data, contentType) { + contentType = contentType || ''; + var sliceSize = 512; + b64Data = b64Data.replace(/^[^,]+,/, ''); + b64Data = b64Data.replace(/\s/g, ''); + var byteCharacters = window.atob(b64Data); + var byteArrays = []; + + for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) { + var slice = byteCharacters.slice(offset, offset + sliceSize); + + var byteNumbers = new Array(slice.length); + for (var i = 0; i < slice.length; i++) { + byteNumbers[i] = slice.charCodeAt(i); + } + + var byteArray = new Uint8Array(byteNumbers); + + byteArrays.push(byteArray); + } + + var blob = new Blob(byteArrays, { type: contentType }); + return blob; + } + + openFile(pdfString, filename) { + const blob = this.b64toBlob(pdfString, 'application/pdf') + let pathFile = '' + const fileName = filename + const contentFile = blob + if (this.platform.is('ios')) { + pathFile = this.file.documentsDirectory + } else { + pathFile = this.file.externalRootDirectory + } + console.log(pdfString) + console.log(pathFile) + console.log(contentFile) + this.file + .writeFile(pathFile, fileName, contentFile, { replace: true }) + .then(success => { + this.fileOpener + .open(pathFile + fileName, 'application/pdf') + .then(() => console.log('File is opened')) + .catch(e => console.log('Error opening file', e)); + }) + .catch(e => console.log('Error writing file', e)) + } + downloadFileMsg(msg: MessageService) { msg.downloadFileMsg() } + downloadFileFromBrowser(fileName: string, data: any): void { + const linkSource = data; + const downloadLink = document.createElement("a"); + downloadLink.href = linkSource; + downloadLink.download = fileName; + downloadLink.click(); + } + async openPreview(msg: MessageService) { - if (!msg.attachments[0].image_url ||msg.attachments[0].image_url === null || msg.attachments[0].image_url === '') { - this.downloadFileMsg(msg) - + if(msg.file.type === "application/webtrix") { + this.viewDocument(msg.file, msg.attachments.image_url) } else { - const modal = await this.modalController.create({ - component: ViewMediaPage, - cssClass: 'modal modal-desktop', - componentProps: { - image: msg.attachments[0].image_url, - type: msg.file.type, - username: msg.u.name, - _updatedAt: msg._updatedAt + if (!msg.attachments[0].image_url || msg.attachments[0].image_url === null || msg.attachments[0].image_url === '') { + this.downloadFileMsg(msg) + + } else { + + var str = msg.attachments[0].image_url; + str = str.substring(1, ((str.length) - 1)); + + if (this.platform.is('desktop') || this.platform.is('mobileweb')) { + + this.downloadFileFromBrowser(msg.attachments[0].name, str) + /* const modal = await this.modalController.create({ + component: ViewMediaPage, + cssClass: 'modal modal-desktop', + componentProps: { + image: str, + type: msg.file.type, + username: msg.u.name, + _updatedAt: msg._updatedAt + } + }); + modal.present(); */ + + } else { + this.openFile(str, msg.attachments[0].name); } - }); - modal.present(); + } } } @@ -1009,7 +1109,7 @@ export class GroupMessagesPage implements OnInit, AfterViewInit, OnDestroy { console.log(msg); if (!msg.attachments[0].title_link || msg.attachments[0].title_link === null || msg.attachments[0].title_link === '') { this.downloadFileMsg(msg) - } else {} + } else { } } } diff --git a/src/app/pages/chat/messages/messages.module.ts b/src/app/pages/chat/messages/messages.module.ts index 83d0d168c..ff08a70a5 100644 --- a/src/app/pages/chat/messages/messages.module.ts +++ b/src/app/pages/chat/messages/messages.module.ts @@ -12,7 +12,6 @@ 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: [ @@ -23,7 +22,6 @@ import { PipesModule } from 'src/app/pipes/pipes.module'; MessagesPageRoutingModule, MatMenuModule, 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 a11653d83..ccfe00101 100644 --- a/src/app/pages/chat/messages/messages.page.html +++ b/src/app/pages/chat/messages/messages.page.html @@ -84,10 +84,10 @@
-
+
+ { console.log(recordData); - if(recordData?.value?.recordDataBase64.includes('data:audio')){ + if (recordData?.value?.recordDataBase64.includes('data:audio')) { this.audioRecorded = this.sanitiser.bypassSecurityTrustResourceUrl(recordData?.value?.recordDataBase64); } - else{ + else { this.audioRecorded = this.sanitiser.bypassSecurityTrustResourceUrl(`data:${recordData.value.mimeType};base64,${recordData?.value?.recordDataBase64}`); } }); - } catch (error) {} + } catch (error) { } + - } startRecording() { @@ -228,8 +245,8 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy { } this.recording = true; VoiceRecorder.startRecording() - .then((result: GenericResponse) => console.log(result.value)) - .catch(error => console.log(error)); + .then((result: GenericResponse) => console.log(result.value)) + .catch(error => console.log(error)); this.calculateDuration(); } @@ -249,8 +266,8 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy { //console.log(recordData); const fileName = new Date().getTime() + ".mp3"; //Save file - this.storage.set('fileName',fileName); - this.storage.set('recordData',result).then(() => { + this.storage.set('fileName', fileName); + this.storage.set('recordData', result).then(() => { console.log('Audio recorded saved'); }) } @@ -260,7 +277,7 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy { }, 1000); } - async deleteRecording(){ + async deleteRecording() { this.storage.remove('fileName'); this.storage.remove('recordData'); @@ -379,17 +396,17 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy { var byteArrays = new Array(slicesCount); for (var sliceIndex = 0; sliceIndex < slicesCount; ++sliceIndex) { - var begin = sliceIndex * sliceSize; - var end = Math.min(begin + sliceSize, bytesLength); + 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); + 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 }); -} + } async sendAudio(fileName) { const roomId = this.roomId @@ -397,85 +414,48 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy { this.storage.get('recordData').then((recordData) => { audioFile = recordData; - if(recordData?.value?.recordDataBase64.includes('data:audio')){ + if (recordData?.value?.recordDataBase64.includes('data:audio')) { this.audioRecorded = recordData?.value?.recordDataBase64; } - else{ + else { this.audioRecorded = `data:${recordData.value.mimeType};base64,${recordData?.value?.recordDataBase64}`; } console.log(this.audioRecorded); - //Converting base64 to blob - const encodedData = btoa(this.audioRecorded); - const blob = this.base64toBlob(encodedData, recordData.value.mimeType) - console.log(blob) - const formData = new FormData(); - formData.append("blobFile", blob); + //Converting base64 to blob + const encodedData = btoa(this.audioRecorded); + const blob = this.base64toBlob(encodedData, recordData.value.mimeType) + console.log(blob) + const formData = new FormData(); + formData.append("blobFile", blob); - this.wsChatMethodsService.getDmRoom(roomId).send({ - file: { - "type": "application/audio", - "msDuration":audioFile.value.msDuration, - "mimeType":audioFile.value.mimeType, - }, - attachments: [{ - "title": fileName , - "title_link_download": true, - "type": "audio" - }], - temporaryData: formData - }) + this.wsChatMethodsService.getDmRoom(roomId).send({ + file: { + "type": "application/audio", + "msDuration": audioFile.value.msDuration, + "mimeType": audioFile.value.mimeType, + }, + attachments: [{ + "title": fileName, + "title_link_download": true, + "type": "audio" + }], + 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") { - //this.openViewDocumentModal(file); + viewDocument(file: any, url?: string) { + console.log() + if (file.type == "application/webtrix") { + this.openViewDocumentModal(file); } - - if (msg.attachments.type == "application/pdf") { - - try { - const writeSecretFile = async () => { - await Filesystem.writeFile({ - path: msg.attachments.name, - data: msg.attachments.image_url, - directory: Directory.Documents, - encoding: Encoding.UTF8, - }); - }; - - console.log('WRITE', writeSecretFile); - - const readSecretFile = async () => { - const contents = await Filesystem.readFile({ - path: msg.attachments.name, - directory: Directory.Documents, - encoding: Encoding.UTF8, - }); - - console.log('secrets:', contents); - }; - - console.log('READ', readSecretFile); - - } catch (e) { - console.error("Unable to write file", e); - } + else { + let fullUrl = "https://www.tabularium.pt" + url; + this.fileService.viewDocumentByUrl(fullUrl); } } @@ -708,6 +688,7 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy { "DocId": res.data.selected.Id, "Assunto": res.data.selected.Assunto, }, + temporaryData: res, attachments: [{ "title": res.data.selected.Assunto, "description": res.data.selected.DocTypeDesc, @@ -758,37 +739,62 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy { } - + getFileReader(): FileReader { + const fileReader = new FileReader(); + const zoneOriginalInstance = (fileReader as any)["__zone_symbol__originalInstance"]; + return zoneOriginalInstance || fileReader; + } async addFileToChat(types: typeof FileType[]) { const roomId = this.roomId const file: any = await this.fileService.getFileFromDevice(types); - console.log('Add file', file) - /* const imageData = await this.fileToBase64Service.convert(file).then((filee) => { - console.log('Add file', filee) - }) */ - const blob = new Blob(file, { type: file.type }) - console.log('Add file', blob) - const formData = new FormData(); - formData.append("blobFile", blob); + console.log('Add file', JSON.stringify(await this.getBase64(file))) - 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 - }) + if (file.type != "application/img" && file.type != "image/png" && file.type != "image/jpeg" && file.type != "image/gif") { + const encodedData = btoa(JSON.stringify(await this.getBase64(file))); + const blob = this.base64toBlob(encodedData, file.type) + console.log('Add Blob file', blob) + + 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 + }); + } else { + console.log('File type invalid') + } + + + + } + + 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); + }; + }); } @@ -906,39 +912,109 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy { } - testeDownload(msg: MessageService) { - this.downloadFile = ""; - this.AttachmentsService.downloadFileAndStore(msg.file.guid); - } + /* testeDownload(msg: MessageService) { + this.downloadFile = ""; + this.AttachmentsService.downloadFileAndStore(msg.file.guid); + } */ downloadFileMsg(msg: MessageService) { - msg.downloadFileMsg() + msg.downloadFileMsg(); } - testDownlod(msg: MessageService) { - this.AttachmentsService.downloadFileAndStore(msg.file.guid) + b64toBlob(b64Data, contentType) { + contentType = contentType || ''; + var sliceSize = 512; + b64Data = b64Data.replace(/^[^,]+,/, ''); + b64Data = b64Data.replace(/\s/g, ''); + var byteCharacters = window.atob(b64Data); + var byteArrays = []; + + for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) { + var slice = byteCharacters.slice(offset, offset + sliceSize); + + var byteNumbers = new Array(slice.length); + for (var i = 0; i < slice.length; i++) { + byteNumbers[i] = slice.charCodeAt(i); + } + + var byteArray = new Uint8Array(byteNumbers); + + byteArrays.push(byteArray); + } + + var blob = new Blob(byteArrays, { type: contentType }); + return blob; } + openFile(pdfString, filename, type) { + const blob = this.b64toBlob(pdfString, type) + let pathFile = '' + const fileName = filename + const contentFile = blob + if (this.platform.is('ios')) { + pathFile = this.file.documentsDirectory + } else { + pathFile = this.file.externalRootDirectory + } + console.log(pdfString) + console.log(pathFile) + console.log(contentFile) + this.file + .writeFile(pathFile, fileName, contentFile, { replace: true }) + .then(success => { + this.fileOpener + .open(pathFile + fileName, type) + .then(() => console.log('File is opened')) + .catch(e => console.log('Error opening file', e)); + }) + .catch(e => console.log('Error writing file', e)) + } + + downloadFileFromBrowser(fileName: string, data: any): void { + const linkSource = data; + const downloadLink = document.createElement("a"); + downloadLink.href = linkSource; + downloadLink.download = fileName; + downloadLink.click(); + } + + async openPreview(msg) { console.log(msg); - if (!msg.attachments[0].image_url || msg.attachments[0].image_url === null || msg.attachments[0].image_url === '' || !msg.attachments[0].title_link || msg.attachments[0].title_link === null || msg.attachments[0].title_link === '') { - this.downloadFile(msg) - //this.testDownlod(msg) - + if(msg.file.type === "application/webtrix") { + this.viewDocument(msg.file, msg.attachments.image_url) } else { - const modal = await this.modalController.create({ - component: ViewMediaPage, - cssClass: 'modal modal-desktop', - componentProps: { - image: msg.attachments[0].image_url, - type: msg.file.type, - username: msg.u.name, - _updatedAt: msg._updatedAt + + if (!msg.attachments[0].image_url || msg.attachments[0].image_url === null || msg.attachments[0].image_url === '') { + this.downloadFileMsg(msg) + //this.testDownlod(msg) + + } else { + var str = msg.attachments[0].image_url; + str = str.substring(1, ((str.length) - 1)); + + if (this.platform.is('desktop') || this.platform.is('mobileweb')) { + + this.downloadFileFromBrowser(msg.attachments[0].name, str) + /* const modal = await this.modalController.create({ + component: ViewMediaPage, + cssClass: 'modal modal-desktop', + componentProps: { + image: str, + type: msg.file.type, + username: msg.u.name, + _updatedAt: msg._updatedAt + } + }); + modal.present(); */ + + } else { + this.openFile(str, msg.attachments[0].name, msg.file.type); } - }); - modal.present(); + + } } } @@ -947,7 +1023,7 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy { console.log(msg); if (!msg.attachments[0].title_link || msg.attachments[0].title_link === null || msg.attachments[0].title_link === '') { this.downloadFileMsg(msg) - } else {} + } else { } } diff --git a/src/app/services/chat/message.service.ts b/src/app/services/chat/message.service.ts index de1e78de2..2c053f6c8 100644 --- a/src/app/services/chat/message.service.ts +++ b/src/app/services/chat/message.service.ts @@ -233,12 +233,17 @@ export class MessageService { } else if (event.type === HttpEventType.Response) { if (this.file.type == "application/img") { downloadFile = 'data:image/jpeg;base64,' + btoa(new Uint8Array(event.body).reduce((data, byte) => data + String.fromCharCode(byte), '')); - } else if (this.file.type === 'application/pdf') { + } else if (this.file.type != "application/img") { - downloadFile = event.body as any; - } else if (this.file.type == 'application/audio') { downloadFile = new Uint8Array(event.body).reduce((data, byte) => data + String.fromCharCode(byte), ''); - } + console.log(downloadFile) + } /* else if (this.file.type == 'application/audio') { + downloadFile = new Uint8Array(event.body).reduce((data, byte) => data + String.fromCharCode(byte), ''); + } else if (this.file.type == 'application/vnd.openxmlformats-officedocument.wordprocessingml.document') { + downloadFile = new Uint8Array(event.body).reduce((data, byte) => data + String.fromCharCode(byte), ''); + } */ + + console.log('Download file ',downloadFile ) this.attachments[0] = { image_url: downloadFile, 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 2e0a784e4..61ac8afd6 100644 --- a/src/app/shared/chat/group-messages/group-messages.page.html +++ b/src/app/shared/chat/group-messages/group-messages.page.html @@ -217,9 +217,9 @@ - + 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 67eb520b6..0748f45f9 100644 --- a/src/app/shared/chat/group-messages/group-messages.page.ts +++ b/src/app/shared/chat/group-messages/group-messages.page.ts @@ -1,5 +1,5 @@ import { Component, OnChanges, OnInit, Input, SimpleChanges, ChangeDetectorRef, Output, EventEmitter, ViewChild, ElementRef, AfterViewChecked, AfterViewInit, OnDestroy } from '@angular/core'; -import { ActionSheetController, AnimationController, IonSlides, MenuController, ModalController, PopoverController } from '@ionic/angular'; +import { ActionSheetController, AnimationController, IonSlides, MenuController, ModalController, PopoverController, Platform } from '@ionic/angular'; import { AlertService } from 'src/app/services/alert.service'; import { AuthService } from 'src/app/services/auth.service'; import { ChatService } from 'src/app/services/chat.service'; @@ -36,6 +36,8 @@ 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 { File } from '@awesome-cordova-plugins/file/ngx'; +import { FileOpener } from '@awesome-cordova-plugins/file-opener/ngx'; /* import * as pdfjsLib from 'pdfjs-dist'; @@ -94,8 +96,8 @@ export class GroupMessagesPage implements OnInit, OnChanges, AfterViewInit, OnDe allowTyping = true; storedFileNames = []; lastAudioRecorded = ''; - audioRecorded:any = ""; - audioDownloaded:any = ""; + audioRecorded: any = ""; + audioDownloaded: any = ""; durationDisplay = ''; duration = 0; @@ -121,6 +123,9 @@ export class GroupMessagesPage implements OnInit, OnChanges, AfterViewInit, OnDe private CameraService: CameraService, private toastService: ToastService, private sanitiser: DomSanitizer, + private file: File, + private platform: Platform, + private fileOpener: FileOpener, ) { console.log('OnCONSTRUCTOR'); @@ -142,7 +147,7 @@ export class GroupMessagesPage implements OnInit, OnChanges, AfterViewInit, OnDe this.showAvatar = false - setTimeout(()=>{ + setTimeout(() => { this.scrollToBottomClicked() this.showAvatar = true }, 50) @@ -152,7 +157,7 @@ export class GroupMessagesPage implements OnInit, OnChanges, AfterViewInit, OnDe } ngOnInit() { - this.loggedUser=this.loggedUserChat; + this.loggedUser = this.loggedUserChat; setTimeout(() => { this.getRoomInfo(); }, 1000); @@ -259,7 +264,7 @@ export class GroupMessagesPage implements OnInit, OnChanges, AfterViewInit, OnDe }, 1000) } - async getFile(fileName?:any){ + async getFile(fileName?: any) { const audioFile = await Filesystem.readFile({ path: fileName, directory: Directory.Data @@ -277,14 +282,14 @@ export class GroupMessagesPage implements OnInit, OnChanges, AfterViewInit, OnDe this.storage.get('recordData').then((recordData) => { console.log(recordData); - if(recordData?.value?.recordDataBase64.includes('data:audio')){ + if (recordData?.value?.recordDataBase64.includes('data:audio')) { this.audioRecorded = this.sanitiser.bypassSecurityTrustResourceUrl(recordData?.value?.recordDataBase64); } - else{ + else { this.audioRecorded = this.sanitiser.bypassSecurityTrustResourceUrl(`data:${recordData.value.mimeType};base64,${recordData?.value?.recordDataBase64}`); } }); - } catch (error) {} + } catch (error) { } } @@ -316,8 +321,8 @@ export class GroupMessagesPage implements OnInit, OnChanges, AfterViewInit, OnDe //console.log(recordData); const fileName = new Date().getTime() + ".mp3"; //Save file - this.storage.set('fileName',fileName); - this.storage.set('recordData',result).then(() => { + this.storage.set('fileName', fileName); + this.storage.set('recordData', result).then(() => { console.log('Audio recorded saved'); }) } @@ -327,7 +332,7 @@ export class GroupMessagesPage implements OnInit, OnChanges, AfterViewInit, OnDe }, 1000); } - async deleteRecording(){ + async deleteRecording() { this.storage.remove('fileName'); this.storage.remove('recordData'); @@ -425,17 +430,17 @@ export class GroupMessagesPage implements OnInit, OnChanges, AfterViewInit, OnDe var byteArrays = new Array(slicesCount); for (var sliceIndex = 0; sliceIndex < slicesCount; ++sliceIndex) { - var begin = sliceIndex * sliceSize; - var end = Math.min(begin + sliceSize, bytesLength); + 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); + 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 }); -} + } async sendAudio(fileName) { const roomId = this.roomId @@ -443,36 +448,36 @@ export class GroupMessagesPage implements OnInit, OnChanges, AfterViewInit, OnDe this.storage.get('recordData').then((recordData) => { console.log(recordData); audioFile = recordData; - if(recordData?.value?.recordDataBase64.includes('data:audio')){ + if (recordData?.value?.recordDataBase64.includes('data:audio')) { this.audioRecorded = recordData?.value?.recordDataBase64; } - else{ + else { this.audioRecorded = `data:${recordData.value.mimeType};base64,${recordData?.value?.recordDataBase64}`; } - //Converting base64 to blob - const encodedData = btoa(this.audioRecorded); - const blob = this.base64toBlob(encodedData, recordData.value.mimeType) - console.log(blob) - const formData = new FormData(); - formData.append("blobFile", blob); + //Converting base64 to blob + const encodedData = btoa(this.audioRecorded); + const blob = this.base64toBlob(encodedData, recordData.value.mimeType) + console.log(blob) + const formData = new FormData(); + formData.append("blobFile", blob); - this.wsChatMethodsService.getGroupRoom(roomId).send({ - file: { - "type": "application/audio", - "msDuration":audioFile.value.msDuration, - "mimeType":audioFile.value.mimeType, - }, - attachments: [{ - "title": fileName , - "title_link_download": true, - "type": "audio" - }], - temporaryData: formData - }) + this.wsChatMethodsService.getGroupRoom(roomId).send({ + file: { + "type": "application/audio", + "msDuration": audioFile.value.msDuration, + "mimeType": audioFile.value.mimeType, + }, + attachments: [{ + "title": fileName, + "title_link_download": true, + "type": "audio" + }], + temporaryData: formData + }) - }); + }); this.deleteRecording(); } @@ -723,7 +728,7 @@ export class GroupMessagesPage implements OnInit, OnChanges, AfterViewInit, OnDe //const imageData = await this.fileToBase64Service.convert(file) //console.log('ADDFILECHAT', imageData) - const response = await fetch('data:image/jpeg;base64,'+ file.base64String!); + const response = await fetch('data:image/jpeg;base64,' + file.base64String!); const blob = await response.blob(); const formData = new FormData(); @@ -736,8 +741,8 @@ export class GroupMessagesPage implements OnInit, OnChanges, AfterViewInit, OnDe }, temporaryData: formData, attachments: [{ - "title": file.path , - "image_url": 'data:image/jpeg;base64,' +file.base64String, + "title": file.path, + "image_url": 'data:image/jpeg;base64,' + file.base64String, "text": "description", "title_link_download": false, }] @@ -751,7 +756,7 @@ export class GroupMessagesPage implements OnInit, OnChanges, AfterViewInit, OnDe const image = await this.CameraService.takePicture(); await this.fileService.saveImage(image) const lastphoto: any = await this.fileService.loadFiles(); - const { capturedImage, capturedImageTitle} = await this.fileService.loadFileData(lastphoto); + const { capturedImage, capturedImageTitle } = await this.fileService.loadFileData(lastphoto); const base64 = await fetch(capturedImage); const blob = await base64.blob(); @@ -764,7 +769,7 @@ export class GroupMessagesPage implements OnInit, OnChanges, AfterViewInit, OnDe "guid": '' }, attachments: [{ - "title": capturedImageTitle , + "title": capturedImageTitle, "image_url": capturedImage, "text": "description", "title_link_download": false, @@ -795,13 +800,13 @@ export class GroupMessagesPage implements OnInit, OnChanges, AfterViewInit, OnDe } }); await modal.present(); - modal.onDidDismiss().then(async res=>{ + modal.onDidDismiss().then(async res => { const data = res.data; - if(data.selected) { + if (data.selected) { this.wsChatMethodsService.getGroupRoom(roomId).send({ - file:{ + file: { "name": res.data.selected.Assunto, "type": "application/webtrix", "ApplicationId": res.data.selected.ApplicationType, @@ -827,7 +832,7 @@ export class GroupMessagesPage implements OnInit, OnChanges, AfterViewInit, OnDe } }); } - async addFileToChatMobile(types: typeof FileType[] ) { + async addFileToChatMobile(types: typeof FileType[]) { const roomId = this.roomId const file = await Camera.getPhoto({ @@ -840,7 +845,7 @@ export class GroupMessagesPage implements OnInit, OnChanges, AfterViewInit, OnDe //const imageData = await this.fileToBase64Service.convert(file) //console.log('ADDFILECHAT', imageData) - const response = await fetch('data:image/jpeg;base64,'+ file.base64String!); + const response = await fetch('data:image/jpeg;base64,' + file.base64String!); const blob = await response.blob(); const formData = new FormData(); @@ -853,8 +858,8 @@ export class GroupMessagesPage implements OnInit, OnChanges, AfterViewInit, OnDe }, temporaryData: formData, attachments: [{ - "title": file.path , - "image_url": 'data:image/jpeg;base64,' +file.base64String, + "title": file.path, + "image_url": 'data:image/jpeg;base64,' + file.base64String, "text": "description", "title_link_download": false, }] @@ -863,52 +868,63 @@ export class GroupMessagesPage implements OnInit, OnChanges, AfterViewInit, OnDe } - async addFileToChat(types: typeof FileType[] ) { + async addFileToChat(types: typeof FileType[]) { const roomId = this.roomId const file: any = await this.fileService.getFileFromDevice(types); console.log('Add file', file) - /* const imageData = await this.fileToBase64Service.convert(file).then((filee) => { - console.log('Add file', filee) - }) */ - const blob = new Blob([file],{type: file.type}) - console.log('Add file', blob) - const formData = new FormData(); - formData.append("blobFile", blob); + if (file.type != "application/img" && file.type != "image/png" && file.type != "image/jpeg" && file.type != "image/gif") { - let pdfBase64; - this.blobToBase64(blob).then(res => { - console.log('Base64 pdf', res); - this.wsChatMethodsService.getGroupRoom(roomId).send({ + const encodedData = btoa(JSON.stringify(await this.getBase64(file))); + const blob = this.base64toBlob(encodedData, file.type) + console.log('Add Blob file', blob) + + const formData = new FormData(); + formData.append("blobFile", blob); + + this.wsChatMethodsService.getDmRoom(roomId).send({ file: { "type": file.type, "guid": '', }, attachments: [{ - "title": file.name , - "name": file.name , - "image_url": res, + "title": file.name, + "name": file.name, + //"image_url": res, // "text": "description", "title_link_download": false, }], temporaryData: formData }) - }); + + } else { + console.log('File type invalid') + } } - blobToBase64 = blob => { - const reader = new FileReader(); - reader.readAsDataURL(blob); + getFileReader(): FileReader { + const fileReader = new FileReader(); + const zoneOriginalInstance = (fileReader as any)["__zone_symbol__originalInstance"]; + return zoneOriginalInstance || fileReader; + } + + getBase64(file) { + var reader = this.getFileReader(); + reader.readAsDataURL(file); return new Promise(resolve => { - reader.onloadend = () => { - resolve(reader.result); + reader.onload = function () { + resolve(reader.result) + }; + reader.onerror = function (error) { + console.log('Error: ', error); }; }); - }; + + } bookMeeting() { let data = { @@ -954,7 +970,7 @@ export class GroupMessagesPage implements OnInit, OnChanges, AfterViewInit, OnDe } }); await modal.present(); - modal.onDidDismiss().then( async (res) => { + modal.onDidDismiss().then(async (res) => { console.log(res['data']); const roomId = this.roomId; @@ -996,23 +1012,95 @@ export class GroupMessagesPage implements OnInit, OnChanges, AfterViewInit, OnDe msg.downloadFileMsg() } + downloadFileFromBrowser(fileName: string, data: any): void { + const linkSource = data; + const downloadLink = document.createElement("a"); + downloadLink.href = linkSource; + downloadLink.download = fileName; + downloadLink.click(); + } + + b64toBlob(b64Data, contentType) { + contentType = contentType || ''; + var sliceSize = 512; + b64Data = b64Data.replace(/^[^,]+,/, ''); + b64Data = b64Data.replace(/\s/g, ''); + var byteCharacters = window.atob(b64Data); + var byteArrays = []; + + for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) { + var slice = byteCharacters.slice(offset, offset + sliceSize); + + var byteNumbers = new Array(slice.length); + for (var i = 0; i < slice.length; i++) { + byteNumbers[i] = slice.charCodeAt(i); + } + + var byteArray = new Uint8Array(byteNumbers); + + byteArrays.push(byteArray); + } + + var blob = new Blob(byteArrays, { type: contentType }); + return blob; + } + + openFile(pdfString, filename, type) { + const blob = this.b64toBlob(pdfString, type) + let pathFile = '' + const fileName = filename + const contentFile = blob + if (this.platform.is('ios')) { + pathFile = this.file.documentsDirectory + } else { + pathFile = this.file.externalRootDirectory + } + console.log(pdfString) + console.log(pathFile) + console.log(contentFile) + this.file + .writeFile(pathFile, fileName, contentFile, { replace: true }) + .then(success => { + this.fileOpener + .open(pathFile + fileName, type) + .then(() => console.log('File is opened')) + .catch(e => console.log('Error opening file', e)); + }) + .catch(e => console.log('Error writing file', e)) + } + async openPreview(msg) { - if (!msg.attachments[0].image_url || msg.attachments[0].image_url === null || msg.attachments[0].image_url === '' ) { - this.downloadFileMsg(msg) - + if (msg.file.type === "application/webtrix") { + this.viewDocument(msg.file, msg.attachments.image_url) } else { - const modal = await this.modalController.create({ - component: ViewMediaPage, - cssClass: 'modal modal-desktop', - componentProps: { - image: msg.attachments[0].image_url, - type: msg.file.type, - username: msg.u.name, - _updatedAt: msg._updatedAt + + if (!msg.attachments[0].image_url || msg.attachments[0].image_url === null || msg.attachments[0].image_url === '') { + this.downloadFileMsg(msg) + + } else { + + var str = msg.attachments[0].image_url; + str = str.substring(1, ((str.length) - 1)); + + if (this.platform.is('desktop') || this.platform.is('mobileweb')) { + this.downloadFileFromBrowser(msg.attachments[0].name, str) + } else if (this.platform.is('tablet')) { + this.openFile(str, msg.attachments[0].name, msg.file.type); } - }); - modal.present(); + + /* const modal = await this.modalController.create({ + component: ViewMediaPage, + cssClass: 'modal modal-desktop', + componentProps: { + image: str, + type: msg.file.type, + username: msg.u.name, + _updatedAt: msg._updatedAt + } + }); + modal.present(); */ + } } } @@ -1021,7 +1109,7 @@ export class GroupMessagesPage implements OnInit, OnChanges, AfterViewInit, OnDe console.log(msg); if (!msg.attachments[0].title_link || msg.attachments[0].title_link === null || msg.attachments[0].title_link === '') { this.downloadFileMsg(msg) - } else {} + } else { } } } diff --git a/src/app/shared/chat/messages/messages.page.html b/src/app/shared/chat/messages/messages.page.html index 7ec469275..8fdd6e7a6 100644 --- a/src/app/shared/chat/messages/messages.page.html +++ b/src/app/shared/chat/messages/messages.page.html @@ -97,6 +97,7 @@ + @@ -198,9 +199,9 @@ - + diff --git a/src/app/shared/chat/messages/messages.page.ts b/src/app/shared/chat/messages/messages.page.ts index bba14b36c..5343eb941 100644 --- a/src/app/shared/chat/messages/messages.page.ts +++ b/src/app/shared/chat/messages/messages.page.ts @@ -1,5 +1,5 @@ import { AfterViewChecked, AfterViewInit, Component, ElementRef, ChangeDetectorRef, EventEmitter, Input, OnChanges, OnDestroy, OnInit, Output, SimpleChanges, ViewChild } from '@angular/core'; -import { AnimationController, GestureController, IonSlides, ModalController, PopoverController } from '@ionic/angular'; +import { AnimationController, GestureController, IonSlides, ModalController, PopoverController, Platform } from '@ionic/angular'; import { AlertService } from 'src/app/services/alert.service'; import { AuthService } from 'src/app/services/auth.service'; import { ChatService } from 'src/app/services/chat.service'; @@ -35,6 +35,8 @@ import { DocumentViewer, DocumentViewerOptions } from '@ionic-native/document-vi import { VoiceRecorder, VoiceRecorderPlugin, RecordingData, GenericResponse, CurrentRecordingStatus } from 'capacitor-voice-recorder'; import { Filesystem, Directory, Encoding } from '@capacitor/filesystem'; import { DomSanitizer } from '@angular/platform-browser'; +import { File } from '@awesome-cordova-plugins/file/ngx'; +import { FileOpener } from '@awesome-cordova-plugins/file-opener/ngx'; const IMAGE_DIR = 'stored-images'; @Component({ @@ -76,7 +78,7 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy scrollToBottomBtn = false; longPressActive = false; frameUrl: any; - downloadFile: any; + downloadFile: string; massages: MessageService[] = [] showAvatar = true; @@ -85,8 +87,8 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy allowTyping = true; storedFileNames = []; lastAudioRecorded = ''; - audioRecorded:any = ""; - audioDownloaded:any = ""; + audioRecorded: any = ""; + audioDownloaded: any = ""; durationDisplay = ''; duration = 0; @@ -118,6 +120,9 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy private processesService: ProcessesService, private fileToBase64Service: FileToBase64Service, private sanitiser: DomSanitizer, + private file: File, + private platform: Platform, + private fileOpener: FileOpener, ) { this.loggedUser = authService.ValidatedUserChat['data']; } @@ -238,7 +243,7 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy }, 1000) } - async getFile(fileName?:any){ + async getFile(fileName?: any) { const audioFile = await Filesystem.readFile({ path: fileName, directory: Directory.Data @@ -256,16 +261,25 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy this.storage.get('recordData').then((recordData) => { console.log(recordData); - if(recordData?.value?.recordDataBase64.includes('data:audio')){ + if (recordData?.value?.recordDataBase64.includes('data:audio')) { this.audioRecorded = this.sanitiser.bypassSecurityTrustResourceUrl(recordData?.value?.recordDataBase64); } - else{ + else { this.audioRecorded = this.sanitiser.bypassSecurityTrustResourceUrl(`data:${recordData.value.mimeType};base64,${recordData?.value?.recordDataBase64}`); } }); - } catch (error) {} + } catch (error) { } + 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() { @@ -294,8 +308,8 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy //console.log(recordData); const fileName = new Date().getTime() + ".mp3"; //Save file - this.storage.set('fileName',fileName); - this.storage.set('recordData',result).then(() => { + this.storage.set('fileName', fileName); + this.storage.set('recordData', result).then(() => { console.log('Audio recorded saved'); }) } @@ -305,7 +319,7 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy }, 1000); } - async deleteRecording(){ + async deleteRecording() { this.storage.remove('fileName'); this.storage.remove('recordData'); @@ -355,6 +369,71 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy this.wsChatMethodsService.getDmRoom(this.roomId).send({}) } + + async sendAudio(fileName) { + const roomId = this.roomId + let audioFile; + this.storage.get('recordData').then((recordData) => { + console.log(recordData); + audioFile = 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 encodedData = btoa(this.audioRecorded); + const blob = this.base64toBlob(encodedData, recordData.value.mimeType) + console.log(blob) + const formData = new FormData(); + formData.append("blobFile", blob); + + this.wsChatMethodsService.getDmRoom(roomId).send({ + file: { + "type": "application/audio", + "msDuration": audioFile.value.msDuration, + "mimeType": audioFile.value.mimeType, + }, + attachments: [{ + "title": fileName, + "title_link_download": true, + "type": "audio" + }], + temporaryData: formData + }) + + }); + this.deleteRecording(); + } + + + deleteMessage(msgId: string, msg: MessageService) { + this.wsChatMethodsService.getDmRoom(this.roomId).sendDeleteRequest(msgId) + if (msg.file.type == "application/webtrix") { + this.openViewDocumentModal(msg.file); + } + else { + console.log('PDF CLICK', msg) + var str = msg.attachments[0].image_url; + str = str.substring(1, ((str.length) - 1)); + + const encodedData = btoa(str); + /* let fullUrl; + fullUrl = "https://gabinetedigitalchat.dyndns.info" + url; + //fullUrl = "http://www.africau.edu/images/default/sample.pdf"; + + this.frameUrl = fullUrl; */ + let file = this.base64toBlob(encodedData, 'application/pdf') + let fileURL = URL.createObjectURL(file) + console.log('PDF CLICK', fileURL) + window.open(fileURL); + + // this.chatService.getDocumentDetails(fullUrl); + } + } + base64toBlob(base64Data, contentType) { contentType = contentType || ''; var sliceSize = 1024; @@ -364,88 +443,16 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy var byteArrays = new Array(slicesCount); for (var sliceIndex = 0; sliceIndex < slicesCount; ++sliceIndex) { - var begin = sliceIndex * sliceSize; - var end = Math.min(begin + sliceSize, bytesLength); + 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); + 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 }); -} - - async sendAudio(fileName) { - const roomId = this.roomId - let audioFile; - this.storage.get('recordData').then((recordData) => { - console.log(recordData); - audioFile = recordData; - if(recordData?.value?.recordDataBase64.includes('data:audio')){ - this.audioRecorded = recordData?.value?.recordDataBase64; - } - else{ - this.audioRecorded = `data:${recordData.value.mimeType};base64,${recordData?.value?.recordDataBase64}`; - } - - console.log(this.audioRecorded); - - //Converting base64 to blob - const encodedData = btoa(this.audioRecorded); - const blob = this.base64toBlob(encodedData, recordData.value.mimeType) - console.log(blob) - const formData = new FormData(); - formData.append("blobFile", blob); - - this.wsChatMethodsService.getDmRoom(roomId).send({ - file: { - "type": "application/audio", - "msDuration":audioFile.value.msDuration, - "mimeType":audioFile.value.mimeType, - }, - attachments: [{ - "title": fileName , - "title_link_download": true, - "type": "audio" - }], - temporaryData: formData - }) - - }); - this.deleteRecording(); - } - - - deleteMessage(msgId: string, msg:MessageService) { - this.wsChatMethodsService.getDmRoom(this.roomId).sendDeleteRequest(msgId) - } - - async viewDocument(msg: any, url?: string) { - if (msg.file.type == "application/img") { - let response: any = await this.AttachmentsService.getFile(msg.file.guid).toPromise(); - console.log(response); - alert(response); - - //this.openPreview(msg); - - } - else if (msg.file.type == "application/webtrix") { - this.openViewDocumentModal(msg.file); - } - else { - console.log('PDF CLICK', msg) - /* let fullUrl; - fullUrl = "https://gabinetedigitalchat.dyndns.info" + url; - //fullUrl = "http://www.africau.edu/images/default/sample.pdf"; - - this.frameUrl = fullUrl; */ - let file = new Blob([msg.attachments[0].image_url], { type: 'application/pdf' }); - let fileURL = URL.createObjectURL(file) - window.open(fileURL); - - // this.chatService.getDocumentDetails(fullUrl); - } } @@ -695,6 +702,7 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy }); await modal.present(); modal.onDidDismiss().then(async res => { + console.log('webTrix ', res.data) const data = res.data; const roomId = this.roomId @@ -708,6 +716,7 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy "DocId": res.data.selected.Id, "Assunto": res.data.selected.Assunto, }, + temporaryData: res, attachments: [{ "title": res.data.selected.Assunto, "description": res.data.selected.DocTypeDesc, @@ -766,19 +775,23 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy const file: any = await this.fileService.getFileFromDevice(types); + //if (file.type == "application/pdf") { + console.log('Add file', file) /* const imageData = await this.fileToBase64Service.convert(file).then((filee) => { console.log('Add file', filee) }) */ - const blob = new Blob([file], { type: file.type }) - console.log('Add file', blob) + console.log('Add file', JSON.stringify(await this.getBase64(file))) - const formData = new FormData(); - formData.append("blobFile", blob); + if (file.type != "application/img" && file.type != "image/png" && file.type != "image/jpeg" && file.type != "image/gif") { + + const encodedData = btoa(JSON.stringify(await this.getBase64(file))); + const blob = this.base64toBlob(encodedData, file.type) + console.log('Add Blob file', blob) + + const formData = new FormData(); + formData.append("blobFile", blob); - let pdfBase64; - this.blobToBase64(blob).then(res => { - console.log('Base64 pdf', res); this.wsChatMethodsService.getDmRoom(roomId).send({ file: { "type": file.type, @@ -793,20 +806,33 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy }], temporaryData: formData }) - }); + + } else { + console.log('File type invalid') + } } - blobToBase64 = blob => { - const reader = new FileReader(); - reader.readAsDataURL(blob); + getFileReader(): FileReader { + const fileReader = new FileReader(); + const zoneOriginalInstance = (fileReader as any)["__zone_symbol__originalInstance"]; + return zoneOriginalInstance || fileReader; + } + + getBase64(file) { + var reader = this.getFileReader(); + reader.readAsDataURL(file); return new Promise(resolve => { - reader.onloadend = () => { - resolve(reader.result); + reader.onload = function () { + resolve(reader.result) + }; + reader.onerror = function (error) { + console.log('Error: ', error); }; }); - }; + + } bookMeeting() { @@ -904,16 +930,6 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy msg.downloadFileMsg() } - _arrayBufferToBase64( buffer ) { - var binary = ''; - var bytes = new Uint8Array( buffer ); - var len = bytes.byteLength; - for (var i = 0; i < len; i++) { - binary += String.fromCharCode( bytes[ i ] ); - } - return window.btoa( binary ); -} - pdfPreview() { const options: DocumentViewerOptions = { title: 'My App' @@ -925,32 +941,123 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy console.log(msg); if (!msg.attachments[0].title_link || msg.attachments[0].title_link === null || msg.attachments[0].title_link === '') { this.downloadFileMsg(msg) - } else {} + } else { } + } + + b64toBlob(b64Data, contentType) { + contentType = contentType || ''; + var sliceSize = 512; + b64Data = b64Data.replace(/^[^,]+,/, ''); + b64Data = b64Data.replace(/\s/g, ''); + var byteCharacters = window.atob(b64Data); + var byteArrays = []; + + for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) { + var slice = byteCharacters.slice(offset, offset + sliceSize); + + var byteNumbers = new Array(slice.length); + for (var i = 0; i < slice.length; i++) { + byteNumbers[i] = slice.charCodeAt(i); + } + + var byteArray = new Uint8Array(byteNumbers); + + byteArrays.push(byteArray); + } + + var blob = new Blob(byteArrays, { type: contentType }); + return blob; + } + + downloadFileFromBrowser(fileName: string, data: any): void { + const linkSource = data; + const downloadLink = document.createElement("a"); + downloadLink.href = linkSource; + downloadLink.download = fileName; + downloadLink.click(); + } + + viewDocument(file: any, url?: string) { + console.log() + if (file.type == "application/webtrix") { + this.openViewDocumentModal(file); + } + else { + let fullUrl = "https://www.tabularium.pt" + url; + this.fileService.viewDocumentByUrl(fullUrl); + } + } + + openFile(pdfString, filename, type) { + const blob = this.b64toBlob(pdfString, type) + let pathFile = '' + const fileName = filename + const contentFile = blob + if (this.platform.is('ios')) { + pathFile = this.file.documentsDirectory + } else { + pathFile = this.file.externalRootDirectory + } + console.log(pdfString) + console.log(pathFile) + console.log(contentFile) + this.file + .writeFile(pathFile, fileName, contentFile, { replace: true }) + .then(success => { + this.fileOpener + .open(pathFile + fileName, type) + .then(() => console.log('File is opened')) + .catch(e => console.log('Error opening file', e)); + }) + .catch(e => console.log('Error writing file', e)) } async openPreview(msg) { console.log(msg); - if (!msg.attachments[0].image_url || msg.attachments[0].image_url === null || msg.attachments[0].image_url === '') { - this.downloadFileMsg(msg) - + if(msg.file.type === "application/webtrix") { + this.viewDocument(msg.file, msg.attachments.image_url) } else { - /* if(msg.file.type === "application/pdf") { - this.viewDocument(msg, msg.attachments.image_url) - } else { */ - const modal = await this.modalController.create({ - component: ViewMediaPage, - cssClass: 'modal modal-desktop', - componentProps: { - image: msg.attachments[0].image_url, - type: msg.file.type, - username: msg.u.name, - _updatedAt: msg._updatedAt + if (!msg.attachments[0].image_url || msg.attachments[0].image_url === null || msg.attachments[0].image_url === '') { + this.downloadFileMsg(msg) + + + /* } else if (msg.file.type === "application/pdf") { + + + console.log(str); + const win = window.open("", "_blank"); + let html = ''; + + html += ''; + html += ''; + html += '