MOBILE-4481 ws.ts: Get mimetype from file transfer headers

main
Alfonso Salces 2023-12-14 08:50:26 +01:00
parent 88931bd50d
commit 8f2c3445e2
9 changed files with 89 additions and 110 deletions

24
package-lock.json generated
View File

@ -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",

View File

@ -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",

View File

@ -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(),

View File

@ -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;

View File

@ -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 };

View File

@ -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,

View File

@ -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);

View File

@ -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);

View File

@ -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 ===