MOBILE-4481 ws.ts: Get mimetype from file transfer headers
parent
88931bd50d
commit
8f2c3445e2
|
@ -26,7 +26,6 @@
|
||||||
"@awesome-cordova-plugins/diagnostic": "^6.6.0",
|
"@awesome-cordova-plugins/diagnostic": "^6.6.0",
|
||||||
"@awesome-cordova-plugins/file": "^6.6.0",
|
"@awesome-cordova-plugins/file": "^6.6.0",
|
||||||
"@awesome-cordova-plugins/file-opener": "^6.6.0",
|
"@awesome-cordova-plugins/file-opener": "^6.6.0",
|
||||||
"@awesome-cordova-plugins/file-transfer": "^6.6.0",
|
|
||||||
"@awesome-cordova-plugins/geolocation": "^6.6.0",
|
"@awesome-cordova-plugins/geolocation": "^6.6.0",
|
||||||
"@awesome-cordova-plugins/http": "^6.6.0",
|
"@awesome-cordova-plugins/http": "^6.6.0",
|
||||||
"@awesome-cordova-plugins/in-app-browser": "^6.6.0",
|
"@awesome-cordova-plugins/in-app-browser": "^6.6.0",
|
||||||
|
@ -45,6 +44,7 @@
|
||||||
"@moodlehq/cordova-plugin-advanced-http": "3.3.1-moodle.1",
|
"@moodlehq/cordova-plugin-advanced-http": "3.3.1-moodle.1",
|
||||||
"@moodlehq/cordova-plugin-file-opener": "4.0.0-moodle.1",
|
"@moodlehq/cordova-plugin-file-opener": "4.0.0-moodle.1",
|
||||||
"@moodlehq/cordova-plugin-file-transfer": "2.0.0-moodle.2",
|
"@moodlehq/cordova-plugin-file-transfer": "2.0.0-moodle.2",
|
||||||
|
"@moodlehq/cordova-plugin-camera": "6.0.0-moodle.2",
|
||||||
"@moodlehq/cordova-plugin-inappbrowser": "5.0.0-moodle.3",
|
"@moodlehq/cordova-plugin-inappbrowser": "5.0.0-moodle.3",
|
||||||
"@moodlehq/cordova-plugin-intent": "2.2.0-moodle.3",
|
"@moodlehq/cordova-plugin-intent": "2.2.0-moodle.3",
|
||||||
"@moodlehq/cordova-plugin-ionic-webview": "5.0.0-moodle.3",
|
"@moodlehq/cordova-plugin-ionic-webview": "5.0.0-moodle.3",
|
||||||
|
@ -153,6 +153,12 @@
|
||||||
"node": ">=18.18.2 <19"
|
"node": ">=18.18.2 <19"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@moodlehq/cordova-plugin-file-transfer": {
|
||||||
|
"version": "1.7.1-moodle.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/@moodlehq/cordova-plugin-file-transfer/-/cordova-plugin-file-transfer-1.7.1-moodle.7.tgz",
|
||||||
|
"integrity": "sha512-h4PALmtuSAExfy5DBHvB91P+Z+Dc6DLpWaF7GZeYUM1ROa8OCfw5hc1vq8xFMc+tgan8DSVKUYD2CJX6zlhpMg==",
|
||||||
|
"extraneous": true
|
||||||
|
},
|
||||||
"cordova-plugin-moodleapp": {
|
"cordova-plugin-moodleapp": {
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
@ -2610,22 +2616,6 @@
|
||||||
"resolved": "https://registry.npmjs.org/@types/cordova/-/cordova-11.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/@types/cordova/-/cordova-11.0.3.tgz",
|
||||||
"integrity": "sha512-kyuRQ40/NWQVhqGIHq78Ehu2Bf9Mlg0LhmSmis6ZFJK7z933FRfYi8tHe/k/0fB+PGfCf95rJC6TO7dopaFvAg=="
|
"integrity": "sha512-kyuRQ40/NWQVhqGIHq78Ehu2Bf9Mlg0LhmSmis6ZFJK7z933FRfYi8tHe/k/0fB+PGfCf95rJC6TO7dopaFvAg=="
|
||||||
},
|
},
|
||||||
"node_modules/@awesome-cordova-plugins/file-transfer": {
|
|
||||||
"version": "6.6.0",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@types/cordova": "latest"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"@awesome-cordova-plugins/core": "^6.0.1",
|
|
||||||
"rxjs": "^5.5.0 || ^6.5.0 || ^7.3.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@awesome-cordova-plugins/file-transfer/node_modules/@types/cordova": {
|
|
||||||
"version": "11.0.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/cordova/-/cordova-11.0.3.tgz",
|
|
||||||
"integrity": "sha512-kyuRQ40/NWQVhqGIHq78Ehu2Bf9Mlg0LhmSmis6ZFJK7z933FRfYi8tHe/k/0fB+PGfCf95rJC6TO7dopaFvAg=="
|
|
||||||
},
|
|
||||||
"node_modules/@awesome-cordova-plugins/file/node_modules/@types/cordova": {
|
"node_modules/@awesome-cordova-plugins/file/node_modules/@types/cordova": {
|
||||||
"version": "11.0.3",
|
"version": "11.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/@types/cordova/-/cordova-11.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/@types/cordova/-/cordova-11.0.3.tgz",
|
||||||
|
|
|
@ -61,7 +61,6 @@
|
||||||
"@awesome-cordova-plugins/diagnostic": "^6.6.0",
|
"@awesome-cordova-plugins/diagnostic": "^6.6.0",
|
||||||
"@awesome-cordova-plugins/file": "^6.6.0",
|
"@awesome-cordova-plugins/file": "^6.6.0",
|
||||||
"@awesome-cordova-plugins/file-opener": "^6.6.0",
|
"@awesome-cordova-plugins/file-opener": "^6.6.0",
|
||||||
"@awesome-cordova-plugins/file-transfer": "^6.6.0",
|
|
||||||
"@awesome-cordova-plugins/geolocation": "^6.6.0",
|
"@awesome-cordova-plugins/geolocation": "^6.6.0",
|
||||||
"@awesome-cordova-plugins/http": "^6.6.0",
|
"@awesome-cordova-plugins/http": "^6.6.0",
|
||||||
"@awesome-cordova-plugins/in-app-browser": "^6.6.0",
|
"@awesome-cordova-plugins/in-app-browser": "^6.6.0",
|
||||||
|
|
|
@ -22,7 +22,6 @@ import { Camera } from '@awesome-cordova-plugins/camera/ngx';
|
||||||
import { Clipboard } from '@awesome-cordova-plugins/clipboard/ngx';
|
import { Clipboard } from '@awesome-cordova-plugins/clipboard/ngx';
|
||||||
import { File } from '@awesome-cordova-plugins/file/ngx';
|
import { File } from '@awesome-cordova-plugins/file/ngx';
|
||||||
import { FileOpener } from '@awesome-cordova-plugins/file-opener/ngx';
|
import { FileOpener } from '@awesome-cordova-plugins/file-opener/ngx';
|
||||||
import { FileTransfer } from '@awesome-cordova-plugins/file-transfer/ngx';
|
|
||||||
import { Geolocation } from '@awesome-cordova-plugins/geolocation/ngx';
|
import { Geolocation } from '@awesome-cordova-plugins/geolocation/ngx';
|
||||||
import { InAppBrowser } from '@awesome-cordova-plugins/in-app-browser/ngx';
|
import { InAppBrowser } from '@awesome-cordova-plugins/in-app-browser/ngx';
|
||||||
import { LocalNotifications } from '@awesome-cordova-plugins/local-notifications/ngx';
|
import { LocalNotifications } from '@awesome-cordova-plugins/local-notifications/ngx';
|
||||||
|
@ -34,7 +33,6 @@ import { CameraMock } from './services/camera';
|
||||||
import { ClipboardMock } from './services/clipboard';
|
import { ClipboardMock } from './services/clipboard';
|
||||||
import { FileMock } from './services/file';
|
import { FileMock } from './services/file';
|
||||||
import { FileOpenerMock } from './services/file-opener';
|
import { FileOpenerMock } from './services/file-opener';
|
||||||
import { FileTransferMock } from './services/file-transfer';
|
|
||||||
import { GeolocationMock } from './services/geolocation';
|
import { GeolocationMock } from './services/geolocation';
|
||||||
import { InAppBrowserMock } from './services/inappbrowser';
|
import { InAppBrowserMock } from './services/inappbrowser';
|
||||||
import { LocalNotificationsMock } from './services/local-notifications';
|
import { LocalNotificationsMock } from './services/local-notifications';
|
||||||
|
@ -75,10 +73,6 @@ import { SecureStorageMock } from '@features/emulator/classes/SecureStorage';
|
||||||
provide: FileOpener,
|
provide: FileOpener,
|
||||||
useFactory: (): FileOpener => CorePlatform.is('cordova') ? new FileOpener() : new FileOpenerMock(),
|
useFactory: (): FileOpener => CorePlatform.is('cordova') ? new FileOpener() : new FileOpenerMock(),
|
||||||
},
|
},
|
||||||
{
|
|
||||||
provide: FileTransfer,
|
|
||||||
useFactory: (): FileTransfer => CorePlatform.is('cordova') ? new FileTransfer() : new FileTransferMock(),
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
provide: Geolocation,
|
provide: Geolocation,
|
||||||
useFactory: (): Geolocation => CorePlatform.is('cordova') ? new Geolocation() : new GeolocationMock(),
|
useFactory: (): Geolocation => CorePlatform.is('cordova') ? new Geolocation() : new GeolocationMock(),
|
||||||
|
|
|
@ -18,7 +18,7 @@ import { CoreFile } from '@services/file';
|
||||||
import { File, makeSingleton } from '@singletons';
|
import { File, makeSingleton } from '@singletons';
|
||||||
import { CoreLogger } from '@singletons/logger';
|
import { CoreLogger } from '@singletons/logger';
|
||||||
import { FileMock } from './file';
|
import { FileMock } from './file';
|
||||||
import { FileTransferErrorMock } from './file-transfer';
|
import { FileTransferErrorMock, FileTransferMock } from './file-transfer';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper service for the emulator feature. It also acts as an init handler.
|
* Helper service for the emulator feature. It also acts as an init handler.
|
||||||
|
@ -39,6 +39,7 @@ export class CoreEmulatorHelperProvider {
|
||||||
*/
|
*/
|
||||||
async load(): Promise<void> {
|
async load(): Promise<void> {
|
||||||
window.FileTransferError = FileTransferErrorMock;
|
window.FileTransferError = FileTransferErrorMock;
|
||||||
|
window.FileTransfer = FileTransferMock;
|
||||||
|
|
||||||
const fileService = File.instance;
|
const fileService = File.instance;
|
||||||
|
|
||||||
|
|
|
@ -13,9 +13,6 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { CoreTextUtils } from '@services/utils/text';
|
import { CoreTextUtils } from '@services/utils/text';
|
||||||
import { Injectable } from '@angular/core';
|
|
||||||
import { FileTransfer, FileTransferObject, FileUploadResult, FileTransferError } from '@awesome-cordova-plugins/file-transfer/ngx';
|
|
||||||
|
|
||||||
import { CoreFile } from '@services/file';
|
import { CoreFile } from '@services/file';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -43,40 +40,25 @@ export class FileTransferErrorMock implements FileTransferError {
|
||||||
/**
|
/**
|
||||||
* Emulates the Cordova FileTransfer plugin in desktop apps and in browser.
|
* Emulates the Cordova FileTransfer plugin in desktop apps and in browser.
|
||||||
*/
|
*/
|
||||||
@Injectable()
|
export class FileTransferMock {
|
||||||
export class FileTransferMock extends FileTransfer {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new FileTransferObjectMock object.
|
|
||||||
*
|
|
||||||
* @returns a new file transfer mock.
|
|
||||||
*/
|
|
||||||
create(): FileTransferObjectMock {
|
|
||||||
return new FileTransferObjectMock();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Emulates the FileTransferObject class in desktop apps and in browser.
|
|
||||||
*/
|
|
||||||
export class FileTransferObjectMock extends FileTransferObject {
|
|
||||||
|
|
||||||
progressListener?: (event: ProgressEvent) => void;
|
|
||||||
source?: string;
|
source?: string;
|
||||||
target?: string;
|
target?: string;
|
||||||
xhr?: XMLHttpRequest;
|
xhr?: XMLHttpRequest;
|
||||||
|
|
||||||
protected reject?: (reason?: unknown) => void;
|
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||||
|
onprogress: (event: ProgressEvent) => void = () => {};
|
||||||
|
|
||||||
|
errorCallback?: (error: FileTransferError) => void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Aborts an in-progress transfer. The onerror callback is passed a FileTransferError
|
* Aborts an in-progress transfer. The onerror callback is passed a FileTransferError
|
||||||
* object which has an error code of FileTransferError.ABORT_ERR.
|
* object which has an error code of FileTransferError.ABORT_ERR.
|
||||||
*/
|
*/
|
||||||
abort(): void {
|
abort(): void {
|
||||||
if (this.xhr) {
|
if (this.xhr) {
|
||||||
this.xhr.abort();
|
this.xhr.abort();
|
||||||
this.reject?.(
|
this.errorCallback?.(
|
||||||
new FileTransferErrorMock(FileTransferErrorMock.ABORT_ERR, this.source || '', this.target || '', 0, '', ''),
|
new FileTransferErrorMock(FileTransferErrorMock.ABORT_ERR, this.source || '', this.target || '', 0, '', ''),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -87,13 +69,20 @@ export class FileTransferObjectMock extends FileTransferObject {
|
||||||
*
|
*
|
||||||
* @param source URL of the server to download the file, as encoded by encodeURI().
|
* @param source URL of the server to download the file, as encoded by encodeURI().
|
||||||
* @param target Filesystem url representing the file on the device.
|
* @param target Filesystem url representing the file on the device.
|
||||||
|
* @param successCallback Callback to execute if download the file sucessfully.
|
||||||
|
* @param errorCallback Callback to execute if an error happened downloading the file.
|
||||||
* @param trustAllHosts If set to true, it accepts all security certificates.
|
* @param trustAllHosts If set to true, it accepts all security certificates.
|
||||||
* @param options Optional parameters, currently only supports headers.
|
* @param options Optional parameters, currently only supports headers.
|
||||||
* @returns Returns a Promise that resolves to a FileEntry object.
|
|
||||||
*/
|
*/
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
download(
|
||||||
download(source: string, target: string, trustAllHosts?: boolean, options?: { [s: string]: any }): Promise<unknown> {
|
source: string,
|
||||||
return new Promise((resolve, reject): void => {
|
target: string,
|
||||||
|
successCallback: (params: CoreFileTransferDownloadResponse) => void,
|
||||||
|
errorCallback: (error: FileTransferError) => void,
|
||||||
|
trustAllHosts?: boolean,
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
options?: Record<string, any>,
|
||||||
|
): void {
|
||||||
// Use XMLHttpRequest instead of HttpClient to support onprogress and abort.
|
// Use XMLHttpRequest instead of HttpClient to support onprogress and abort.
|
||||||
const basicAuthHeader = this.getBasicAuthHeader(source);
|
const basicAuthHeader = this.getBasicAuthHeader(source);
|
||||||
const xhr = new XMLHttpRequest();
|
const xhr = new XMLHttpRequest();
|
||||||
|
@ -101,7 +90,7 @@ export class FileTransferObjectMock extends FileTransferObject {
|
||||||
this.xhr = xhr;
|
this.xhr = xhr;
|
||||||
this.source = source;
|
this.source = source;
|
||||||
this.target = target;
|
this.target = target;
|
||||||
this.reject = reject;
|
this.errorCallback = errorCallback;
|
||||||
|
|
||||||
if (basicAuthHeader) {
|
if (basicAuthHeader) {
|
||||||
source = source.replace(this.getUrlCredentials(source) + '@', '');
|
source = source.replace(this.getUrlCredentials(source) + '@', '');
|
||||||
|
@ -124,13 +113,12 @@ export class FileTransferObjectMock extends FileTransferObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
xhr.onprogress = (ev: ProgressEvent): void => {
|
xhr.onprogress = (ev: ProgressEvent): void => {
|
||||||
if (this.progressListener) {
|
this.onprogress(ev);
|
||||||
this.progressListener(ev);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
xhr.onerror = (): void => {
|
xhr.onerror = (): void => {
|
||||||
reject(new FileTransferErrorMock(-1, source, target, xhr.status, xhr.statusText, ''));
|
const error = new FileTransferErrorMock(-1, source, target, xhr.status, xhr.statusText, '');
|
||||||
|
errorCallback(error);
|
||||||
};
|
};
|
||||||
|
|
||||||
xhr.onload = async (): Promise<void> => {
|
xhr.onload = async (): Promise<void> => {
|
||||||
|
@ -141,28 +129,27 @@ export class FileTransferObjectMock extends FileTransferObject {
|
||||||
if (status < 200 || status >= 300) {
|
if (status < 200 || status >= 300) {
|
||||||
// Request failed. Try to get the error message.
|
// Request failed. Try to get the error message.
|
||||||
response = await this.parseResponse(response);
|
response = await this.parseResponse(response);
|
||||||
|
const error = new FileTransferErrorMock(-1, source, target, xhr.status, response || xhr.statusText, '');
|
||||||
|
|
||||||
reject(new FileTransferErrorMock(-1, source, target, xhr.status, response || xhr.statusText, ''));
|
return errorCallback(error);
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!response) {
|
if (!response) {
|
||||||
reject();
|
const error = new FileTransferErrorMock(-1, source, target, xhr.status, xhr.statusText, 'No response obtained');
|
||||||
|
|
||||||
return;
|
return errorCallback(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
const basePath = CoreFile.getBasePathInstant();
|
const basePath = CoreFile.getBasePathInstant();
|
||||||
target = target.replace(basePath, ''); // Remove basePath from the target.
|
target = target.replace(basePath, ''); // Remove basePath from the target.
|
||||||
target = target.replace(/%20/g, ' '); // Replace all %20 with spaces.
|
target = target.replace(/%20/g, ' '); // Replace all %20 with spaces.
|
||||||
|
CoreFile.writeFile(target, response)
|
||||||
// eslint-disable-next-line promise/catch-or-return
|
.then(entry =>
|
||||||
CoreFile.writeFile(target, response).then(resolve, reject);
|
successCallback({ entry: entry as unknown as globalThis.FileEntry, headers: response.headers }))
|
||||||
|
.catch(error => errorCallback(error));
|
||||||
};
|
};
|
||||||
|
|
||||||
xhr.send();
|
xhr.send();
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -227,15 +214,6 @@ export class FileTransferObjectMock extends FileTransferObject {
|
||||||
return credentials && credentials[1];
|
return credentials && credentials[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Registers a listener that gets called whenever a new chunk of data is transferred.
|
|
||||||
*
|
|
||||||
* @param listener Listener that takes a progress event.
|
|
||||||
*/
|
|
||||||
onProgress(listener: (event: ProgressEvent) => void): void {
|
|
||||||
this.progressListener = listener;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse a response, converting it into text and the into an object if needed.
|
* Parse a response, converting it into text and the into an object if needed.
|
||||||
*
|
*
|
||||||
|
@ -285,11 +263,17 @@ export class FileTransferObjectMock extends FileTransferObject {
|
||||||
*
|
*
|
||||||
* @param fileUrl Filesystem URL representing the file on the device or a data URI.
|
* @param fileUrl Filesystem URL representing the file on the device or a data URI.
|
||||||
* @param url URL of the server to receive the file, as encoded by encodeURI().
|
* @param url URL of the server to receive the file, as encoded by encodeURI().
|
||||||
|
* @param successCallback Callback to execute if upload the file sucessfully.
|
||||||
|
* @param errorCallback Callback to execute if an error happened uploading the file.
|
||||||
* @param options Optional parameters.
|
* @param options Optional parameters.
|
||||||
* @returns Promise that resolves to a FileUploadResult and rejects with FileTransferError.
|
|
||||||
*/
|
*/
|
||||||
upload(fileUrl: string, url: string, options?: FileUploadOptions): Promise<FileUploadResult> {
|
upload(
|
||||||
return new Promise((resolve, reject): void => {
|
fileUrl: string,
|
||||||
|
url: string,
|
||||||
|
successCallback: (result: FileUploadResult) => void,
|
||||||
|
errorCallback: (error: FileTransferError) => void,
|
||||||
|
options?: FileUploadOptions,
|
||||||
|
): void {
|
||||||
const basicAuthHeader = this.getBasicAuthHeader(url);
|
const basicAuthHeader = this.getBasicAuthHeader(url);
|
||||||
let fileKey: string | undefined;
|
let fileKey: string | undefined;
|
||||||
let fileName: string | undefined;
|
let fileName: string | undefined;
|
||||||
|
@ -330,7 +314,6 @@ export class FileTransferObjectMock extends FileTransferObject {
|
||||||
// Adding a Content-Type header with the mimeType makes the request fail (it doesn't detect the token in the params).
|
// Adding a Content-Type header with the mimeType makes the request fail (it doesn't detect the token in the params).
|
||||||
// Don't include this header, and delete it if it's supplied.
|
// Don't include this header, and delete it if it's supplied.
|
||||||
delete headers['Content-Type'];
|
delete headers['Content-Type'];
|
||||||
|
|
||||||
// Get the file to upload.
|
// Get the file to upload.
|
||||||
CoreFile.getFile(fileUrl).then((fileEntry) =>
|
CoreFile.getFile(fileUrl).then((fileEntry) =>
|
||||||
CoreFile.getFileObjectFromFileEntry(fileEntry)).then((file) => {
|
CoreFile.getFileObjectFromFileEntry(fileEntry)).then((file) => {
|
||||||
|
@ -345,28 +328,28 @@ export class FileTransferObjectMock extends FileTransferObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
xhr.onprogress = (ev: ProgressEvent): void => {
|
xhr.onprogress = (ev: ProgressEvent): void => {
|
||||||
if (this.progressListener) {
|
this.onprogress(ev);
|
||||||
this.progressListener(ev);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
this.xhr = xhr;
|
this.xhr = xhr;
|
||||||
this.source = fileUrl;
|
this.source = fileUrl;
|
||||||
this.target = url;
|
this.target = url;
|
||||||
this.reject = reject;
|
this.errorCallback = errorCallback;
|
||||||
|
|
||||||
xhr.onerror = (): void => {
|
xhr.onerror = (): void => {
|
||||||
reject(new FileTransferErrorMock(-1, fileUrl, url, xhr.status, xhr.statusText, ''));
|
const error = new FileTransferErrorMock(-1, fileUrl, url, xhr.status, xhr.statusText, '');
|
||||||
|
errorCallback(error);
|
||||||
};
|
};
|
||||||
|
|
||||||
xhr.onload = (): void => {
|
xhr.onload = (): void => {
|
||||||
// Finished uploading the file.
|
const result = {
|
||||||
resolve({
|
|
||||||
bytesSent: file.size,
|
bytesSent: file.size,
|
||||||
responseCode: xhr.status,
|
responseCode: xhr.status,
|
||||||
response: xhr.response,
|
response: xhr.response,
|
||||||
headers: this.getHeadersAsObject(xhr),
|
headers: this.getHeadersAsObject(xhr),
|
||||||
});
|
};
|
||||||
|
|
||||||
|
// Finished uploading the file.
|
||||||
|
successCallback(result);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Create a form data to send params and the file.
|
// Create a form data to send params and the file.
|
||||||
|
@ -374,13 +357,14 @@ export class FileTransferObjectMock extends FileTransferObject {
|
||||||
for (const name in params) {
|
for (const name in params) {
|
||||||
fd.append(name, params[name]);
|
fd.append(name, params[name]);
|
||||||
}
|
}
|
||||||
fd.append('file', file, fileName);
|
|
||||||
|
|
||||||
|
fd.append('file', file, fileName);
|
||||||
xhr.send(fd);
|
xhr.send(fd);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}).catch(reject);
|
}).catch(error => errorCallback(error));
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type CoreFileTransferDownloadResponse = { entry: globalThis.FileEntry; headers: Record<string, string> | undefined };
|
||||||
|
|
|
@ -22,7 +22,6 @@ import { Device } from '@awesome-cordova-plugins/device/ngx';
|
||||||
import { Diagnostic } from '@awesome-cordova-plugins/diagnostic/ngx';
|
import { Diagnostic } from '@awesome-cordova-plugins/diagnostic/ngx';
|
||||||
import { File } from '@awesome-cordova-plugins/file/ngx';
|
import { File } from '@awesome-cordova-plugins/file/ngx';
|
||||||
import { FileOpener } from '@awesome-cordova-plugins/file-opener/ngx';
|
import { FileOpener } from '@awesome-cordova-plugins/file-opener/ngx';
|
||||||
import { FileTransfer } from '@awesome-cordova-plugins/file-transfer/ngx';
|
|
||||||
import { Geolocation } from '@awesome-cordova-plugins/geolocation/ngx';
|
import { Geolocation } from '@awesome-cordova-plugins/geolocation/ngx';
|
||||||
import { HTTP } from '@awesome-cordova-plugins/http/ngx';
|
import { HTTP } from '@awesome-cordova-plugins/http/ngx';
|
||||||
import { InAppBrowser } from '@awesome-cordova-plugins/in-app-browser/ngx';
|
import { InAppBrowser } from '@awesome-cordova-plugins/in-app-browser/ngx';
|
||||||
|
@ -47,7 +46,6 @@ export const CORE_NATIVE_SERVICES = [
|
||||||
Diagnostic,
|
Diagnostic,
|
||||||
File,
|
File,
|
||||||
FileOpener,
|
FileOpener,
|
||||||
FileTransfer,
|
|
||||||
Geolocation,
|
Geolocation,
|
||||||
HTTP,
|
HTTP,
|
||||||
InAppBrowser,
|
InAppBrowser,
|
||||||
|
@ -73,7 +71,6 @@ export const CORE_NATIVE_SERVICES = [
|
||||||
Diagnostic,
|
Diagnostic,
|
||||||
File,
|
File,
|
||||||
FileOpener,
|
FileOpener,
|
||||||
FileTransfer,
|
|
||||||
Geolocation,
|
Geolocation,
|
||||||
HTTP,
|
HTTP,
|
||||||
InAppBrowser,
|
InAppBrowser,
|
||||||
|
|
|
@ -16,7 +16,6 @@ import { Injectable } from '@angular/core';
|
||||||
import { HttpResponse, HttpParams, HttpErrorResponse } from '@angular/common/http';
|
import { HttpResponse, HttpParams, HttpErrorResponse } from '@angular/common/http';
|
||||||
|
|
||||||
import { FileEntry } from '@awesome-cordova-plugins/file/ngx';
|
import { FileEntry } from '@awesome-cordova-plugins/file/ngx';
|
||||||
import { FileUploadOptions, FileUploadResult } from '@awesome-cordova-plugins/file-transfer/ngx';
|
|
||||||
import { Md5 } from 'ts-md5/dist/md5';
|
import { Md5 } from 'ts-md5/dist/md5';
|
||||||
import { Observable, firstValueFrom } from 'rxjs';
|
import { Observable, firstValueFrom } from 'rxjs';
|
||||||
import { timeout } from 'rxjs/operators';
|
import { timeout } from 'rxjs/operators';
|
||||||
|
@ -29,7 +28,7 @@ import { CoreTextErrorObject, CoreTextUtils } from '@services/utils/text';
|
||||||
import { CoreConstants } from '@/core/constants';
|
import { CoreConstants } from '@/core/constants';
|
||||||
import { CoreError } from '@classes/errors/error';
|
import { CoreError } from '@classes/errors/error';
|
||||||
import { CoreInterceptor } from '@classes/interceptor';
|
import { CoreInterceptor } from '@classes/interceptor';
|
||||||
import { makeSingleton, Translate, FileTransfer, Http, NativeHttp } from '@singletons';
|
import { makeSingleton, Translate, Http, NativeHttp } from '@singletons';
|
||||||
import { CoreLogger } from '@singletons/logger';
|
import { CoreLogger } from '@singletons/logger';
|
||||||
import { CoreWSError } from '@classes/errors/wserror';
|
import { CoreWSError } from '@classes/errors/wserror';
|
||||||
import { CoreAjaxError } from '@classes/errors/ajaxerror';
|
import { CoreAjaxError } from '@classes/errors/ajaxerror';
|
||||||
|
@ -254,14 +253,25 @@ export class CoreWSProvider {
|
||||||
// Create the tmp file as an empty file.
|
// Create the tmp file as an empty file.
|
||||||
const fileEntry = await CoreFile.createFile(tmpPath);
|
const fileEntry = await CoreFile.createFile(tmpPath);
|
||||||
|
|
||||||
const transfer = FileTransfer.create();
|
const transfer = new window.FileTransfer();
|
||||||
onProgress && transfer.onProgress(onProgress);
|
|
||||||
|
if (onProgress) {
|
||||||
|
transfer.onprogress = onProgress;
|
||||||
|
}
|
||||||
|
|
||||||
// Download the file in the tmp file.
|
// Download the file in the tmp file.
|
||||||
await transfer.download(url, CoreFile.getFileEntryURL(fileEntry), true, {
|
const fileDownloaded = await new Promise<{
|
||||||
headers: {
|
entry: globalThis.FileEntry;
|
||||||
'User-Agent': navigator.userAgent,
|
headers: Record<string, string> | undefined;
|
||||||
},
|
}>((resolve, reject) => {
|
||||||
|
transfer.download(
|
||||||
|
url,
|
||||||
|
CoreFile.getFileEntryURL(fileEntry),
|
||||||
|
(result) => resolve(result),
|
||||||
|
(error: FileTransferError) => reject(error),
|
||||||
|
true,
|
||||||
|
{ headers: { 'User-Agent': navigator.userAgent } },
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
let extension = '';
|
let extension = '';
|
||||||
|
@ -271,8 +281,10 @@ export class CoreWSProvider {
|
||||||
|
|
||||||
// Google Drive extensions will be considered invalid since Moodle usually converts them.
|
// Google Drive extensions will be considered invalid since Moodle usually converts them.
|
||||||
if (!extension || ['gdoc', 'gsheet', 'gslides', 'gdraw', 'php'].includes(extension)) {
|
if (!extension || ['gdoc', 'gsheet', 'gslides', 'gdraw', 'php'].includes(extension)) {
|
||||||
|
|
||||||
// Not valid, get the file's mimetype.
|
// Not valid, get the file's mimetype.
|
||||||
const mimetype = await this.getRemoteFileMimeType(url);
|
const requestContentType = fileDownloaded.headers?.['Content-Type']?.split(';')[0];
|
||||||
|
const mimetype = requestContentType ?? await this.getRemoteFileMimeType(url);
|
||||||
|
|
||||||
if (mimetype) {
|
if (mimetype) {
|
||||||
const remoteExtension = CoreMimetypeUtils.getExtension(mimetype, url);
|
const remoteExtension = CoreMimetypeUtils.getExtension(mimetype, url);
|
||||||
|
@ -983,9 +995,11 @@ export class CoreWSProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
const uploadUrl = preSets.siteUrl + '/webservice/upload.php';
|
const uploadUrl = preSets.siteUrl + '/webservice/upload.php';
|
||||||
const transfer = FileTransfer.create();
|
const transfer = new window.FileTransfer();
|
||||||
|
|
||||||
onProgress && transfer.onProgress(onProgress);
|
if (onProgress) {
|
||||||
|
transfer.onprogress = onProgress;
|
||||||
|
}
|
||||||
|
|
||||||
options.httpMethod = 'POST';
|
options.httpMethod = 'POST';
|
||||||
options.params = {
|
options.params = {
|
||||||
|
@ -1002,7 +1016,8 @@ export class CoreWSProvider {
|
||||||
let success: FileUploadResult;
|
let success: FileUploadResult;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
success = await transfer.upload(filePath, uploadUrl, options, true);
|
success = await new Promise((resolve, reject) =>
|
||||||
|
transfer.upload( filePath, uploadUrl, (result) => resolve(result), (error) => reject(error), options, true));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.logger.error('Error while uploading file', filePath, error);
|
this.logger.error('Error while uploading file', filePath, error);
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,6 @@ import { Diagnostic as DiagnosticService } from '@awesome-cordova-plugins/diagno
|
||||||
import { Device as DeviceService } from '@awesome-cordova-plugins/device/ngx';
|
import { Device as DeviceService } from '@awesome-cordova-plugins/device/ngx';
|
||||||
import { File as FileService } from '@awesome-cordova-plugins/file/ngx';
|
import { File as FileService } from '@awesome-cordova-plugins/file/ngx';
|
||||||
import { FileOpener as FileOpenerService } from '@awesome-cordova-plugins/file-opener/ngx';
|
import { FileOpener as FileOpenerService } from '@awesome-cordova-plugins/file-opener/ngx';
|
||||||
import { FileTransfer as FileTransferService } from '@awesome-cordova-plugins/file-transfer/ngx';
|
|
||||||
import { Geolocation as GeolocationService } from '@awesome-cordova-plugins/geolocation/ngx';
|
import { Geolocation as GeolocationService } from '@awesome-cordova-plugins/geolocation/ngx';
|
||||||
import { HTTP } from '@awesome-cordova-plugins/http/ngx';
|
import { HTTP } from '@awesome-cordova-plugins/http/ngx';
|
||||||
import { InAppBrowser as InAppBrowserService } from '@awesome-cordova-plugins/in-app-browser/ngx';
|
import { InAppBrowser as InAppBrowserService } from '@awesome-cordova-plugins/in-app-browser/ngx';
|
||||||
|
@ -175,7 +174,6 @@ export const Clipboard = makeSingleton(ClipboardService);
|
||||||
export const Diagnostic = makeSingleton(DiagnosticService);
|
export const Diagnostic = makeSingleton(DiagnosticService);
|
||||||
export const File = makeSingleton(FileService);
|
export const File = makeSingleton(FileService);
|
||||||
export const FileOpener = makeSingleton(FileOpenerService);
|
export const FileOpener = makeSingleton(FileOpenerService);
|
||||||
export const FileTransfer = makeSingleton(FileTransferService);
|
|
||||||
export const Geolocation = makeSingleton(GeolocationService);
|
export const Geolocation = makeSingleton(GeolocationService);
|
||||||
export const InAppBrowser = makeSingleton(InAppBrowserService);
|
export const InAppBrowser = makeSingleton(InAppBrowserService);
|
||||||
export const Keyboard = makeSingleton(KeyboardService);
|
export const Keyboard = makeSingleton(KeyboardService);
|
||||||
|
|
|
@ -13,6 +13,7 @@ For more information about upgrading, read the official documentation: https://m
|
||||||
- CoreLoginHelper.getErrorMessages has been removed. Please create the messages object yourself.
|
- CoreLoginHelper.getErrorMessages has been removed. Please create the messages object yourself.
|
||||||
- CoreAppProvider.isAutomated() has been deprecated, use CorePlatformService.isAutomated() instead.
|
- CoreAppProvider.isAutomated() has been deprecated, use CorePlatformService.isAutomated() instead.
|
||||||
- Due to a breaking change in cordova-plugin-file, avoid using FileEntry.toURL(). Use CoreFileProvider.getFileEntryURL instead.
|
- Due to a breaking change in cordova-plugin-file, avoid using FileEntry.toURL(). Use CoreFileProvider.getFileEntryURL instead.
|
||||||
|
- FileTransfer service is no longer available, now we recommend use window.FileTransfer instead.
|
||||||
|
|
||||||
=== 4.3.0 ===
|
=== 4.3.0 ===
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue