MOBILE-2795 ios: Handle files shared through iCloud

main
Dani Palou 2019-01-10 13:18:04 +01:00
parent 144163ced7
commit 971aebd658
7 changed files with 72 additions and 20 deletions

View File

@ -35,11 +35,13 @@ export class CoreSharedFilesChooseSitePage implements OnInit {
protected filePath: string;
protected fileEntry: any;
protected isInbox: boolean; // Whether the file is in the Inbox folder.
constructor(private navCtrl: NavController, navParams: NavParams, private sharedFilesHelper: CoreSharedFilesHelperProvider,
private sitesProvider: CoreSitesProvider, private domUtils: CoreDomUtilsProvider,
private fileProvider: CoreFileProvider) {
this.filePath = navParams.get('filePath');
this.isInbox = navParams.get('isInbox');
}
/**
@ -57,7 +59,7 @@ export class CoreSharedFilesChooseSitePage implements OnInit {
this.fileName = fileAndDir.name;
// Get the file.
this.fileProvider.getFile(this.filePath).then((fe) => {
this.fileProvider.getExternalFile(this.filePath).then((fe) => {
this.fileEntry = fe;
this.fileName = this.fileEntry.name;
}).catch(() => {
@ -80,7 +82,7 @@ export class CoreSharedFilesChooseSitePage implements OnInit {
*/
storeInSite(siteId: string): void {
this.loaded = false;
this.sharedFilesHelper.storeSharedFileInSite(this.fileEntry, siteId).then(() => {
this.sharedFilesHelper.storeSharedFileInSite(this.fileEntry, siteId, this.isInbox).then(() => {
this.navCtrl.pop();
}).finally(() => {
this.loaded = true;

View File

@ -77,10 +77,22 @@ export class CoreSharedFilesHelperProvider {
* Go to the choose site view.
*
* @param {string} filePath File path to send to the view.
* @param {boolean} [isInbox] Whether the file is in the Inbox folder.
*/
goToChooseSite(filePath: string): void {
goToChooseSite(filePath: string, isInbox?: boolean): void {
const navCtrl = this.appProvider.getRootNavController();
navCtrl.push('CoreSharedFilesChooseSitePage', { filePath: filePath });
navCtrl.push('CoreSharedFilesChooseSitePage', { filePath: filePath, isInbox: isInbox });
}
/**
* Whether the user is already choosing a site to store a shared file.
*
* @return {boolean} Whether the user is already choosing a site to store a shared file.
*/
protected isChoosingSite(): boolean {
const navCtrl = this.appProvider.getRootNavController();
return navCtrl && navCtrl.getActive().id == 'CoreSharedFilesChooseSitePage';
}
/**
@ -115,34 +127,62 @@ export class CoreSharedFilesHelperProvider {
});
}
/**
* Delete a shared file.
*
* @param {any} fileEntry The file entry to delete.
* @param {boolean} [isInbox] Whether the file is in the Inbox folder.
* @return {Promise<any>} Promise resolved when done.
*/
protected removeSharedFile(fileEntry: any, isInbox?: boolean): Promise<any> {
if (isInbox) {
return this.sharedFilesProvider.deleteInboxFile(fileEntry);
} else {
return this.fileProvider.removeFileByFileEntry(fileEntry);
}
}
/**
* Checks if there is a new file received in iOS and move it to the shared folder of current site.
* If more than one site is found, the user will have to choose the site where to store it in.
* If more than one file is found, treat only the first one.
*
* @param {string} [path] Path to a file received when launching the app.
* @return {Promise<any>} Promise resolved when done.
*/
searchIOSNewSharedFiles(): Promise<any> {
searchIOSNewSharedFiles(path?: string): Promise<any> {
return this.initDelegate.ready().then(() => {
const navCtrl = this.appProvider.getRootNavController();
if (navCtrl && navCtrl.getActive().id == 'CoreSharedFilesChooseSite') {
if (this.isChoosingSite()) {
// We're already treating a shared file. Abort.
return Promise.reject(null);
}
return this.sharedFilesProvider.checkIOSNewFiles().then((fileEntry) => {
let promise;
if (path) {
// The app was launched with the path to the file, get the file.
promise = this.fileProvider.getExternalFile(path);
} else {
// No path received, search if there is any file in the Inbox folder.
promise = this.sharedFilesProvider.checkIOSNewFiles();
}
return promise.then((fileEntry) => {
return this.sitesProvider.getSitesIds().then((siteIds) => {
if (!siteIds.length) {
// No sites stored, show error and delete the file.
this.domUtils.showErrorModal('core.sharedfiles.errorreceivefilenosites', true);
return this.sharedFilesProvider.deleteInboxFile(fileEntry);
return this.removeSharedFile(fileEntry, !path);
} else if (siteIds.length == 1) {
return this.storeSharedFileInSite(fileEntry, siteIds[0]);
} else {
this.goToChooseSite(fileEntry.fullPath);
return this.storeSharedFileInSite(fileEntry, siteIds[0], !path);
} else if (!this.isChoosingSite()) {
this.goToChooseSite(fileEntry.toURL(), !path);
}
});
}).catch((error) => {
if (error) {
this.logger.error('Error searching iOS new shared files', error, path);
}
});
});
}
@ -152,16 +192,17 @@ export class CoreSharedFilesHelperProvider {
*
* @param {any} fileEntry Shared file entry.
* @param {string} [siteId] Site ID. If not defined, current site.
* @param {boolean} [isInbox] Whether the file is in the Inbox folder.
* @return {Promise<any>} Promise resolved when done.
*/
storeSharedFileInSite(fileEntry: any, siteId?: string): Promise<any> {
storeSharedFileInSite(fileEntry: any, siteId?: string, isInbox?: boolean): Promise<any> {
siteId = siteId || this.sitesProvider.getCurrentSiteId();
// First of all check if there's already a file with the same name in the shared files folder.
const sharedFilesDirPath = this.sharedFilesProvider.getSiteSharedFilesDirPath(siteId);
return this.fileProvider.getUniqueNameInFolder(sharedFilesDirPath, fileEntry.name).then((newName) => {
if (newName == fileEntry.name) {
if (newName.toLowerCase() == fileEntry.name.toLowerCase()) {
// No file with the same name. Use the original file name.
return newName;
} else {
@ -172,7 +213,7 @@ export class CoreSharedFilesHelperProvider {
return this.sharedFilesProvider.storeFileInSite(fileEntry, name, siteId).catch((err) => {
this.domUtils.showErrorModal(err || 'Error moving file.');
}).finally(() => {
this.sharedFilesProvider.deleteInboxFile(fileEntry);
this.removeSharedFile(fileEntry, isInbox);
this.domUtils.showAlertTranslated('core.success', 'core.sharedfiles.successstorefile');
});
});

View File

@ -229,7 +229,7 @@ export class CoreSharedFilesProvider {
// Create dir if it doesn't exist already.
return this.fileProvider.createDir(sharedFilesFolder).then(() => {
return this.fileProvider.moveFile(entry.fullPath, newPath).then((newFile) => {
return this.fileProvider.moveExternalFile(entry.toURL(), newPath).then((newFile) => {
this.eventsProvider.trigger(CoreEventsProvider.FILE_SHARED, { siteId: siteId, name: newName });
return newFile;

View File

@ -18,6 +18,7 @@ import { CoreSharedFilesProvider } from './providers/sharedfiles';
import { CoreSharedFilesHelperProvider } from './providers/helper';
import { CoreSharedFilesUploadHandler } from './providers/upload-handler';
import { CoreFileUploaderDelegate } from '@core/fileuploader/providers/delegate';
import { CoreEventsProvider } from '@providers/events';
// List of providers (without handlers).
export const CORE_SHAREDFILES_PROVIDERS: any[] = [
@ -38,7 +39,7 @@ export const CORE_SHAREDFILES_PROVIDERS: any[] = [
})
export class CoreSharedFilesModule {
constructor(platform: Platform, delegate: CoreFileUploaderDelegate, handler: CoreSharedFilesUploadHandler,
helper: CoreSharedFilesHelperProvider) {
helper: CoreSharedFilesHelperProvider, eventsProvider: CoreEventsProvider) {
// Register the handler.
delegate.registerHandler(handler);
@ -48,6 +49,13 @@ export class CoreSharedFilesModule {
platform.resume.subscribe(() => {
helper.searchIOSNewSharedFiles();
});
eventsProvider.on(CoreEventsProvider.APP_LAUNCHED_URL, (url) => {
if (url && url.indexOf('file://') === 0) {
// We received a file in iOS, it's probably a shared file. Treat it.
helper.searchIOSNewSharedFiles(url);
}
});
}
}
}

View File

@ -1052,7 +1052,7 @@ export class CoreFileProvider {
// Index the files by name.
entries.forEach((entry) => {
files[entry.name] = entry;
files[entry.name.toLowerCase()] = entry;
});
// Format extension.
@ -1063,7 +1063,7 @@ export class CoreFileProvider {
}
newName = fileNameWithoutExtension + extension;
if (typeof files[newName] == 'undefined') {
if (typeof files[newName.toLowerCase()] == 'undefined') {
// No file with the same name.
return newName;
} else {

View File

@ -455,7 +455,7 @@ export class CoreMimetypeUtilsProvider {
if (position > -1) {
// Check extension corresponds to a mimetype to know if it's valid.
extension = path.substr(position + 1);
extension = path.substr(position + 1).toLowerCase();
if (typeof this.getMimeType(extension) != 'undefined') {
return path.substr(0, position); // Remove extension.
}

View File

@ -9,6 +9,7 @@ information provided here is intended especially for developers.
- Use of completionstatus on the module object has been deprecated, use completiondata instead.
- The function CoreSitesProvider.loadSite has changed, now it will trigger SESSION_EXPIRED event if the site is logged out. Its params and return value have changed.
- When using CoreDomUtils.showAlert, please use alert.didDismiss.subscribe() instead of alert.onDidDismiss().
- The page CoreSharedFilesChooseSitePage now expects to receive the full path to the file (file.toURL()) instead of the relative path.
- The following strings have been deprecated:
core.dfdaymonthyear. Please use core.strftimedatefullshort instead.
core.dfdayweekmonth. Please use core.strftimedayshort instead.