MOBILE-3270 core: Fix upload files from Google Drive

main
Dani Palou 2020-04-07 12:22:47 +02:00
parent f819331f50
commit ec3a1bdb56
3 changed files with 38 additions and 18 deletions

View File

@ -78,7 +78,7 @@ export class CoreLocalFileComponent implements OnInit {
this.size = this.textUtils.bytesToSize(metadata.size, 2);
}
this.timemodified = this.timeUtils.userDate(metadata.modificationTime, 'core.strftimedatetimeshort');
this.timemodified = this.timeUtils.userDate(metadata.modificationTime.getTime(), 'core.strftimedatetimeshort');
});
}

View File

@ -18,6 +18,7 @@ import { CoreFileProvider } from '@providers/file';
import { CoreDomUtilsProvider } from '@providers/utils/dom';
import { CoreTextUtilsProvider } from '@providers/utils/text';
import { CoreTimeUtilsProvider } from '@providers/utils/time';
import { MediaFile } from '@ionic-native/media-capture';
/**
* Page to capture media in browser or desktop.
@ -364,13 +365,21 @@ export class CoreEmulatorCaptureMediaPage implements OnInit, OnDestroy {
if (this.isImage && !this.isCaptureImage) {
this.dismissWithData(fileEntry.toURL());
} else {
// The capture plugin returns a MediaFile, not a FileEntry.
// The only difference is that it supports a new function that won't be supported in desktop.
fileEntry.getFormatData = (successFn, errorFn): any => {
// The capture plugin should return a MediaFile, not a FileEntry. Convert it.
return this.fileProvider.getMetadata(fileEntry).then((metadata) => {
const mediaFile: MediaFile = {
name: fileEntry.name,
fullPath: fileEntry.fullPath,
type: null,
lastModifiedDate: metadata.modificationTime,
size: metadata.size,
getFormatData: (successFn, errorFn): void => {
// Nothing to do.
}
};
this.dismissWithData([fileEntry]);
this.dismissWithData([mediaFile]);
});
}
}).catch((err) => {
this.domUtils.showErrorModal(err);

View File

@ -14,7 +14,7 @@
import { Injectable } from '@angular/core';
import { Platform } from 'ionic-angular';
import { File, FileEntry, DirectoryEntry } from '@ionic-native/file';
import { File, FileEntry, DirectoryEntry, Entry, Metadata } from '@ionic-native/file';
import { CoreAppProvider } from './app';
import { CoreLoggerProvider } from './logger';
@ -545,7 +545,7 @@ export class CoreFileProvider {
reader.onloadend = (evt): void => {
const target = <any> evt.target; // Convert to <any> to be able to use non-standard properties.
if (target.result !== undefined || target.result !== null) {
if (target.result !== undefined && target.result !== null) {
if (format == CoreFileProvider.FORMATJSON) {
// Convert to object.
const parsed = this.textUtils.parseJSON(target.result, null);
@ -558,7 +558,7 @@ export class CoreFileProvider {
} else {
resolve(target.result);
}
} else if (target.error !== undefined || target.error !== null) {
} else if (target.error !== undefined && target.error !== null) {
reject(target.error);
} else {
reject({ code: null, message: 'READER_ONLOADEND_ERR' });
@ -602,7 +602,7 @@ export class CoreFileProvider {
* @param append Whether to append the data to the end of the file.
* @return Promise to be resolved when the file is written.
*/
writeFile(path: string, data: any, append?: boolean): Promise<any> {
writeFile(path: string, data: any, append?: boolean): Promise<FileEntry> {
return this.init().then(() => {
// Remove basePath if it's in the path.
path = this.removeStartingSlash(path.replace(this.basePath, ''));
@ -635,15 +635,18 @@ export class CoreFileProvider {
* @param append Whether to append the data to the end of the file.
* @return Promise resolved when done.
*/
writeFileDataInFile(file: any, path: string, onProgress?: (event: CoreFileProgressEvent) => any, offset: number = 0,
append?: boolean): Promise<any> {
async writeFileDataInFile(file: Blob, path: string, onProgress?: (event: CoreFileProgressEvent) => void, offset: number = 0,
append?: boolean): Promise<FileEntry> {
offset = offset || 0;
// Get the chunk to read.
const blob = file.slice(offset, Math.min(offset + this.CHUNK_SIZE, file.size));
const readWholeFile = offset === 0 && this.CHUNK_SIZE >= file.size;
const chunk = readWholeFile ? file : file.slice(offset, Math.min(offset + this.CHUNK_SIZE, file.size));
try {
const fileEntry = await this.writeFileDataInFileChunk(chunk, path, append);
return this.writeFileDataInFileChunk(blob, path, append).then((fileEntry) => {
offset += this.CHUNK_SIZE;
onProgress && onProgress({
@ -659,7 +662,15 @@ export class CoreFileProvider {
// Read the next chunk.
return this.writeFileDataInFile(file, path, onProgress, offset, true);
});
} catch (error) {
if (readWholeFile || !error || error.name != 'NotReadableError') {
return Promise.reject(error);
}
// Permission error when reading file in chunks. This usually happens with Google Drive files.
// Try to read the whole file at once.
return this.writeFileDataInFileChunk(file, path, false);
}
}
/**
@ -670,7 +681,7 @@ export class CoreFileProvider {
* @param append Whether to append the data to the end of the file.
* @return Promise resolved when done.
*/
protected writeFileDataInFileChunk(chunkData: any, path: string, append?: boolean): Promise<any> {
protected writeFileDataInFileChunk(chunkData: any, path: string, append?: boolean): Promise<FileEntry> {
// Read the chunk data.
return this.readFileData(chunkData, CoreFileProvider.FORMATARRAYBUFFER).then((fileData) => {
// Write the data in the file.
@ -1053,7 +1064,7 @@ export class CoreFileProvider {
* @param fileEntry FileEntry retrieved from getFile or similar.
* @return Promise resolved with metadata.
*/
getMetadata(fileEntry: Entry): Promise<any> {
getMetadata(fileEntry: Entry): Promise<Metadata> {
if (!fileEntry || !fileEntry.getMetadata) {
return Promise.reject(null);
}