216 lines
7.9 KiB
TypeScript

// (C) Copyright 2015 Martin Dougiamas
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import { Component, OnDestroy } from '@angular/core';
import { IonicPage, NavParams } from 'ionic-angular';
import { TranslateService } from '@ngx-translate/core';
import { CoreAppProvider } from '@providers/app';
import { CoreEventsProvider } from '@providers/events';
import { CoreSitesProvider } from '@providers/sites';
import { CoreDomUtilsProvider } from '@providers/utils/dom';
import { CoreTextUtilsProvider } from '@providers/utils/text';
import { AddonFilesProvider } from '../../providers/files';
import { AddonFilesHelperProvider } from '../../providers/helper';
/**
* Page that displays the list of files.
*/
@IonicPage({ segment: 'addon-files-list' })
@Component({
selector: 'page-addon-files-list',
templateUrl: 'list.html',
})
export class AddonFilesListPage implements OnDestroy {
title: string; // Page title.
showPrivateFiles: boolean; // Whether the user can view private files.
showSiteFiles: boolean; // Whether the user can view site files.
showUpload: boolean; // Whether the user can upload files.
root: string; // The root of the files loaded: 'my' or 'site'.
path: string; // The path of the directory being loaded. If empty path it means the root is being loaded.
userQuota: number; // The user quota (in bytes).
filesInfo: any; // Info about private files (size, number of files, etc.).
spaceUsed: string; // Space used in a readable format.
userQuotaReadable: string; // User quota in a readable format.
files: any[]; // List of files.
component: string; // Component to link the file downloads to.
filesLoaded: boolean; // Whether the files are loaded.
protected updateSiteObserver;
constructor(navParams: NavParams, eventsProvider: CoreEventsProvider, private sitesProvider: CoreSitesProvider,
private domUtils: CoreDomUtilsProvider, private translate: TranslateService, private appProvider: CoreAppProvider,
private filesProvider: AddonFilesProvider, private filesHelper: AddonFilesHelperProvider,
private textUtils: CoreTextUtilsProvider) {
this.title = navParams.get('title') || this.translate.instant('addon.files.files');
this.root = navParams.get('root');
this.path = navParams.get('path');
// Update visibility if current site info is updated.
this.updateSiteObserver = eventsProvider.on(CoreEventsProvider.SITE_UPDATED, () => {
this.setVisibility();
}, sitesProvider.getCurrentSiteId());
}
/**
* View loaded.
*/
ionViewDidLoad(): void {
this.setVisibility();
this.userQuota = this.sitesProvider.getCurrentSite().getInfo().userquota;
if (!this.root) {
// Load private files by default.
if (this.showPrivateFiles) {
this.root = 'my';
} else if (this.showSiteFiles) {
this.root = 'site';
}
}
if (this.root) {
this.rootChanged();
} else {
this.filesLoaded = true;
}
}
/**
* Refresh the data.
*
* @param {any} refresher Refresher.
*/
refreshData(refresher: any): void {
this.refreshFiles().finally(() => {
refresher.complete();
});
}
/**
* Function called when the root has changed.
*/
rootChanged(): void {
this.filesLoaded = false;
this.component = this.root == 'my' ? AddonFilesProvider.PRIVATE_FILES_COMPONENT : AddonFilesProvider.SITE_FILES_COMPONENT;
this.fetchFiles().finally(() => {
this.filesLoaded = true;
});
}
/**
* Upload a new file.
*/
uploadFile(): void {
this.filesProvider.versionCanUploadFiles().then((canUpload) => {
if (!canUpload) {
this.domUtils.showAlertTranslated('core.notice', 'addon.files.erroruploadnotworking');
} else if (!this.appProvider.isOnline()) {
this.domUtils.showErrorModal('core.fileuploader.errormustbeonlinetoupload', true);
} else {
this.filesHelper.uploadPrivateFile(this.filesInfo).then(() => {
// File uploaded, refresh the list.
this.filesLoaded = false;
this.refreshFiles().finally(() => {
this.filesLoaded = true;
});
}).catch(() => {
// Ignore errors, they're handled inside the function.
});
}
});
}
/**
* Set visibility of some items based on site data.
*/
protected setVisibility(): void {
this.showPrivateFiles = this.filesProvider.canViewPrivateFiles();
this.showSiteFiles = this.filesProvider.canViewSiteFiles();
this.showUpload = this.filesProvider.canUploadFiles();
}
/**
* Fetch the files.
*
* @return {Promise<any>} Promise resolved when done.
*/
protected fetchFiles(): Promise<any> {
let promise;
if (!this.path) {
// The path is unknown, the user must be requesting a root.
if (this.root == 'site') {
this.title = this.translate.instant('addon.files.sitefiles');
promise = this.filesProvider.getSiteFiles();
} else if (this.root == 'my') {
this.title = this.translate.instant('addon.files.files');
promise = this.filesProvider.getPrivateFiles().then((files) => {
if (this.showUpload && this.filesProvider.canGetPrivateFilesInfo() && this.userQuota > 0) {
// Get the info to calculate the available size.
return this.filesProvider.getPrivateFilesInfo().then((info) => {
this.filesInfo = info;
this.spaceUsed = this.textUtils.bytesToSize(info.filesizewithoutreferences, 1);
this.userQuotaReadable = this.textUtils.bytesToSize(this.userQuota, 1);
return files;
});
} else {
// User quota isn't useful, delete it.
delete this.userQuota;
}
return files;
});
} else {
// Unknown root.
promise = Promise.reject(null);
}
} else {
// Path is set, serve the files the user requested.
promise = this.filesProvider.getFiles(this.path);
}
return promise.then((files) => {
this.files = files;
}).catch((error) => {
this.domUtils.showErrorModalDefault(error, 'addon.files.couldnotloadfiles', true);
});
}
/**
* Refresh the displayed files.
*
* @return {Promise<any>} Promise resolved when done.
*/
protected refreshFiles(): Promise<any> {
const promises = [];
promises.push(this.filesProvider.invalidateDirectory(this.root, this.path));
promises.push(this.filesProvider.invalidatePrivateFilesInfoForUser());
return Promise.all(promises).finally(() => {
return this.fetchFiles();
});
}
/**
* Page destroyed.
*/
ngOnDestroy(): void {
this.updateSiteObserver && this.updateSiteObserver.off();
}
}